Re: [Qemu-devel] [PULL 0/9] ppc-for-2.12 queue 20180315

2018-03-16 Thread David Gibson
On Fri, Mar 16, 2018 at 05:25:04PM +, Peter Maydell wrote:
> On 15 March 2018 at 04:18, David Gibson  wrote:
> > The following changes since commit 026aaf47c02b79036feb830206cfebb2a726510d:
> >
> >   Merge remote-tracking branch 
> > 'remotes/ehabkost/tags/python-next-pull-request' into staging (2018-03-13 
> > 16:26:44 +)
> >
> > are available in the Git repository at:
> >
> >   git://github.com/dgibson/qemu.git tags/ppc-for-2.12-20180315
> >
> > for you to fetch changes up to a9ab8cc157054ea6941fb849c78d9e6c515a7730:
> >
> >   target/ppc: fix tlbsync to check privilege level depending on GTSE 
> > (2018-03-15 11:18:31 +1100)
> >
> > 
> > ppc patch queue for 2018-03-15
> >
> > Here's the set of accumulated patches now that we're into soft freeze.
> > I've split new functionality into a ppc-for-2.13 branch, so this only
> > has bugfixes.  Well.. and a couple of simple cleanups to make bugfixes
> > easier, some test improvements and a trivial change to make command
> > line options more obvious.  I think those are all acceptable for soft
> > freeze.
> >
> 
> Hi -- this looks like it provokes new runtime error warnings from the
> clang sanitizer:

Hrm.  What options do you need to trip these warnings?  Just using
--cc=clang doesn't give them to me, and using --enable-sanitizers
gives my piles of unrelated warnings.

> 
> TEST: tests/boot-serial-test... (pid=926)
>   /ppc/boot-serial/ppce500:OK
>   /ppc/boot-serial/prep:   OK
>   /ppc/boot-serial/40p:OK
>   /ppc/boot-serial/g3beige:OK
>   /ppc/boot-serial/mac99:  OK
>   /ppc/boot-serial/sam460ex:
> /home/petmay01/linaro/qemu-for-merges/target/ppc/translate.c:2979:15:
> runtime error: load of value 142, which is not a valid value for type
> 'bool'
> OK
> 
> TEST: tests/boot-serial-test... (pid=1016)
>   /ppc64/boot-serial/ppce500:  OK
>   /ppc64/boot-serial/prep: OK
>   /ppc64/boot-serial/40p:  OK
>   /ppc64/boot-serial/mac99:OK
>   /ppc64/boot-serial/pseries:  OK
>   /ppc64/boot-serial/powernv:  OK
>   /ppc64/boot-serial/sam460ex:
> /home/petmay01/linaro/qemu-for-merges/target/ppc/translate.c:2979:15:
> runtime error: load of value 85, which is not a valid value for type
> 'bool'
> OK
> 
> Looks like you're not initializing ctx->lazy_tlb_flush for all configs:
> if (env->mmu_model == POWERPC_MMU_32B ||
> env->mmu_model == POWERPC_MMU_601 ||
> (env->mmu_model & POWERPC_MMU_64B))
> ctx->lazy_tlb_flush = true;
> 
> should perhaps be
> ctx->lazy_tlb_flush =
> env->mmu_model == POWERPC_MMU_32B ||
> env->mmu_model == POWERPC_MMU_601 ||
> (env->mmu_model & POWERPC_MMU_64B);
> 
> ?

Uh.. maybe.. except I don't see anything in the series that would be
likely to change that behaviour.

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


signature.asc
Description: PGP signature


[Qemu-devel] [PATCH v5.2 for 2.13 0/4] tpm: Extend TPM with state migration support

2018-03-16 Thread Stefan Berger
This series of patches implements support for migrating the state of the
external 'swtpm' TPM emulator as well as that of the TIS interface. 

For testing of TPM 2 (migration) please use the following git repos and
branches:

libtpms: 
   - repo: https://github.com/stefanberger/libtpms
   - branch: tpm2-preview.rev146.v2

swtpm:
   - repo: https://github.com/stefanberger/swtpm
   - branch: tpm2-preview.rev146.v2

Regards,
  Stefan

Changes:
 v4->v5:
   - followed Marc-André's and Alan's comments where possible; some comments
 were not addressed and reasons posted to mailing list
   - converted debug statements to tracing
   - qemu_chr_fe_read_all does not return errno, so displaying expected versus
 received number of bytes rather than strerror(errno)
   - added test cases
   - added documentation for migration to docs/spec/tpm.txt

 v3->v4:
   - dropped the size limit enforcement on blobs received from the swtpm
   - the .post_load migration function requires errno's to be returned.
 -> some of the functions have been converted to return a better errno


Stefan Berger (4):
  tpm: extend TPM emulator with state migration support
  tpm: extend TPM TIS with state migration support
  docs: tpm: add VM save/restore example and troubleshooting guide
  tpm: Add test cases that uses the external swtpm with CRB interface

 docs/specs/tpm.txt | 106 +++
 hw/tpm/tpm_emulator.c  | 318 +++--
 hw/tpm/tpm_tis.c   |  52 +++-
 hw/tpm/trace-events|   9 +-
 tests/Makefile.include |   3 +
 tests/tpm-crb-swtpm-test.c | 244 ++
 tests/tpm-util.c   | 143 
 tests/tpm-util.h   |  36 +
 8 files changed, 897 insertions(+), 14 deletions(-)
 create mode 100644 tests/tpm-crb-swtpm-test.c
 create mode 100644 tests/tpm-util.c
 create mode 100644 tests/tpm-util.h

-- 
2.5.5




[Qemu-devel] [PATCH v5.2 for 2.13 4/4] tpm: Add test cases that uses the external swtpm with CRB interface

2018-03-16 Thread Stefan Berger
Add a test program for testing the CRB with the external swtpm.

The 1st test case extends a PCR and reads back the value and compares
it against an expected return packet.

The 2nd test case repeats the 1st test case and then migrates the
external swtpm's state along with the VM state to a destination
QEMU and swtpm and checks that the PCR has the expected value now.

Signed-off-by: Stefan Berger 
---
 tests/Makefile.include |   3 +
 tests/tpm-crb-swtpm-test.c | 244 +
 tests/tpm-util.c   | 143 ++
 tests/tpm-util.h   |  36 +++
 4 files changed, 426 insertions(+)
 create mode 100644 tests/tpm-crb-swtpm-test.c
 create mode 100644 tests/tpm-util.c
 create mode 100644 tests/tpm-util.h

diff --git a/tests/Makefile.include b/tests/Makefile.include
index 42fd426..bd4f56f 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -297,6 +297,7 @@ check-qtest-i386-$(CONFIG_VHOST_USER_NET_TEST_i386) += 
tests/vhost-user-test$(EX
 ifeq ($(CONFIG_VHOST_USER_NET_TEST_i386),)
 check-qtest-x86_64-$(CONFIG_VHOST_USER_NET_TEST_x86_64) += 
tests/vhost-user-test$(EXESUF)
 endif
+check-qtest-i386-$(CONFIG_TPM) += tests/tpm-crb-swtpm-test$(EXESUF)
 check-qtest-i386-$(CONFIG_TPM) += tests/tpm-crb-test$(EXESUF)
 check-qtest-i386-$(CONFIG_TPM) += tests/tpm-tis-test$(EXESUF)
 check-qtest-i386-$(CONFIG_SLIRP) += tests/test-netfilter$(EXESUF)
@@ -719,6 +720,8 @@ tests/test-util-sockets$(EXESUF): tests/test-util-sockets.o 
\
 tests/test-io-task$(EXESUF): tests/test-io-task.o $(test-io-obj-y)
 tests/test-io-channel-socket$(EXESUF): tests/test-io-channel-socket.o \
 tests/io-channel-helpers.o tests/socket-helpers.o $(test-io-obj-y)
+tests/tpm-crb-swtpm-test$(EXESUF): tests/tpm-crb-swtpm-test.o tests/tpm-emu.o \
+   tests/tpm-util.o $(test-io-obj-y)
 tests/tpm-crb-test$(EXESUF): tests/tpm-crb-test.o tests/tpm-emu.o 
$(test-io-obj-y)
 tests/tpm-tis-test$(EXESUF): tests/tpm-tis-test.o tests/tpm-emu.o 
$(test-io-obj-y)
 tests/test-io-channel-file$(EXESUF): tests/test-io-channel-file.o \
diff --git a/tests/tpm-crb-swtpm-test.c b/tests/tpm-crb-swtpm-test.c
new file mode 100644
index 000..b2f6068
--- /dev/null
+++ b/tests/tpm-crb-swtpm-test.c
@@ -0,0 +1,244 @@
+/*
+ * QTest testcase for TPM CRB talking to external swtpm and swtpm migration
+ *
+ * Copyright (c) 2018 IBM Corporation
+ *  with parts borrowed from migration-test.c that is:
+ * Copyright (c) 2016-2018 Red Hat, Inc. and/or its affiliates
+ *
+ * Authors:
+ *   Stefan Berger 
+ *
+ * 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 
+
+#include "hw/acpi/tpm.h"
+#include "io/channel-socket.h"
+#include "libqtest.h"
+#include "tpm-util.h"
+#include "sysemu/tpm.h"
+#include "qapi/qmp/qdict.h"
+
+typedef struct TestState {
+char *src_tpm_path;
+char *dst_tpm_path;
+char *uri;
+} TestState;
+
+bool got_stop;
+
+static void migrate(QTestState *who, const char *uri)
+{
+QDict *rsp;
+gchar *cmd;
+
+cmd = g_strdup_printf("{ 'execute': 'migrate',"
+  "'arguments': { 'uri': '%s' } }",
+  uri);
+rsp = qtest_qmp(who, cmd);
+g_free(cmd);
+g_assert(qdict_haskey(rsp, "return"));
+QDECREF(rsp);
+}
+
+/*
+ * Events can get in the way of responses we are actually waiting for.
+ */
+static QDict *wait_command(QTestState *who, const char *command)
+{
+const char *event_string;
+QDict *response;
+
+response = qtest_qmp(who, command);
+
+while (qdict_haskey(response, "event")) {
+/* OK, it was an event */
+event_string = qdict_get_str(response, "event");
+if (!strcmp(event_string, "STOP")) {
+got_stop = true;
+}
+QDECREF(response);
+response = qtest_qmp_receive(who);
+}
+return response;
+}
+
+static void wait_for_migration_complete(QTestState *who)
+{
+while (true) {
+QDict *rsp, *rsp_return;
+bool completed;
+const char *status;
+
+rsp = wait_command(who, "{ 'execute': 'query-migrate' }");
+rsp_return = qdict_get_qdict(rsp, "return");
+status = qdict_get_str(rsp_return, "status");
+completed = strcmp(status, "completed") == 0;
+g_assert_cmpstr(status, !=,  "failed");
+QDECREF(rsp);
+if (completed) {
+return;
+}
+usleep(1000);
+}
+}
+
+static void migration_start_qemu(QTestState **src_qemu, QTestState **dst_qemu,
+ SocketAddress *src_tpm_addr,
+ SocketAddress *dst_tpm_addr,
+ const char *miguri)
+{
+char *src_qemu_args, *dst_qemu_args;
+
+src_qemu_args = g_strdup_printf(
+"-chardev socket,id=chr,path=%s "
+

[Qemu-devel] [PATCH v5.2 for 2.13 2/4] tpm: extend TPM TIS with state migration support

2018-03-16 Thread Stefan Berger
Extend the TPM TIS interface with state migration support.

We need to synchronize with the backend thread to make sure that a command
being processed by the external TPM emulator has completed and its
response been received.

Signed-off-by: Stefan Berger 
---
 hw/tpm/tpm_tis.c| 52 ++--
 hw/tpm/trace-events |  1 +
 2 files changed, 51 insertions(+), 2 deletions(-)

diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
index 2ac7e74..fec3d73 100644
--- a/hw/tpm/tpm_tis.c
+++ b/hw/tpm/tpm_tis.c
@@ -894,9 +894,57 @@ static void tpm_tis_reset(DeviceState *dev)
 tpm_backend_startup_tpm(s->be_driver, s->be_buffer_size);
 }
 
+/* persistent state handling */
+
+static int tpm_tis_pre_save(void *opaque)
+{
+TPMState *s = opaque;
+uint8_t locty = s->active_locty;
+
+trace_tpm_tis_pre_save(locty, s->rw_offset);
+
+if (DEBUG_TIS) {
+tpm_tis_dump_state(opaque, 0);
+}
+
+/*
+ * Synchronize with backend completion.
+ */
+tpm_backend_finish_sync(s->be_driver);
+
+return 0;
+}
+
+static const VMStateDescription vmstate_locty = {
+.name = "tpm-tis/locty",
+.version_id = 1,
+.fields  = (VMStateField[]) {
+VMSTATE_UINT32(state, TPMLocality),
+VMSTATE_UINT32(inte, TPMLocality),
+VMSTATE_UINT32(ints, TPMLocality),
+VMSTATE_UINT8(access, TPMLocality),
+VMSTATE_UINT32(sts, TPMLocality),
+VMSTATE_UINT32(iface_id, TPMLocality),
+VMSTATE_END_OF_LIST(),
+}
+};
+
 static const VMStateDescription vmstate_tpm_tis = {
-.name = "tpm",
-.unmigratable = 1,
+.name = "tpm-tis",
+.version_id = 1,
+.pre_save  = tpm_tis_pre_save,
+.fields = (VMStateField[]) {
+VMSTATE_BUFFER(buffer, TPMState),
+VMSTATE_UINT16(rw_offset, TPMState),
+VMSTATE_UINT8(active_locty, TPMState),
+VMSTATE_UINT8(aborting_locty, TPMState),
+VMSTATE_UINT8(next_locty, TPMState),
+
+VMSTATE_STRUCT_ARRAY(loc, TPMState, TPM_TIS_NUM_LOCALITIES, 1,
+ vmstate_locty, TPMLocality),
+
+VMSTATE_END_OF_LIST()
+}
 };
 
 static Property tpm_tis_properties[] = {
diff --git a/hw/tpm/trace-events b/hw/tpm/trace-events
index c5bfbf1..25bee0c 100644
--- a/hw/tpm/trace-events
+++ b/hw/tpm/trace-events
@@ -50,3 +50,4 @@ tpm_tis_mmio_write_locty_seized(uint8_t locty, uint8_t 
active) "Locality %d seiz
 tpm_tis_mmio_write_init_abort(void) "Initiating abort"
 tpm_tis_mmio_write_lowering_irq(void) "Lowering IRQ"
 tpm_tis_mmio_write_data2send(uint32_t value, unsigned size) "Data to send to 
TPM: 0x%08x (size=%d)"
+tpm_tis_pre_save(uint8_t locty, uint32_t rw_offset) "locty: %d, rw_offset = %u"
-- 
2.5.5




[Qemu-devel] [PATCH v5.2 for 2.13 1/4] tpm: extend TPM emulator with state migration support

2018-03-16 Thread Stefan Berger
Extend the TPM emulator backend device with state migration support.

The external TPM emulator 'swtpm' provides a protocol over
its control channel to retrieve its state blobs. We implement
functions for getting and setting the different state blobs.
In case the setting of the state blobs fails, we return a
negative errno code to fail the start of the VM.

Since we have an external TPM emulator, we need to make sure
that we do not migrate the state for as long as it is busy
processing a request. We need to wait for notification that
the request has completed processing.

Signed-off-by: Stefan Berger 
---
 hw/tpm/tpm_emulator.c | 318 --
 hw/tpm/trace-events   |   8 +-
 2 files changed, 314 insertions(+), 12 deletions(-)

diff --git a/hw/tpm/tpm_emulator.c b/hw/tpm/tpm_emulator.c
index 6418ef0..6d6158d 100644
--- a/hw/tpm/tpm_emulator.c
+++ b/hw/tpm/tpm_emulator.c
@@ -4,7 +4,7 @@
  *  Copyright (c) 2017 Intel Corporation
  *  Author: Amarnath Valluri 
  *
- *  Copyright (c) 2010 - 2013 IBM Corporation
+ *  Copyright (c) 2010 - 2013, 2018 IBM Corporation
  *  Authors:
  *Stefan Berger 
  *
@@ -49,6 +49,19 @@
 #define TPM_EMULATOR_IMPLEMENTS_ALL_CAPS(S, cap) (((S)->caps & (cap)) == (cap))
 
 /* data structures */
+
+/* blobs from the TPM; part of VM state when migrating */
+typedef struct TPMBlobBuffers {
+uint32_t permanent_flags;
+TPMSizedBuffer permanent;
+
+uint32_t volatil_flags;
+TPMSizedBuffer volatil;
+
+uint32_t savestate_flags;
+TPMSizedBuffer savestate;
+} TPMBlobBuffers;
+
 typedef struct TPMEmulator {
 TPMBackend parent;
 
@@ -64,6 +77,8 @@ typedef struct TPMEmulator {
 
 unsigned int established_flag:1;
 unsigned int established_flag_cached:1;
+
+TPMBlobBuffers state_blobs;
 } TPMEmulator;
 
 
@@ -293,7 +308,8 @@ static int tpm_emulator_set_buffer_size(TPMBackend *tb,
 return 0;
 }
 
-static int tpm_emulator_startup_tpm(TPMBackend *tb, size_t buffersize)
+static int tpm_emulator_startup_tpm_resume(TPMBackend *tb, size_t buffersize,
+ bool is_resume)
 {
 TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
 ptm_init init = {
@@ -301,12 +317,17 @@ static int tpm_emulator_startup_tpm(TPMBackend *tb, 
size_t buffersize)
 };
 ptm_res res;
 
+trace_tpm_emulator_startup_tpm_resume(is_resume, buffersize);
+
 if (buffersize != 0 &&
 tpm_emulator_set_buffer_size(tb, buffersize, NULL) < 0) {
 goto err_exit;
 }
 
-trace_tpm_emulator_startup_tpm();
+if (is_resume) {
+init.u.req.init_flags |= cpu_to_be32(PTM_INIT_FLAG_DELETE_VOLATILE);
+}
+
 if (tpm_emulator_ctrlcmd(tpm_emu, CMD_INIT, , sizeof(init),
  sizeof(init)) < 0) {
 error_report("tpm-emulator: could not send INIT: %s",
@@ -325,6 +346,11 @@ err_exit:
 return -1;
 }
 
+static int tpm_emulator_startup_tpm(TPMBackend *tb, size_t buffersize)
+{
+return tpm_emulator_startup_tpm_resume(tb, buffersize, false);
+}
+
 static bool tpm_emulator_get_tpm_established_flag(TPMBackend *tb)
 {
 TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
@@ -423,16 +449,21 @@ static size_t tpm_emulator_get_buffer_size(TPMBackend *tb)
 static int tpm_emulator_block_migration(TPMEmulator *tpm_emu)
 {
 Error *err = NULL;
+ptm_cap caps = PTM_CAP_GET_STATEBLOB | PTM_CAP_SET_STATEBLOB |
+   PTM_CAP_STOP;
 
-error_setg(_emu->migration_blocker,
-   "Migration disabled: TPM emulator not yet migratable");
-migrate_add_blocker(tpm_emu->migration_blocker, );
-if (err) {
-error_report_err(err);
-error_free(tpm_emu->migration_blocker);
-tpm_emu->migration_blocker = NULL;
+if (!TPM_EMULATOR_IMPLEMENTS_ALL_CAPS(tpm_emu, caps)) {
+error_setg(_emu->migration_blocker,
+   "Migration disabled: TPM emulator does not support "
+   "migration");
+migrate_add_blocker(tpm_emu->migration_blocker, );
+if (err) {
+error_report_err(err);
+error_free(tpm_emu->migration_blocker);
+tpm_emu->migration_blocker = NULL;
 
-return -1;
+return -1;
+}
 }
 
 return 0;
@@ -570,6 +601,267 @@ static const QemuOptDesc tpm_emulator_cmdline_opts[] = {
 { /* end of list */ },
 };
 
+/*
+ * Transfer a TPM state blob from the TPM into a provided buffer.
+ *
+ * @tpm_emu: TPMEmulator
+ * @type: the type of blob to transfer
+ * @tsb: the TPMSizeBuffer to fill with the blob
+ * @flags: the flags to return to the caller
+ */
+static int tpm_emulator_get_state_blob(TPMEmulator *tpm_emu,
+   uint8_t type,
+   TPMSizedBuffer *tsb,
+   uint32_t *flags)
+{
+ptm_getstate pgs;
+ptm_res res;
+ssize_t n;
+uint32_t 

[Qemu-devel] [PATCH v5.2 for 2.13 3/4] docs: tpm: add VM save/restore example and troubleshooting guide

2018-03-16 Thread Stefan Berger
Extend the docs related to TPM with specs related to VM save and
restore and a troubleshooting guide for TPM migration.

Signed-off-by: Stefan Berger 
---
 docs/specs/tpm.txt | 106 +
 1 file changed, 106 insertions(+)

diff --git a/docs/specs/tpm.txt b/docs/specs/tpm.txt
index d1d7157..c230c4c 100644
--- a/docs/specs/tpm.txt
+++ b/docs/specs/tpm.txt
@@ -200,3 +200,109 @@ crw---. 1 root root 10, 224 Jul 11 10:11 /dev/tpm0
 PCR-00: 35 4E 3B CE 23 9F 38 59 ...
 ...
 PCR-23: 00 00 00 00 00 00 00 00 ...
+
+
+=== Migration with the TPM emulator ===
+
+The TPM emulator supports the following types of virtual machine migration:
+
+- VM save / restore (migration into a file)
+- Network migration
+- Snapshotting (migration into storage like QoW2 or QED)
+
+The following command sequences can be used to test VM save / restore.
+
+
+In a 1st terminal start an instance of a swtpm using the following command:
+
+mkdir /tmp/mytpm1
+swtpm socket --tpmstate dir=/tmp/mytpm1 \
+  --ctrl type=unixio,path=/tmp/mytpm1/swtpm-sock \
+  --log level=20 --tpm2
+
+In a 2nd terminal start the VM:
+
+qemu-system-x86_64 -display sdl -enable-kvm \
+  -m 1024 -boot d -bios bios-256k.bin -boot menu=on \
+  -chardev socket,id=chrtpm,path=/tmp/mytpm1/swtpm-sock \
+  -tpmdev emulator,id=tpm0,chardev=chrtpm \
+  -device tpm-tis,tpmdev=tpm0 \
+  -monitor stdio \
+  test.img
+
+Verify that the attached TPM is working as expected using applications inside
+the VM.
+
+To store the state of the VM use the following command in the QEMU monitor in
+the 2nd terminal:
+
+(qemu) migrate "exec:cat > testvm.bin"
+(qemu) quit
+
+At this point a file called 'testvm.bin' should exists and the swtpm and QEMU
+processes should have ended.
+
+To test 'VM restore' you have to start the swtpm with the same parameters
+as before. If previously a TPM 2 [--tpm2] was saved, --tpm2 must now be
+passed again on the command line.
+
+In the 1st terminal restart the swtpm with the same command line as before:
+
+swtpm socket --tpmstate dir=/tmp/mytpm1 \
+  --ctrl type=unixio,path=/tmp/mytpm1/swtpm-sock \
+  --log level=20 --tpm2
+
+In the 2nd terminal restore the state of the VM using the additonal
+'-incoming' option.
+
+qemu-system-x86_64 -display sdl -enable-kvm \
+  -m 1024 -boot d -bios bios-256k.bin -boot menu=on \
+  -chardev socket,id=chrtpm,path=/tmp/mytpm1/swtpm-sock \
+  -tpmdev emulator,id=tpm0,chardev=chrtpm \
+  -device tpm-tis,tpmdev=tpm0 \
+  -incoming "exec:cat < testvm.bin" \
+  test.img
+
+
+Troubleshooting migration:
+
+There are several reasons why migration may fail. In case of problems,
+please ensure that the command lines adhere to the following rules and,
+if possible, that identical versions of QEMU and swtpm are used at all
+times.
+
+VM save and restore:
+ - QEMU command line parameters should be identical apart from the
+   '-incoming' option on VM restore
+ - swtpm command line parameters should be identical
+
+VM migration to 'localhost':
+ - QEMU command line parameters should be identical apart from the
+   '-incoming' option on the destination side
+ - swtpm command line parameters should point to two different
+   directories on the source and destination swtpm (--tpmstate dir=...)
+   (especially if different versions of libtpms were to be used on the
+   same machine).
+
+VM migration across the network:
+ - QEMU command line parameters should be identical apart from the
+   '-incoming' option on the destination side
+ - swtpm command line parameters should be identical
+
+VM Snapshotting:
+ - QEMU command line parameters should be identical
+ - swtpm command line parameters should be identical
+
+
+Besides that, migration failure reasons on the swtpm level may include
+the following:
+
+ - the versions of the swtpm on the source and destination sides are
+   incompatible
+   - downgrading of TPM state may not be supported
+   - the source and destination libtpms were compiled with different
+ compile-time options and the destination side refuses to accept the
+ state
+ - different migration keys are used on the source and destination side
+   and the destination side cannot decrypt the migrated state
+   (swtpm ... --migration-key ... )
-- 
2.5.5




[Qemu-devel] [Bug 1435359] Re: Booting kernel 3.19.2 fails most of the time

2018-03-16 Thread Bart Van Assche
I haven't seen this for a long time so please proceed with closing this
ticket.

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

Title:
  Booting kernel 3.19.2 fails most of the time

Status in QEMU:
  Incomplete

Bug description:
  Host system: openSuSE 13.2 + kernel 4.0.0-rc4 + qemu 2.2.1.

  When I try to boot a virtual machine with Ubuntu 14.10 and kernel
  3.13.0 every boot succeeds. However, with kernel 3.19.2 booting fails
  most of the time. The following appears in /var/log/libvirt/qemu
  /ubuntu-vm.log when I try to boot that VM with kernel 3.19.2:

  2015-03-23 02:44:18.801+: starting up
  LC_ALL=C PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 
QEMU_AUDIO_DRV=spice /usr/bin/qemu-system-x86_64 -name ubuntu-vm -S -machine 
pc-i440fx-2.1,accel=kvm,usb=off -cpu Haswell -m 2048 -realtime mlock=off -smp 
4,sockets=4,cores=1,threads=1 -uuid 395110dc-9fbe-4542-8fce-4ef958f24b2c 
-no-user-config -nodefaults -chardev 
socket,id=charmonitor,path=/var/lib/libvirt/qemu/ubuntu-vm.monitor,server,nowait
 -mon chardev=charmonitor,id=monitor,mode=control -rtc base=utc,driftfix=slew 
-global kvm-pit.lost_tick_policy=discard -no-hpet -no-shutdown -global 
PIIX4_PM.disable_s3=1 -global PIIX4_PM.disable_s4=1 -boot strict=on -device 
ich9-usb-ehci1,id=usb,bus=pci.0,addr=0x5.0x7 -device 
ich9-usb-uhci1,masterbus=usb.0,firstport=0,bus=pci.0,multifunction=on,addr=0x5 
-device ich9-usb-uhci2,masterbus=usb.0,firstport=2,bus=pci.0,addr=0x5.0x1 
-device ich9-usb-uhci3,masterbus=usb.0,firstport=4,bus=pci.0,addr=0x5.0x2 
-device virtio-serial-pci,id=virtio-serial0,bus=pci.0,addr=0x4 -drive 
file=/var/lib/libvirt/images/ubuntusaucy.qcow2,if=none,id=drive-virtio-disk0,format=qcow2
 -device 
virtio-blk-pci,scsi=off,bus=pci.0,addr=0x7,drive=drive-virtio-disk0,id=virtio-disk0,bootindex=1
 -drive 
file=/var/lib/libvirt/images/ubuntu-14.04-mini.iso,if=none,id=drive-ide0-0-0,readonly=on,format=raw
 -device ide-cd,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0,bootindex=2 
-netdev tap,fd=22,id=hostnet0,vhost=on,vhostfd=23 -device 
virtio-net-pci,netdev=hostnet0,id=net0,mac=52:54:00:5e:71:5e,bus=pci.0,addr=0x3 
-chardev spicevmc,id=charchannel0,name=vdagent -device 
virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,id=channel0,name=com.redhat.spice.0
 -spice port=5900,addr=127.0.0.1,disable-ticketing,seamless-migration=on 
-device 
qxl-vga,id=video0,ram_size=67108864,vram_size=67108864,bus=pci.0,addr=0x2 
-chardev spicevmc,id=charredir0,name=usbredir -device 
usb-redir,chardev=charredir0,id=redir0 -chardev 
spicevmc,id=charredir1,name=usbredir -device 
usb-redir,chardev=charredir1,id=redir1 -chardev 
spicevmc,id=charredir2,name=usbredir -device 
usb-redir,chardev=charredir2,id=redir2 -chardev 
spicevmc,id=charredir3,name=usbredir -device 
usb-redir,chardev=charredir3,id=redir3 -device 
virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x8 -object 
rng-random,id=rng0,filename=/dev/random -device 
virtio-rng-pci,rng=rng0,bus=pci.0,addr=0x9 -msg timestamp=on
  main_channel_link: add main channel client
  main_channel_handle_parsed: net test: latency 0.229000 ms, bitrate 
284 bps (27126.736111 Mbps)
  red_dispatcher_set_cursor_peer: 
  inputs_connect: inputs channel client create
  ((null):30728): SpiceWorker-ERROR **: 
red_worker.c:8337:red_marshall_qxl_drawable: invalid type
  KVM: injection failed, MSI lost (Input/output error)
  qemu-system-x86_64: /home/bart/software/qemu-2.2.1/hw/net/vhost_net.c:264: 
vhost_net_stop_one: Assertion `r >= 0' failed.
  2015-03-23 02:44:44.952+: shutting down

  That message is similar to the message reported by the older qemu
  version provided by openSuse (qemu 2.1.0 + qemu-kvm 2.1.0):

  2015-03-21 13:51:00.724+: starting up
  LC_ALL=C PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 
QEMU_AUDIO_DRV=spice /usr/bin/qemu-system-x86_64 -name ubuntu-vm -S -machine 
pc-i440fx-2.1,accel=kvm,usb=off -cpu Haswell -m 1024 -realtime mlock=off -smp 
4,sockets=4,cores=1,threads=1 -uuid 395110dc-9fbe-4542-8fce-4ef958f24b2c 
-no-user-config -nodefaults -chardev 
socket,id=charmonitor,path=/var/lib/libvirt/qemu/ubuntu-vm.monitor,server,nowait
 -mon chardev=charmonitor,id=monitor,mode=control -rtc base=utc,driftfix=slew 
-global kvm-pit.lost_tick_policy=discard -no-hpet -no-shutdown -global 
PIIX4_PM.disable_s3=1 -global PIIX4_PM.disable_s4=1 -boot strict=on -device 
ich9-usb-ehci1,id=usb,bus=pci.0,addr=0x5.0x7 -device 
ich9-usb-uhci1,masterbus=usb.0,firstport=0,bus=pci.0,multifunction=on,addr
  =0x5 -device 
ich9-usb-uhci2,masterbus=usb.0,firstport=2,bus=pci.0,addr=0x5.0x1 -device 
ich9-usb-uhci3,masterbus=usb.0,firstport=4,bus=pci.0,addr=0x5.0x2 -device 
virtio-serial-pci,id=virtio-serial0,bus=pci.0,addr=0x6 -drive 
file=/var/lib/libvirt/images/ubuntusaucy.qcow2,if=none,id=drive-virtio-disk0,format=qcow2
 -device 

Re: [Qemu-devel] [PATCH v3 00/22] More fully implement ARM PMUv3

2018-03-16 Thread Aaron Lindsay
My apologies for the below style issues - I've already fixed them up for
v4...

-Aaron

On Mar 16 13:58, no-re...@patchew.org wrote:
> Hi,
> 
> This series seems to have some coding style problems. See output below for
> more information:
> 
> Type: series
> Message-id: 1521232280-13089-1-git-send-email-alind...@codeaurora.org
> Subject: [Qemu-devel] [PATCH v3 00/22] More fully implement ARM PMUv3
> 
> === TEST SCRIPT BEGIN ===
> #!/bin/bash
> 
> BASE=base
> n=1
> total=$(git log --oneline $BASE.. | wc -l)
> failed=0
> 
> git config --local diff.renamelimit 0
> git config --local diff.renames True
> git config --local diff.algorithm histogram
> 
> commits="$(git log --format=%H --reverse $BASE..)"
> for c in $commits; do
> echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
> if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; 
> then
> failed=1
> echo
> fi
> n=$((n+1))
> done
> 
> exit $failed
> === TEST SCRIPT END ===
> 
> Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
> From https://github.com/patchew-project/qemu
>  * [new tag]   
> patchew/1521232280-13089-1-git-send-email-alind...@codeaurora.org -> 
> patchew/1521232280-13089-1-git-send-email-alind...@codeaurora.org
> Switched to a new branch 'test'
> d81791b184 target/arm: Implement PMSWINC
> 512124d018 target/arm: PMU: Set PMCR.N to 4
> b748e97306 target/arm: PMU: Add instruction and cycle events
> 7e46a77f89 target/arm: Finish implementation of PM[X]EVCNTR and PM[X]EVTYPER
> 82cffef855 target/arm: Add array for supported PMU events, generate PMCEID[01]
> d635021d0a target/arm: Split arm_ccnt_enabled into generic pmu_counter_enabled
> 3e1b438deb target/arm: Implement PMOVSSET
> c13c832988 target/arm: Add ARM_FEATURE_V7VE for v7 Virtualization Extensions
> 9c80af4d82 target/arm: Make PMOVSCLR 64 bits wide
> 8ffbcd3dd8 target/arm: Allow AArch32 access for PMCCFILTR
> 7dc4ec9715 target/arm: Filter cycle counter based on PMCCFILTR_EL0
> f1e40f9fff target/arm: Fix bitmask for PMCCFILTR writes
> eb142b42b4 target/arm: Allow EL change hooks to do IO
> d37186abdd target/arm: Add pre-EL change hooks
> ae12e161da target/arm: Support multiple EL change hooks
> 9bfa99805d target/arm: Fetch GICv3 state directly from CPUARMState
> 881bee5e96 target/arm: Mask PMU register writes based on PMCR_EL0.N
> 890ad6472b target/arm: Reorganize PMCCNTR read, write, sync
> 922eec023b target/arm: Treat PMCCNTR as alias of PMCCNTR_EL0
> 5b1ce33c0b target/arm: Check PMCNTEN for whether PMCCNTR is enabled
> 2ecb09ae04 target/arm: A15 PMCEID0 initialization style nit
> 0f26a1568a target/arm: A53: Initialize PMCEID[01]
> 
> === OUTPUT BEGIN ===
> Checking PATCH 1/22: target/arm: A53: Initialize PMCEID[01]...
> Checking PATCH 2/22: target/arm: A15 PMCEID0 initialization style nit...
> Checking PATCH 3/22: target/arm: Check PMCNTEN for whether PMCCNTR is 
> enabled...
> Checking PATCH 4/22: target/arm: Treat PMCCNTR as alias of PMCCNTR_EL0...
> Checking PATCH 5/22: target/arm: Reorganize PMCCNTR read, write, sync...
> Checking PATCH 6/22: target/arm: Mask PMU register writes based on 
> PMCR_EL0.N...
> Checking PATCH 7/22: target/arm: Fetch GICv3 state directly from 
> CPUARMState...
> Checking PATCH 8/22: target/arm: Support multiple EL change hooks...
> ERROR: space prohibited between function name and open parenthesis '('
> #26: FILE: target/arm/cpu.c:62:
> +entry = g_malloc0(sizeof (*entry));
> 
> total: 1 errors, 0 warnings, 87 lines checked
> 
> Your patch has style problems, please review.  If any of these errors
> are false positives report them to the maintainer, see
> CHECKPATCH in MAINTAINERS.
> 
> Checking PATCH 9/22: target/arm: Add pre-EL change hooks...
> ERROR: space prohibited between function name and open parenthesis '('
> #26: FILE: target/arm/cpu.c:62:
> +entry = g_malloc0(sizeof (*entry));
> 
> total: 1 errors, 0 warnings, 110 lines checked
> 
> Your patch has style problems, please review.  If any of these errors
> are false positives report them to the maintainer, see
> CHECKPATCH in MAINTAINERS.
> 
> Checking PATCH 10/22: target/arm: Allow EL change hooks to do IO...
> Checking PATCH 11/22: target/arm: Fix bitmask for PMCCFILTR writes...
> Checking PATCH 12/22: target/arm: Filter cycle counter based on 
> PMCCFILTR_EL0...
> Checking PATCH 13/22: target/arm: Allow AArch32 access for PMCCFILTR...
> Checking PATCH 14/22: target/arm: Make PMOVSCLR 64 bits wide...
> Checking PATCH 15/22: target/arm: Add ARM_FEATURE_V7VE for v7 Virtualization 
> Extensions...
> Checking PATCH 16/22: target/arm: Implement PMOVSSET...
> WARNING: line over 80 characters
> #39: FILE: target/arm/helper.c:1417:
> +  .access = PL0_RW, .fieldoffset = offsetoflow32(CPUARMState, 
> cp15.c9_pmovsr),
> 
> total: 0 errors, 1 warnings, 59 lines checked
> 
> Your patch has style problems, please review.  If any of these errors
> are false positives report them to the maintainer, see
> CHECKPATCH in 

Re: [Qemu-devel] [PATCH v5.1 for 2.13 0/4] tpm: Extend TPM with state migration support

2018-03-16 Thread no-reply
Hi,

This series seems to have some coding style problems. See output below for
more information:

Type: series
Message-id: 1521242665-15807-1-git-send-email-stef...@linux.vnet.ibm.com
Subject: [Qemu-devel] [PATCH v5.1 for 2.13 0/4] tpm: Extend TPM with state 
migration support

=== TEST SCRIPT BEGIN ===
#!/bin/bash

BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0

git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram

commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
failed=1
echo
fi
n=$((n+1))
done

exit $failed
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 * [new tag]   
patchew/1521242665-15807-1-git-send-email-stef...@linux.vnet.ibm.com -> 
patchew/1521242665-15807-1-git-send-email-stef...@linux.vnet.ibm.com
Switched to a new branch 'test'
1195d3f6ef tpm: Add test cases that uses the external swtpm with CRB interface
c462cd1932 docs: tpm: add VM save/restore example and troubleshooting guide
ad36584301 tpm: extend TPM TIS with state migration support
b6f35a440a tpm: extend TPM emulator with state migration support

=== OUTPUT BEGIN ===
Checking PATCH 1/4: tpm: extend TPM emulator with state migration support...
Checking PATCH 2/4: tpm: extend TPM TIS with state migration support...
Checking PATCH 3/4: docs: tpm: add VM save/restore example and troubleshooting 
guide...
Checking PATCH 4/4: tpm: Add test cases that uses the external swtpm with CRB 
interface...
ERROR: braces {} are necessary for all arms of this statement
#331: FILE: tests/tpm-util.c:36:
+} while (g_get_monotonic_time() < end_time);
[...]

ERROR: line over 90 characters
#387: FILE: tests/tpm-util.c:92:
+gboolean tpm_util_swtpm_start(const char *path, GPid *pid, SocketAddress 
**addr, GError **error)

ERROR: braces {} are necessary for all arms of this statement
#409: FILE: tests/tpm-util.c:114:
+for (i = 0; swtpm_argv[i]; i++)
[...]

ERROR: braces {} are necessary for all arms of this statement
#419: FILE: tests/tpm-util.c:124:
+if (!pid)
[...]

total: 4 errors, 0 warnings, 430 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

=== OUTPUT END ===

Test command exited with code: 1


---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-de...@freelists.org

[Qemu-devel] [PATCH v5.1 for 2.13 3/4] docs: tpm: add VM save/restore example and troubleshooting guide

2018-03-16 Thread Stefan Berger
Extend the docs related to TPM with specs related to VM save and
restore and a troubleshooting guide for TPM migration.

Signed-off-by: Stefan Berger 
---
 docs/specs/tpm.txt | 106 +
 1 file changed, 106 insertions(+)

diff --git a/docs/specs/tpm.txt b/docs/specs/tpm.txt
index d1d7157..c230c4c 100644
--- a/docs/specs/tpm.txt
+++ b/docs/specs/tpm.txt
@@ -200,3 +200,109 @@ crw---. 1 root root 10, 224 Jul 11 10:11 /dev/tpm0
 PCR-00: 35 4E 3B CE 23 9F 38 59 ...
 ...
 PCR-23: 00 00 00 00 00 00 00 00 ...
+
+
+=== Migration with the TPM emulator ===
+
+The TPM emulator supports the following types of virtual machine migration:
+
+- VM save / restore (migration into a file)
+- Network migration
+- Snapshotting (migration into storage like QoW2 or QED)
+
+The following command sequences can be used to test VM save / restore.
+
+
+In a 1st terminal start an instance of a swtpm using the following command:
+
+mkdir /tmp/mytpm1
+swtpm socket --tpmstate dir=/tmp/mytpm1 \
+  --ctrl type=unixio,path=/tmp/mytpm1/swtpm-sock \
+  --log level=20 --tpm2
+
+In a 2nd terminal start the VM:
+
+qemu-system-x86_64 -display sdl -enable-kvm \
+  -m 1024 -boot d -bios bios-256k.bin -boot menu=on \
+  -chardev socket,id=chrtpm,path=/tmp/mytpm1/swtpm-sock \
+  -tpmdev emulator,id=tpm0,chardev=chrtpm \
+  -device tpm-tis,tpmdev=tpm0 \
+  -monitor stdio \
+  test.img
+
+Verify that the attached TPM is working as expected using applications inside
+the VM.
+
+To store the state of the VM use the following command in the QEMU monitor in
+the 2nd terminal:
+
+(qemu) migrate "exec:cat > testvm.bin"
+(qemu) quit
+
+At this point a file called 'testvm.bin' should exists and the swtpm and QEMU
+processes should have ended.
+
+To test 'VM restore' you have to start the swtpm with the same parameters
+as before. If previously a TPM 2 [--tpm2] was saved, --tpm2 must now be
+passed again on the command line.
+
+In the 1st terminal restart the swtpm with the same command line as before:
+
+swtpm socket --tpmstate dir=/tmp/mytpm1 \
+  --ctrl type=unixio,path=/tmp/mytpm1/swtpm-sock \
+  --log level=20 --tpm2
+
+In the 2nd terminal restore the state of the VM using the additonal
+'-incoming' option.
+
+qemu-system-x86_64 -display sdl -enable-kvm \
+  -m 1024 -boot d -bios bios-256k.bin -boot menu=on \
+  -chardev socket,id=chrtpm,path=/tmp/mytpm1/swtpm-sock \
+  -tpmdev emulator,id=tpm0,chardev=chrtpm \
+  -device tpm-tis,tpmdev=tpm0 \
+  -incoming "exec:cat < testvm.bin" \
+  test.img
+
+
+Troubleshooting migration:
+
+There are several reasons why migration may fail. In case of problems,
+please ensure that the command lines adhere to the following rules and,
+if possible, that identical versions of QEMU and swtpm are used at all
+times.
+
+VM save and restore:
+ - QEMU command line parameters should be identical apart from the
+   '-incoming' option on VM restore
+ - swtpm command line parameters should be identical
+
+VM migration to 'localhost':
+ - QEMU command line parameters should be identical apart from the
+   '-incoming' option on the destination side
+ - swtpm command line parameters should point to two different
+   directories on the source and destination swtpm (--tpmstate dir=...)
+   (especially if different versions of libtpms were to be used on the
+   same machine).
+
+VM migration across the network:
+ - QEMU command line parameters should be identical apart from the
+   '-incoming' option on the destination side
+ - swtpm command line parameters should be identical
+
+VM Snapshotting:
+ - QEMU command line parameters should be identical
+ - swtpm command line parameters should be identical
+
+
+Besides that, migration failure reasons on the swtpm level may include
+the following:
+
+ - the versions of the swtpm on the source and destination sides are
+   incompatible
+   - downgrading of TPM state may not be supported
+   - the source and destination libtpms were compiled with different
+ compile-time options and the destination side refuses to accept the
+ state
+ - different migration keys are used on the source and destination side
+   and the destination side cannot decrypt the migrated state
+   (swtpm ... --migration-key ... )
-- 
2.5.5




[Qemu-devel] [PATCH v5.1 for 2.13 1/4] tpm: extend TPM emulator with state migration support

2018-03-16 Thread Stefan Berger
Extend the TPM emulator backend device with state migration support.

The external TPM emulator 'swtpm' provides a protocol over
its control channel to retrieve its state blobs. We implement
functions for getting and setting the different state blobs.
In case the setting of the state blobs fails, we return a
negative errno code to fail the start of the VM.

Since we have an external TPM emulator, we need to make sure
that we do not migrate the state for as long as it is busy
processing a request. We need to wait for notification that
the request has completed processing.

Signed-off-by: Stefan Berger 
---
 hw/tpm/tpm_emulator.c | 318 --
 hw/tpm/trace-events   |   8 +-
 2 files changed, 314 insertions(+), 12 deletions(-)

diff --git a/hw/tpm/tpm_emulator.c b/hw/tpm/tpm_emulator.c
index 6418ef0..6d6158d 100644
--- a/hw/tpm/tpm_emulator.c
+++ b/hw/tpm/tpm_emulator.c
@@ -4,7 +4,7 @@
  *  Copyright (c) 2017 Intel Corporation
  *  Author: Amarnath Valluri 
  *
- *  Copyright (c) 2010 - 2013 IBM Corporation
+ *  Copyright (c) 2010 - 2013, 2018 IBM Corporation
  *  Authors:
  *Stefan Berger 
  *
@@ -49,6 +49,19 @@
 #define TPM_EMULATOR_IMPLEMENTS_ALL_CAPS(S, cap) (((S)->caps & (cap)) == (cap))
 
 /* data structures */
+
+/* blobs from the TPM; part of VM state when migrating */
+typedef struct TPMBlobBuffers {
+uint32_t permanent_flags;
+TPMSizedBuffer permanent;
+
+uint32_t volatil_flags;
+TPMSizedBuffer volatil;
+
+uint32_t savestate_flags;
+TPMSizedBuffer savestate;
+} TPMBlobBuffers;
+
 typedef struct TPMEmulator {
 TPMBackend parent;
 
@@ -64,6 +77,8 @@ typedef struct TPMEmulator {
 
 unsigned int established_flag:1;
 unsigned int established_flag_cached:1;
+
+TPMBlobBuffers state_blobs;
 } TPMEmulator;
 
 
@@ -293,7 +308,8 @@ static int tpm_emulator_set_buffer_size(TPMBackend *tb,
 return 0;
 }
 
-static int tpm_emulator_startup_tpm(TPMBackend *tb, size_t buffersize)
+static int tpm_emulator_startup_tpm_resume(TPMBackend *tb, size_t buffersize,
+ bool is_resume)
 {
 TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
 ptm_init init = {
@@ -301,12 +317,17 @@ static int tpm_emulator_startup_tpm(TPMBackend *tb, 
size_t buffersize)
 };
 ptm_res res;
 
+trace_tpm_emulator_startup_tpm_resume(is_resume, buffersize);
+
 if (buffersize != 0 &&
 tpm_emulator_set_buffer_size(tb, buffersize, NULL) < 0) {
 goto err_exit;
 }
 
-trace_tpm_emulator_startup_tpm();
+if (is_resume) {
+init.u.req.init_flags |= cpu_to_be32(PTM_INIT_FLAG_DELETE_VOLATILE);
+}
+
 if (tpm_emulator_ctrlcmd(tpm_emu, CMD_INIT, , sizeof(init),
  sizeof(init)) < 0) {
 error_report("tpm-emulator: could not send INIT: %s",
@@ -325,6 +346,11 @@ err_exit:
 return -1;
 }
 
+static int tpm_emulator_startup_tpm(TPMBackend *tb, size_t buffersize)
+{
+return tpm_emulator_startup_tpm_resume(tb, buffersize, false);
+}
+
 static bool tpm_emulator_get_tpm_established_flag(TPMBackend *tb)
 {
 TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
@@ -423,16 +449,21 @@ static size_t tpm_emulator_get_buffer_size(TPMBackend *tb)
 static int tpm_emulator_block_migration(TPMEmulator *tpm_emu)
 {
 Error *err = NULL;
+ptm_cap caps = PTM_CAP_GET_STATEBLOB | PTM_CAP_SET_STATEBLOB |
+   PTM_CAP_STOP;
 
-error_setg(_emu->migration_blocker,
-   "Migration disabled: TPM emulator not yet migratable");
-migrate_add_blocker(tpm_emu->migration_blocker, );
-if (err) {
-error_report_err(err);
-error_free(tpm_emu->migration_blocker);
-tpm_emu->migration_blocker = NULL;
+if (!TPM_EMULATOR_IMPLEMENTS_ALL_CAPS(tpm_emu, caps)) {
+error_setg(_emu->migration_blocker,
+   "Migration disabled: TPM emulator does not support "
+   "migration");
+migrate_add_blocker(tpm_emu->migration_blocker, );
+if (err) {
+error_report_err(err);
+error_free(tpm_emu->migration_blocker);
+tpm_emu->migration_blocker = NULL;
 
-return -1;
+return -1;
+}
 }
 
 return 0;
@@ -570,6 +601,267 @@ static const QemuOptDesc tpm_emulator_cmdline_opts[] = {
 { /* end of list */ },
 };
 
+/*
+ * Transfer a TPM state blob from the TPM into a provided buffer.
+ *
+ * @tpm_emu: TPMEmulator
+ * @type: the type of blob to transfer
+ * @tsb: the TPMSizeBuffer to fill with the blob
+ * @flags: the flags to return to the caller
+ */
+static int tpm_emulator_get_state_blob(TPMEmulator *tpm_emu,
+   uint8_t type,
+   TPMSizedBuffer *tsb,
+   uint32_t *flags)
+{
+ptm_getstate pgs;
+ptm_res res;
+ssize_t n;
+uint32_t 

[Qemu-devel] [PATCH v5.1 for 2.13 4/4] tpm: Add test cases that uses the external swtpm with CRB interface

2018-03-16 Thread Stefan Berger
Add a test program for testing the CRB with the external swtpm.

The 1st test case extends a PCR and reads back the value and compares
it against an expected return packet.

The 2nd test case repeats the 1st test case and then migrates the
external swtpm's state along with the VM state to a destination
QEMU and swtpm and checks that the PCR has the expected value now.

Signed-off-by: Stefan Berger 
---
 tests/Makefile.include |   3 +
 tests/tpm-crb-swtpm-test.c | 244 +
 tests/tpm-util.c   | 135 +
 tests/tpm-util.h   |  36 +++
 4 files changed, 418 insertions(+)
 create mode 100644 tests/tpm-crb-swtpm-test.c
 create mode 100644 tests/tpm-util.c
 create mode 100644 tests/tpm-util.h

diff --git a/tests/Makefile.include b/tests/Makefile.include
index 42fd426..bd4f56f 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -297,6 +297,7 @@ check-qtest-i386-$(CONFIG_VHOST_USER_NET_TEST_i386) += 
tests/vhost-user-test$(EX
 ifeq ($(CONFIG_VHOST_USER_NET_TEST_i386),)
 check-qtest-x86_64-$(CONFIG_VHOST_USER_NET_TEST_x86_64) += 
tests/vhost-user-test$(EXESUF)
 endif
+check-qtest-i386-$(CONFIG_TPM) += tests/tpm-crb-swtpm-test$(EXESUF)
 check-qtest-i386-$(CONFIG_TPM) += tests/tpm-crb-test$(EXESUF)
 check-qtest-i386-$(CONFIG_TPM) += tests/tpm-tis-test$(EXESUF)
 check-qtest-i386-$(CONFIG_SLIRP) += tests/test-netfilter$(EXESUF)
@@ -719,6 +720,8 @@ tests/test-util-sockets$(EXESUF): tests/test-util-sockets.o 
\
 tests/test-io-task$(EXESUF): tests/test-io-task.o $(test-io-obj-y)
 tests/test-io-channel-socket$(EXESUF): tests/test-io-channel-socket.o \
 tests/io-channel-helpers.o tests/socket-helpers.o $(test-io-obj-y)
+tests/tpm-crb-swtpm-test$(EXESUF): tests/tpm-crb-swtpm-test.o tests/tpm-emu.o \
+   tests/tpm-util.o $(test-io-obj-y)
 tests/tpm-crb-test$(EXESUF): tests/tpm-crb-test.o tests/tpm-emu.o 
$(test-io-obj-y)
 tests/tpm-tis-test$(EXESUF): tests/tpm-tis-test.o tests/tpm-emu.o 
$(test-io-obj-y)
 tests/test-io-channel-file$(EXESUF): tests/test-io-channel-file.o \
diff --git a/tests/tpm-crb-swtpm-test.c b/tests/tpm-crb-swtpm-test.c
new file mode 100644
index 000..b2f6068
--- /dev/null
+++ b/tests/tpm-crb-swtpm-test.c
@@ -0,0 +1,244 @@
+/*
+ * QTest testcase for TPM CRB talking to external swtpm and swtpm migration
+ *
+ * Copyright (c) 2018 IBM Corporation
+ *  with parts borrowed from migration-test.c that is:
+ * Copyright (c) 2016-2018 Red Hat, Inc. and/or its affiliates
+ *
+ * Authors:
+ *   Stefan Berger 
+ *
+ * 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 
+
+#include "hw/acpi/tpm.h"
+#include "io/channel-socket.h"
+#include "libqtest.h"
+#include "tpm-util.h"
+#include "sysemu/tpm.h"
+#include "qapi/qmp/qdict.h"
+
+typedef struct TestState {
+char *src_tpm_path;
+char *dst_tpm_path;
+char *uri;
+} TestState;
+
+bool got_stop;
+
+static void migrate(QTestState *who, const char *uri)
+{
+QDict *rsp;
+gchar *cmd;
+
+cmd = g_strdup_printf("{ 'execute': 'migrate',"
+  "'arguments': { 'uri': '%s' } }",
+  uri);
+rsp = qtest_qmp(who, cmd);
+g_free(cmd);
+g_assert(qdict_haskey(rsp, "return"));
+QDECREF(rsp);
+}
+
+/*
+ * Events can get in the way of responses we are actually waiting for.
+ */
+static QDict *wait_command(QTestState *who, const char *command)
+{
+const char *event_string;
+QDict *response;
+
+response = qtest_qmp(who, command);
+
+while (qdict_haskey(response, "event")) {
+/* OK, it was an event */
+event_string = qdict_get_str(response, "event");
+if (!strcmp(event_string, "STOP")) {
+got_stop = true;
+}
+QDECREF(response);
+response = qtest_qmp_receive(who);
+}
+return response;
+}
+
+static void wait_for_migration_complete(QTestState *who)
+{
+while (true) {
+QDict *rsp, *rsp_return;
+bool completed;
+const char *status;
+
+rsp = wait_command(who, "{ 'execute': 'query-migrate' }");
+rsp_return = qdict_get_qdict(rsp, "return");
+status = qdict_get_str(rsp_return, "status");
+completed = strcmp(status, "completed") == 0;
+g_assert_cmpstr(status, !=,  "failed");
+QDECREF(rsp);
+if (completed) {
+return;
+}
+usleep(1000);
+}
+}
+
+static void migration_start_qemu(QTestState **src_qemu, QTestState **dst_qemu,
+ SocketAddress *src_tpm_addr,
+ SocketAddress *dst_tpm_addr,
+ const char *miguri)
+{
+char *src_qemu_args, *dst_qemu_args;
+
+src_qemu_args = g_strdup_printf(
+"-chardev socket,id=chr,path=%s "
+

Re: [Qemu-devel] [PATCH v5 for 2.13 0/4] tpm: Extend TPM with state migration support

2018-03-16 Thread Stefan Berger

On 03/16/2018 06:00 PM, no-re...@patchew.org wrote:

Hi,

This series failed docker-quick@centos6 build test. Please find the testing 
commands and
their output below. If you have Docker installed, you can probably reproduce it
locally.

Type: series
Message-id: 1521236796-24551-1-git-send-email-stef...@linux.vnet.ibm.com
Subject: [Qemu-devel] [PATCH v5 for 2.13 0/4] tpm: Extend TPM with state 
migration support


make: *** No rule to make target `tests/tpm-util.o', needed by 
`tests/tpm-crb-swtpm-test'.  Stop.
make: *** Waiting for unfinished jobs
   CC  tests/tpm-emu.o
/tmp/qemu-test/src/tests/tpm-crb-swtpm-test.c:21:22: error: tpm-util.h: No such 
file or directory
/tmp/qemu-test/src/tests/tpm-crb-swtpm-test.c: In function 'tpm_crb_swtpm_test':
/tmp/qemu-test/src/tests/tpm-crb-swtpm-test.c:127: warning: implicit 
declaration of function 'tpm_util_swtpm_start'
/tmp/qemu-test/src/tests/tpm-crb-swtpm-test.c:127: warning: nested extern 
declaration of 'tpm_util_swtpm_start'
/tmp/qemu-test/src/tests/tpm-crb-swtpm-test.c:140: warning: implicit 
declaration of function 'tpm_util_startup'
/tmp/qemu-test/src/tests/tpm-crb-swtpm-test.c:140: warning: nested extern 
declaration of 'tpm_util_startup'
/tmp/qemu-test/src/tests/tpm-crb-swtpm-test.c:140: error: 
'tpm_util_crb_transfer' undeclared (first use in this function)
/tmp/qemu-test/src/tests/tpm-crb-swtpm-test.c:140: error: (Each undeclared 
identifier is reported only once
/tmp/qemu-test/src/tests/tpm-crb-swtpm-test.c:140: error: for each function it 
appears in.)
/tmp/qemu-test/src/tests/tpm-crb-swtpm-test.c:141: warning: implicit 
declaration of function 'tpm_util_pcrextend'
/tmp/qemu-test/src/tests/tpm-crb-swtpm-test.c:141: warning: nested extern 
declaration of 'tpm_util_pcrextend'
/tmp/qemu-test/src/tests/tpm-crb-swtpm-test.c:148: warning: implicit 
declaration of function 'tpm_util_pcrread'
/tmp/qemu-test/src/tests/tpm-crb-swtpm-test.c:148: warning: nested extern 
declaration of 'tpm_util_pcrread'
/tmp/qemu-test/src/tests/tpm-crb-swtpm-test.c:152: warning: implicit 
declaration of function 'tpm_util_swtpm_kill'
/tmp/qemu-test/src/tests/tpm-crb-swtpm-test.c:152: warning: nested extern 
declaration of 'tpm_util_swtpm_kill'
/tmp/qemu-test/src/tests/tpm-crb-swtpm-test.c: In function 
'tpm_crb_swtpm_migration_test':
/tmp/qemu-test/src/tests/tpm-crb-swtpm-test.c:186: error: 
'tpm_util_crb_transfer' undeclared (first use in this function)


Missing new files. Thanks for pointing this out. V5.1 fixes it.

Stefan




[Qemu-devel] [PATCH v5.1 for 2.13 2/4] tpm: extend TPM TIS with state migration support

2018-03-16 Thread Stefan Berger
Extend the TPM TIS interface with state migration support.

We need to synchronize with the backend thread to make sure that a command
being processed by the external TPM emulator has completed and its
response been received.

Signed-off-by: Stefan Berger 
---
 hw/tpm/tpm_tis.c| 52 ++--
 hw/tpm/trace-events |  1 +
 2 files changed, 51 insertions(+), 2 deletions(-)

diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
index 2ac7e74..fec3d73 100644
--- a/hw/tpm/tpm_tis.c
+++ b/hw/tpm/tpm_tis.c
@@ -894,9 +894,57 @@ static void tpm_tis_reset(DeviceState *dev)
 tpm_backend_startup_tpm(s->be_driver, s->be_buffer_size);
 }
 
+/* persistent state handling */
+
+static int tpm_tis_pre_save(void *opaque)
+{
+TPMState *s = opaque;
+uint8_t locty = s->active_locty;
+
+trace_tpm_tis_pre_save(locty, s->rw_offset);
+
+if (DEBUG_TIS) {
+tpm_tis_dump_state(opaque, 0);
+}
+
+/*
+ * Synchronize with backend completion.
+ */
+tpm_backend_finish_sync(s->be_driver);
+
+return 0;
+}
+
+static const VMStateDescription vmstate_locty = {
+.name = "tpm-tis/locty",
+.version_id = 1,
+.fields  = (VMStateField[]) {
+VMSTATE_UINT32(state, TPMLocality),
+VMSTATE_UINT32(inte, TPMLocality),
+VMSTATE_UINT32(ints, TPMLocality),
+VMSTATE_UINT8(access, TPMLocality),
+VMSTATE_UINT32(sts, TPMLocality),
+VMSTATE_UINT32(iface_id, TPMLocality),
+VMSTATE_END_OF_LIST(),
+}
+};
+
 static const VMStateDescription vmstate_tpm_tis = {
-.name = "tpm",
-.unmigratable = 1,
+.name = "tpm-tis",
+.version_id = 1,
+.pre_save  = tpm_tis_pre_save,
+.fields = (VMStateField[]) {
+VMSTATE_BUFFER(buffer, TPMState),
+VMSTATE_UINT16(rw_offset, TPMState),
+VMSTATE_UINT8(active_locty, TPMState),
+VMSTATE_UINT8(aborting_locty, TPMState),
+VMSTATE_UINT8(next_locty, TPMState),
+
+VMSTATE_STRUCT_ARRAY(loc, TPMState, TPM_TIS_NUM_LOCALITIES, 1,
+ vmstate_locty, TPMLocality),
+
+VMSTATE_END_OF_LIST()
+}
 };
 
 static Property tpm_tis_properties[] = {
diff --git a/hw/tpm/trace-events b/hw/tpm/trace-events
index c5bfbf1..25bee0c 100644
--- a/hw/tpm/trace-events
+++ b/hw/tpm/trace-events
@@ -50,3 +50,4 @@ tpm_tis_mmio_write_locty_seized(uint8_t locty, uint8_t 
active) "Locality %d seiz
 tpm_tis_mmio_write_init_abort(void) "Initiating abort"
 tpm_tis_mmio_write_lowering_irq(void) "Lowering IRQ"
 tpm_tis_mmio_write_data2send(uint32_t value, unsigned size) "Data to send to 
TPM: 0x%08x (size=%d)"
+tpm_tis_pre_save(uint8_t locty, uint32_t rw_offset) "locty: %d, rw_offset = %u"
-- 
2.5.5




[Qemu-devel] [PATCH v5.1 for 2.13 0/4] tpm: Extend TPM with state migration support

2018-03-16 Thread Stefan Berger
This series of patches implements support for migrating the state of the
external 'swtpm' TPM emulator as well as that of the TIS interface. 

For testing of TPM 2 (migration) please use the following git repos and
branches:

libtpms: 
   - repo: https://github.com/stefanberger/libtpms
   - branch: tpm2-preview.rev146.v2

swtpm:
   - repo: https://github.com/stefanberger/swtpm
   - branch: tpm2-preview.rev146.v2

Regards,
  Stefan

Changes:
 v4->v5:
   - followed Marc-André's and Alan's comments where possible; some comments
 were not addressed and reasons posted to mailing list
   - converted debug statements to tracing
   - qemu_chr_fe_read_all does not return errno, so displaying expected versus
 received number of bytes rather than strerror(errno)
   - added test cases
   - added documentation for migration to docs/spec/tpm.txt

 v3->v4:
   - dropped the size limit enforcement on blobs received from the swtpm
   - the .post_load migration function requires errno's to be returned.
 -> some of the functions have been converted to return a better errno



Stefan Berger (4):
  tpm: extend TPM emulator with state migration support
  tpm: extend TPM TIS with state migration support
  docs: tpm: add VM save/restore example and troubleshooting guide
  tpm: Add test cases that uses the external swtpm with CRB interface

 docs/specs/tpm.txt | 106 +++
 hw/tpm/tpm_emulator.c  | 318 +++--
 hw/tpm/tpm_tis.c   |  52 +++-
 hw/tpm/trace-events|   9 +-
 tests/Makefile.include |   3 +
 tests/tpm-crb-swtpm-test.c | 244 ++
 tests/tpm-util.c   | 135 +++
 tests/tpm-util.h   |  36 +
 8 files changed, 889 insertions(+), 14 deletions(-)
 create mode 100644 tests/tpm-crb-swtpm-test.c
 create mode 100644 tests/tpm-util.c
 create mode 100644 tests/tpm-util.h

-- 
2.5.5




[Qemu-devel] [PATCH for-2.13] i386: Helpers to encode cache information consistently

2018-03-16 Thread Eduardo Habkost
Instead of having a collection of macros that need to be used in
complex expressions to build CPUID data, define a CPUCacheInfo
struct that can hold information about a given cache.  Helper
functions will take a CPUCacheInfo struct as input to encode
CPUID leaves for a cache.

This will help us ensure consistency between cache information
CPUID leaves, and make the existing inconsistencies in CPUID info
more visible.

Signed-off-by: Eduardo Habkost 
---
 target/i386/cpu.c | 525 ++
 1 file changed, 410 insertions(+), 115 deletions(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 6bb4ce8719..1c0571cac5 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -57,16 +57,226 @@
 #include "disas/capstone.h"
 
 
-/* Cache topology CPUID constants: */
+/* Cache information data structures: */
 
-/* CPUID Leaf 2 Descriptors */
+enum CacheType {
+DCACHE,
+ICACHE,
+UNIFIED_CACHE
+};
 
-#define CPUID_2_L1D_32KB_8WAY_64B 0x2c
-#define CPUID_2_L1I_32KB_8WAY_64B 0x30
-#define CPUID_2_L2_2MB_8WAY_64B   0x7d
-#define CPUID_2_L3_16MB_16WAY_64B 0x4d
+struct CPUCacheInfo {
+enum CacheType type;
+uint8_t level;
+/* Size in bytes */
+uint32_t size;
+/* Line size, in bytes */
+uint16_t line_size;
+/*
+ * Associativity.
+ * Note: representation of fully-associative caches is not implemented
+ */
+uint8_t associativity;
+/* Physical line partitions. CPUID[0x801D].EBX, CPUID[4].EBX */
+uint8_t partitions;
+/* Number of sets. CPUID[0x801D].ECX, CPUID[4].ECX */
+uint32_t sets;
+/*
+ * Lines per tag.
+ * AMD-specific: CPUID[0x8005], CPUID[0x8006].
+ * (Is this synonym to @partitions?)
+ */
+uint8_t lines_per_tag;
+
+/* Self-initializing cache */
+bool self_init;
+/*
+ * WBINVD/INVD is not guaranteed to act upon lower level caches of
+ * non-originating threads sharing this cache.
+ * CPUID[4].EDX[bit 0], CPUID[0x801D].EDX[bit 0]
+ */
+bool no_invd_sharing;
+/*
+ * Cache is inclusive of lower cache levels.
+ * CPUID[4].EDX[bit 1], CPUID[0x801D].EDX[bit 1].
+ */
+bool inclusive;
+/*
+ * A complex function is used to index the cache, potentially using all
+ * address bits.  CPUID[4].EDX[bit 2].
+ */
+bool complex_indexing;
+};
 
 
+/* Helpers for building CPUID[2] descriptors: */
+
+struct CPUID2CacheDescriptorInfo {
+enum CacheType type;
+int level;
+int size;
+int line_size;
+int associativity;
+};
+
+#define KiB 1024
+#define MiB (1024 * 1024)
+
+/*
+ * Known CPUID 2 cache descriptors.
+ * From Intel SDM Volume 2A, CPUID instruction
+ */
+struct CPUID2CacheDescriptorInfo cpuid2_cache_descriptors[] = {
+[0x06] = { .level = 1, .type = ICACHE,.size =   8 * KiB,
+   .associativity = 4,  .line_size = 32, },
+[0x08] = { .level = 1, .type = ICACHE,.size =  16 * KiB,
+   .associativity = 4,  .line_size = 32, },
+[0x09] = { .level = 1, .type = ICACHE,.size =  32 * KiB,
+   .associativity = 4,  .line_size = 64, },
+[0x0A] = { .level = 1, .type = DCACHE,.size =   8 * KiB,
+   .associativity = 2,  .line_size = 32, },
+[0x0C] = { .level = 1, .type = DCACHE,.size =  16 * KiB,
+   .associativity = 4,  .line_size = 32, },
+[0x0D] = { .level = 1, .type = DCACHE,.size =  16 * KiB,
+   .associativity = 4,  .line_size = 64, },
+[0x0E] = { .level = 1, .type = DCACHE,.size =  24 * KiB,
+   .associativity = 6,  .line_size = 64, },
+[0x1D] = { .level = 2, .type = UNIFIED_CACHE, .size = 128 * KiB,
+   .associativity = 2,  .line_size = 64, },
+[0x21] = { .level = 2, .type = UNIFIED_CACHE, .size = 256 * KiB,
+   .associativity = 8,  .line_size = 64, },
+/* lines per sector is not supported cpuid2_cache_descriptor(),
+* so descriptors 0x22, 0x23 are not included
+*/
+[0x24] = { .level = 2, .type = UNIFIED_CACHE, .size =   1 * MiB,
+   .associativity = 16, .line_size = 64, },
+/* lines per sector is not supported cpuid2_cache_descriptor(),
+* so descriptors 0x25, 0x20 are not included
+*/
+[0x2C] = { .level = 1, .type = DCACHE,.size =  32 * KiB,
+   .associativity = 8,  .line_size = 64, },
+[0x30] = { .level = 1, .type = ICACHE,.size =  32 * KiB,
+   .associativity = 8,  .line_size = 64, },
+[0x41] = { .level = 2, .type = UNIFIED_CACHE, .size = 128 * KiB,
+   .associativity = 4,  .line_size = 32, },
+[0x42] = { .level = 2, .type = UNIFIED_CACHE, .size = 256 * KiB,
+   .associativity = 4,  .line_size = 32, },
+[0x43] = { .level = 2, .type = UNIFIED_CACHE, .size = 512 * KiB,
+   .associativity = 4,  .line_size = 32, },
+[0x44] = { .level 

Re: [Qemu-devel] [PATCH] i386/kvm: add support for KVM_CAP_X86_DISABLE_EXITS

2018-03-16 Thread no-reply
Hi,

This series seems to have some coding style problems. See output below for
more information:

Type: series
Message-id: 1521211002-4529-1-git-send-email-wanpen...@tencent.com
Subject: [Qemu-devel] [PATCH] i386/kvm: add support for 
KVM_CAP_X86_DISABLE_EXITS

=== TEST SCRIPT BEGIN ===
#!/bin/bash

BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0

git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram

commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
failed=1
echo
fi
n=$((n+1))
done

exit $failed
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 * [new tag]   
patchew/1521211002-4529-1-git-send-email-wanpen...@tencent.com -> 
patchew/1521211002-4529-1-git-send-email-wanpen...@tencent.com
 t [tag update]patchew/20180315034507.6341-1-f...@redhat.com -> 
patchew/20180315034507.6341-1-f...@redhat.com
Switched to a new branch 'test'
9ababe35bc i386/kvm: add support for KVM_CAP_X86_DISABLE_EXITS

=== OUTPUT BEGIN ===
Checking PATCH 1/1: i386/kvm: add support for KVM_CAP_X86_DISABLE_EXITS...
WARNING: line over 80 characters
#52: FILE: target/i386/kvm.c:1003:
+int disable_exits = kvm_check_extension(cs->kvm_state, 
KVM_CAP_X86_DISABLE_EXITS);

ERROR: line over 90 characters
#58: FILE: target/i386/kvm.c:1009:
+if (kvm_vm_enable_cap(cs->kvm_state, KVM_CAP_X86_DISABLE_EXITS, 0, 
disable_exits)) {

total: 1 errors, 1 warnings, 36 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

=== OUTPUT END ===

Test command exited with code: 1


---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-de...@freelists.org

Re: [Qemu-devel] [Qemu-block] [PATCH for-2.12 0/2] qcow2: add overlap check for bitmap directory

2018-03-16 Thread John Snow


On 11/30/2017 11:47 AM, Vladimir Sementsov-Ogievskiy wrote:
> Add simple constant overlap check.
> 
> Vladimir Sementsov-Ogievskiy (2):
>   qcow2: add overlap check for bitmap directory
>   qcow2: fix indentation after previous patch
> 
>  block/qcow2.h  | 45 -
>  block/qcow2-refcount.c | 12 
>  block/qcow2.c  | 22 ++
>  3 files changed, 50 insertions(+), 29 deletions(-)
> 

Vladimir, do we need this for 2.12 still?
How about "fix bitmaps migration through shared storage"?



Re: [Qemu-devel] [PATCH v5 for 2.13 0/4] tpm: Extend TPM with state migration support

2018-03-16 Thread no-reply
Hi,

This series failed docker-quick@centos6 build test. Please find the testing 
commands and
their output below. If you have Docker installed, you can probably reproduce it
locally.

Type: series
Message-id: 1521236796-24551-1-git-send-email-stef...@linux.vnet.ibm.com
Subject: [Qemu-devel] [PATCH v5 for 2.13 0/4] tpm: Extend TPM with state 
migration support

=== TEST SCRIPT BEGIN ===
#!/bin/bash
set -e
git submodule update --init dtc
# Let docker tests dump environment info
export SHOW_ENV=1
export J=8
time make docker-test-quick@centos6
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
f39c7d70de tpm: Add test cases that uses the external swtpm with CRB interface
5470ab132a docs: tpm: add VM save/restore example and troubleshooting guide
3b2114b4e6 tpm: extend TPM TIS with state migration support
59c9b53eea tpm: extend TPM emulator with state migration support

=== OUTPUT BEGIN ===
Submodule 'dtc' (git://git.qemu-project.org/dtc.git) registered for path 'dtc'
Cloning into '/var/tmp/patchew-tester-tmp-3rs5i4es/src/dtc'...
Submodule path 'dtc': checked out 'e54388015af1fb4bf04d0bca99caba1074d9cc42'
  BUILD   centos6
make[1]: Entering directory '/var/tmp/patchew-tester-tmp-3rs5i4es/src'
  GEN 
/var/tmp/patchew-tester-tmp-3rs5i4es/src/docker-src.2018-03-16-17.58.14.29948/qemu.tar
Cloning into 
'/var/tmp/patchew-tester-tmp-3rs5i4es/src/docker-src.2018-03-16-17.58.14.29948/qemu.tar.vroot'...
done.
Checking out files:  46% (2780/6030)   
Checking out files:  47% (2835/6030)   
Checking out files:  48% (2895/6030)   
Checking out files:  49% (2955/6030)   
Checking out files:  50% (3015/6030)   
Checking out files:  51% (3076/6030)   
Checking out files:  52% (3136/6030)   
Checking out files:  53% (3196/6030)   
Checking out files:  54% (3257/6030)   
Checking out files:  55% (3317/6030)   
Checking out files:  56% (3377/6030)   
Checking out files:  57% (3438/6030)   
Checking out files:  58% (3498/6030)   
Checking out files:  59% (3558/6030)   
Checking out files:  60% (3618/6030)   
Checking out files:  61% (3679/6030)   
Checking out files:  62% (3739/6030)   
Checking out files:  63% (3799/6030)   
Checking out files:  64% (3860/6030)   
Checking out files:  65% (3920/6030)   
Checking out files:  66% (3980/6030)   
Checking out files:  67% (4041/6030)   
Checking out files:  68% (4101/6030)   
Checking out files:  69% (4161/6030)   
Checking out files:  70% (4221/6030)   
Checking out files:  71% (4282/6030)   
Checking out files:  72% (4342/6030)   
Checking out files:  73% (4402/6030)   
Checking out files:  74% (4463/6030)   
Checking out files:  75% (4523/6030)   
Checking out files:  76% (4583/6030)   
Checking out files:  77% (4644/6030)   
Checking out files:  78% (4704/6030)   
Checking out files:  79% (4764/6030)   
Checking out files:  80% (4824/6030)   
Checking out files:  81% (4885/6030)   
Checking out files:  82% (4945/6030)   
Checking out files:  83% (5005/6030)   
Checking out files:  84% (5066/6030)   
Checking out files:  85% (5126/6030)   
Checking out files:  86% (5186/6030)   
Checking out files:  87% (5247/6030)   
Checking out files:  88% (5307/6030)   
Checking out files:  89% (5367/6030)   
Checking out files:  90% (5427/6030)   
Checking out files:  91% (5488/6030)   
Checking out files:  92% (5548/6030)   
Checking out files:  93% (5608/6030)   
Checking out files:  94% (5669/6030)   
Checking out files:  95% (5729/6030)   
Checking out files:  96% (5789/6030)   
Checking out files:  97% (5850/6030)   
Checking out files:  98% (5910/6030)   
Checking out files:  99% (5970/6030)   
Checking out files: 100% (6030/6030)   
Checking out files: 100% (6030/6030), done.
Your branch is up-to-date with 'origin/test'.
Submodule 'dtc' (git://git.qemu-project.org/dtc.git) registered for path 'dtc'
Cloning into 
'/var/tmp/patchew-tester-tmp-3rs5i4es/src/docker-src.2018-03-16-17.58.14.29948/qemu.tar.vroot/dtc'...
Submodule path 'dtc': checked out 'e54388015af1fb4bf04d0bca99caba1074d9cc42'
Submodule 'ui/keycodemapdb' (git://git.qemu.org/keycodemapdb.git) registered 
for path 'ui/keycodemapdb'
Cloning into 
'/var/tmp/patchew-tester-tmp-3rs5i4es/src/docker-src.2018-03-16-17.58.14.29948/qemu.tar.vroot/ui/keycodemapdb'...
Submodule path 'ui/keycodemapdb': checked out 
'6b3d716e2b6472eb7189d3220552280ef3d832ce'
  COPYRUNNER
RUN test-quick in qemu:centos6 
Packages installed:
SDL-devel-1.2.14-7.el6_7.1.x86_64
bison-2.4.1-5.el6.x86_64
bzip2-devel-1.0.5-7.el6_0.x86_64
ccache-3.1.6-2.el6.x86_64
csnappy-devel-0-6.20150729gitd7bc683.el6.x86_64
flex-2.5.35-9.el6.x86_64
gcc-4.4.7-18.el6.x86_64
gettext-0.17-18.el6.x86_64
git-1.7.1-9.el6_9.x86_64
glib2-devel-2.28.8-9.el6.x86_64
libepoxy-devel-1.2-3.el6.x86_64
libfdt-devel-1.4.0-1.el6.x86_64
librdmacm-devel-1.0.21-0.el6.x86_64
lzo-devel-2.03-3.1.el6_5.1.x86_64
make-3.81-23.el6.x86_64
mesa-libEGL-devel-11.0.7-4.el6.x86_64
mesa-libgbm-devel-11.0.7-4.el6.x86_64
package g++ is not 

[Qemu-devel] [PATCH v5 for 2.13 4/4] tpm: Add test cases that uses the external swtpm with CRB interface

2018-03-16 Thread Stefan Berger
Add a test program for testing the CRB with the external swtpm.

The 1st test case extends a PCR and reads back the value and compares
it against an expected return packet.

The 2nd test case repeats the 1st test case and then migrates the
external swtpm's state along with the VM state to a destination
QEMU and swtpm and checks that the PCR has the expected value now.

Signed-off-by: Stefan Berger 
---
 tests/Makefile.include |   3 +
 tests/tpm-crb-swtpm-test.c | 243 +
 2 files changed, 246 insertions(+)
 create mode 100644 tests/tpm-crb-swtpm-test.c

diff --git a/tests/Makefile.include b/tests/Makefile.include
index 42fd426..bd4f56f 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -297,6 +297,7 @@ check-qtest-i386-$(CONFIG_VHOST_USER_NET_TEST_i386) += 
tests/vhost-user-test$(EX
 ifeq ($(CONFIG_VHOST_USER_NET_TEST_i386),)
 check-qtest-x86_64-$(CONFIG_VHOST_USER_NET_TEST_x86_64) += 
tests/vhost-user-test$(EXESUF)
 endif
+check-qtest-i386-$(CONFIG_TPM) += tests/tpm-crb-swtpm-test$(EXESUF)
 check-qtest-i386-$(CONFIG_TPM) += tests/tpm-crb-test$(EXESUF)
 check-qtest-i386-$(CONFIG_TPM) += tests/tpm-tis-test$(EXESUF)
 check-qtest-i386-$(CONFIG_SLIRP) += tests/test-netfilter$(EXESUF)
@@ -719,6 +720,8 @@ tests/test-util-sockets$(EXESUF): tests/test-util-sockets.o 
\
 tests/test-io-task$(EXESUF): tests/test-io-task.o $(test-io-obj-y)
 tests/test-io-channel-socket$(EXESUF): tests/test-io-channel-socket.o \
 tests/io-channel-helpers.o tests/socket-helpers.o $(test-io-obj-y)
+tests/tpm-crb-swtpm-test$(EXESUF): tests/tpm-crb-swtpm-test.o tests/tpm-emu.o \
+   tests/tpm-util.o $(test-io-obj-y)
 tests/tpm-crb-test$(EXESUF): tests/tpm-crb-test.o tests/tpm-emu.o 
$(test-io-obj-y)
 tests/tpm-tis-test$(EXESUF): tests/tpm-tis-test.o tests/tpm-emu.o 
$(test-io-obj-y)
 tests/test-io-channel-file$(EXESUF): tests/test-io-channel-file.o \
diff --git a/tests/tpm-crb-swtpm-test.c b/tests/tpm-crb-swtpm-test.c
new file mode 100644
index 000..844d52d
--- /dev/null
+++ b/tests/tpm-crb-swtpm-test.c
@@ -0,0 +1,243 @@
+/*
+ * QTest testcase for TPM CRB talking to external swtpm and swtpm migration
+ *
+ * Copyright (c) 2018 IBM Corporation
+ *  with parts borrowed from migration-test.c that is:
+ * Copyright (c) 2016-2018 Red Hat, Inc. and/or its affiliates
+ *
+ * Authors:
+ *   Stefan Berger 
+ *
+ * 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 
+
+#include "hw/acpi/tpm.h"
+#include "io/channel-socket.h"
+#include "libqtest.h"
+#include "tpm-util.h"
+#include "sysemu/tpm.h"
+#include "qapi/qmp/qdict.h"
+
+typedef struct TestState {
+char *src_tpm_path;
+char *dst_tpm_path;
+char *uri;
+} TestState;
+
+bool got_stop;
+
+static void migrate(QTestState *who, const char *uri)
+{
+QDict *rsp;
+gchar *cmd;
+
+cmd = g_strdup_printf("{ 'execute': 'migrate',"
+  "'arguments': { 'uri': '%s' } }",
+  uri);
+rsp = qtest_qmp(who, cmd);
+g_free(cmd);
+g_assert(qdict_haskey(rsp, "return"));
+QDECREF(rsp);
+}
+
+/*
+ * Events can get in the way of responses we are actually waiting for.
+ */
+static QDict *wait_command(QTestState *who, const char *command)
+{
+const char *event_string;
+QDict *response;
+
+response = qtest_qmp(who, command);
+
+while (qdict_haskey(response, "event")) {
+/* OK, it was an event */
+event_string = qdict_get_str(response, "event");
+if (!strcmp(event_string, "STOP")) {
+got_stop = true;
+}
+QDECREF(response);
+response = qtest_qmp_receive(who);
+}
+return response;
+}
+
+static void wait_for_migration_complete(QTestState *who)
+{
+while (true) {
+QDict *rsp, *rsp_return;
+bool completed;
+const char *status;
+
+rsp = wait_command(who, "{ 'execute': 'query-migrate' }");
+rsp_return = qdict_get_qdict(rsp, "return");
+status = qdict_get_str(rsp_return, "status");
+completed = strcmp(status, "completed") == 0;
+g_assert_cmpstr(status, !=,  "failed");
+QDECREF(rsp);
+if (completed) {
+return;
+}
+usleep(1000);
+}
+}
+
+static void migration_start_qemu(QTestState **src_qemu, QTestState **dst_qemu,
+ SocketAddress *src_tpm_addr,
+ SocketAddress *dst_tpm_addr,
+ const char *miguri)
+{
+char *src_qemu_args, *dst_qemu_args;
+
+src_qemu_args = g_strdup_printf(
+"-chardev socket,id=chr,path=%s "
+"-tpmdev emulator,id=dev,chardev=chr "
+"-device tpm-crb,tpmdev=dev ",
+src_tpm_addr->u.q_unix.path);
+
+*src_qemu = qtest_init(src_qemu_args);
+
+

[Qemu-devel] [PATCH v5 for 2.13 3/4] docs: tpm: add VM save/restore example and troubleshooting guide

2018-03-16 Thread Stefan Berger
Extend the docs related to TPM with specs related to VM save and
restore and a troubleshooting guide for TPM migration.

Signed-off-by: Stefan Berger 
---
 docs/specs/tpm.txt | 106 +
 1 file changed, 106 insertions(+)

diff --git a/docs/specs/tpm.txt b/docs/specs/tpm.txt
index d1d7157..c230c4c 100644
--- a/docs/specs/tpm.txt
+++ b/docs/specs/tpm.txt
@@ -200,3 +200,109 @@ crw---. 1 root root 10, 224 Jul 11 10:11 /dev/tpm0
 PCR-00: 35 4E 3B CE 23 9F 38 59 ...
 ...
 PCR-23: 00 00 00 00 00 00 00 00 ...
+
+
+=== Migration with the TPM emulator ===
+
+The TPM emulator supports the following types of virtual machine migration:
+
+- VM save / restore (migration into a file)
+- Network migration
+- Snapshotting (migration into storage like QoW2 or QED)
+
+The following command sequences can be used to test VM save / restore.
+
+
+In a 1st terminal start an instance of a swtpm using the following command:
+
+mkdir /tmp/mytpm1
+swtpm socket --tpmstate dir=/tmp/mytpm1 \
+  --ctrl type=unixio,path=/tmp/mytpm1/swtpm-sock \
+  --log level=20 --tpm2
+
+In a 2nd terminal start the VM:
+
+qemu-system-x86_64 -display sdl -enable-kvm \
+  -m 1024 -boot d -bios bios-256k.bin -boot menu=on \
+  -chardev socket,id=chrtpm,path=/tmp/mytpm1/swtpm-sock \
+  -tpmdev emulator,id=tpm0,chardev=chrtpm \
+  -device tpm-tis,tpmdev=tpm0 \
+  -monitor stdio \
+  test.img
+
+Verify that the attached TPM is working as expected using applications inside
+the VM.
+
+To store the state of the VM use the following command in the QEMU monitor in
+the 2nd terminal:
+
+(qemu) migrate "exec:cat > testvm.bin"
+(qemu) quit
+
+At this point a file called 'testvm.bin' should exists and the swtpm and QEMU
+processes should have ended.
+
+To test 'VM restore' you have to start the swtpm with the same parameters
+as before. If previously a TPM 2 [--tpm2] was saved, --tpm2 must now be
+passed again on the command line.
+
+In the 1st terminal restart the swtpm with the same command line as before:
+
+swtpm socket --tpmstate dir=/tmp/mytpm1 \
+  --ctrl type=unixio,path=/tmp/mytpm1/swtpm-sock \
+  --log level=20 --tpm2
+
+In the 2nd terminal restore the state of the VM using the additonal
+'-incoming' option.
+
+qemu-system-x86_64 -display sdl -enable-kvm \
+  -m 1024 -boot d -bios bios-256k.bin -boot menu=on \
+  -chardev socket,id=chrtpm,path=/tmp/mytpm1/swtpm-sock \
+  -tpmdev emulator,id=tpm0,chardev=chrtpm \
+  -device tpm-tis,tpmdev=tpm0 \
+  -incoming "exec:cat < testvm.bin" \
+  test.img
+
+
+Troubleshooting migration:
+
+There are several reasons why migration may fail. In case of problems,
+please ensure that the command lines adhere to the following rules and,
+if possible, that identical versions of QEMU and swtpm are used at all
+times.
+
+VM save and restore:
+ - QEMU command line parameters should be identical apart from the
+   '-incoming' option on VM restore
+ - swtpm command line parameters should be identical
+
+VM migration to 'localhost':
+ - QEMU command line parameters should be identical apart from the
+   '-incoming' option on the destination side
+ - swtpm command line parameters should point to two different
+   directories on the source and destination swtpm (--tpmstate dir=...)
+   (especially if different versions of libtpms were to be used on the
+   same machine).
+
+VM migration across the network:
+ - QEMU command line parameters should be identical apart from the
+   '-incoming' option on the destination side
+ - swtpm command line parameters should be identical
+
+VM Snapshotting:
+ - QEMU command line parameters should be identical
+ - swtpm command line parameters should be identical
+
+
+Besides that, migration failure reasons on the swtpm level may include
+the following:
+
+ - the versions of the swtpm on the source and destination sides are
+   incompatible
+   - downgrading of TPM state may not be supported
+   - the source and destination libtpms were compiled with different
+ compile-time options and the destination side refuses to accept the
+ state
+ - different migration keys are used on the source and destination side
+   and the destination side cannot decrypt the migrated state
+   (swtpm ... --migration-key ... )
-- 
2.5.5




[Qemu-devel] [PATCH v5 for 2.13 2/4] tpm: extend TPM TIS with state migration support

2018-03-16 Thread Stefan Berger
Extend the TPM TIS interface with state migration support.

We need to synchronize with the backend thread to make sure that a command
being processed by the external TPM emulator has completed and its
response been received.

Signed-off-by: Stefan Berger 
---
 hw/tpm/tpm_tis.c| 52 ++--
 hw/tpm/trace-events |  1 +
 2 files changed, 51 insertions(+), 2 deletions(-)

diff --git a/hw/tpm/tpm_tis.c b/hw/tpm/tpm_tis.c
index 2ac7e74..fec3d73 100644
--- a/hw/tpm/tpm_tis.c
+++ b/hw/tpm/tpm_tis.c
@@ -894,9 +894,57 @@ static void tpm_tis_reset(DeviceState *dev)
 tpm_backend_startup_tpm(s->be_driver, s->be_buffer_size);
 }
 
+/* persistent state handling */
+
+static int tpm_tis_pre_save(void *opaque)
+{
+TPMState *s = opaque;
+uint8_t locty = s->active_locty;
+
+trace_tpm_tis_pre_save(locty, s->rw_offset);
+
+if (DEBUG_TIS) {
+tpm_tis_dump_state(opaque, 0);
+}
+
+/*
+ * Synchronize with backend completion.
+ */
+tpm_backend_finish_sync(s->be_driver);
+
+return 0;
+}
+
+static const VMStateDescription vmstate_locty = {
+.name = "tpm-tis/locty",
+.version_id = 1,
+.fields  = (VMStateField[]) {
+VMSTATE_UINT32(state, TPMLocality),
+VMSTATE_UINT32(inte, TPMLocality),
+VMSTATE_UINT32(ints, TPMLocality),
+VMSTATE_UINT8(access, TPMLocality),
+VMSTATE_UINT32(sts, TPMLocality),
+VMSTATE_UINT32(iface_id, TPMLocality),
+VMSTATE_END_OF_LIST(),
+}
+};
+
 static const VMStateDescription vmstate_tpm_tis = {
-.name = "tpm",
-.unmigratable = 1,
+.name = "tpm-tis",
+.version_id = 1,
+.pre_save  = tpm_tis_pre_save,
+.fields = (VMStateField[]) {
+VMSTATE_BUFFER(buffer, TPMState),
+VMSTATE_UINT16(rw_offset, TPMState),
+VMSTATE_UINT8(active_locty, TPMState),
+VMSTATE_UINT8(aborting_locty, TPMState),
+VMSTATE_UINT8(next_locty, TPMState),
+
+VMSTATE_STRUCT_ARRAY(loc, TPMState, TPM_TIS_NUM_LOCALITIES, 1,
+ vmstate_locty, TPMLocality),
+
+VMSTATE_END_OF_LIST()
+}
 };
 
 static Property tpm_tis_properties[] = {
diff --git a/hw/tpm/trace-events b/hw/tpm/trace-events
index c5bfbf1..25bee0c 100644
--- a/hw/tpm/trace-events
+++ b/hw/tpm/trace-events
@@ -50,3 +50,4 @@ tpm_tis_mmio_write_locty_seized(uint8_t locty, uint8_t 
active) "Locality %d seiz
 tpm_tis_mmio_write_init_abort(void) "Initiating abort"
 tpm_tis_mmio_write_lowering_irq(void) "Lowering IRQ"
 tpm_tis_mmio_write_data2send(uint32_t value, unsigned size) "Data to send to 
TPM: 0x%08x (size=%d)"
+tpm_tis_pre_save(uint8_t locty, uint32_t rw_offset) "locty: %d, rw_offset = %u"
-- 
2.5.5




[Qemu-devel] [PATCH v5 for 2.13 0/4] tpm: Extend TPM with state migration support

2018-03-16 Thread Stefan Berger
This series of patches implements support for migrating the state of the
external 'swtpm' TPM emulator as well as that of the TIS interface. 

For testing of TPM 2 (migration) please use the following git repos and
branches:

libtpms: 
   - repo: https://github.com/stefanberger/libtpms
   - branch: tpm2-preview.rev146.v2

swtpm:
   - repo: https://github.com/stefanberger/swtpm
   - branch: tpm2-preview.rev146.v2

Regards,
  Stefan

Changes:
 v4->v5:
   - followed Marc-André's and Alan's comments where possible; some comments
 were not addressed and reasons posted to mailing list
   - converted debug statements to tracing
   - qemu_chr_fe_read_all does not return errno, so displaying expected versus
 received number of bytes rather than strerror(errno)
   - added test cases
   - added documentation for migration to docs/spec/tpm.txt

 v3->v4:
   - dropped the size limit enforcement on blobs received from the swtpm
   - the .post_load migration function requires errno's to be returned.
 -> some of the functions have been converted to return a better errno


Stefan Berger (4):
  tpm: extend TPM emulator with state migration support
  tpm: extend TPM TIS with state migration support
  docs: tpm: add VM save/restore example and troubleshooting guide
  tpm: Add test cases that uses the external swtpm with CRB interface

 docs/specs/tpm.txt | 106 +++
 hw/tpm/tpm_emulator.c  | 318 +++--
 hw/tpm/tpm_tis.c   |  52 +++-
 hw/tpm/trace-events|   9 +-
 tests/Makefile.include |   3 +
 tests/tpm-crb-swtpm-test.c | 243 ++
 6 files changed, 717 insertions(+), 14 deletions(-)
 create mode 100644 tests/tpm-crb-swtpm-test.c

-- 
2.5.5




[Qemu-devel] [PATCH v5 for 2.13 1/4] tpm: extend TPM emulator with state migration support

2018-03-16 Thread Stefan Berger
Extend the TPM emulator backend device with state migration support.

The external TPM emulator 'swtpm' provides a protocol over
its control channel to retrieve its state blobs. We implement
functions for getting and setting the different state blobs.
In case the setting of the state blobs fails, we return a
negative errno code to fail the start of the VM.

Since we have an external TPM emulator, we need to make sure
that we do not migrate the state for as long as it is busy
processing a request. We need to wait for notification that
the request has completed processing.

Signed-off-by: Stefan Berger 
---
 hw/tpm/tpm_emulator.c | 318 --
 hw/tpm/trace-events   |   8 +-
 2 files changed, 314 insertions(+), 12 deletions(-)

diff --git a/hw/tpm/tpm_emulator.c b/hw/tpm/tpm_emulator.c
index 6418ef0..6d6158d 100644
--- a/hw/tpm/tpm_emulator.c
+++ b/hw/tpm/tpm_emulator.c
@@ -4,7 +4,7 @@
  *  Copyright (c) 2017 Intel Corporation
  *  Author: Amarnath Valluri 
  *
- *  Copyright (c) 2010 - 2013 IBM Corporation
+ *  Copyright (c) 2010 - 2013, 2018 IBM Corporation
  *  Authors:
  *Stefan Berger 
  *
@@ -49,6 +49,19 @@
 #define TPM_EMULATOR_IMPLEMENTS_ALL_CAPS(S, cap) (((S)->caps & (cap)) == (cap))
 
 /* data structures */
+
+/* blobs from the TPM; part of VM state when migrating */
+typedef struct TPMBlobBuffers {
+uint32_t permanent_flags;
+TPMSizedBuffer permanent;
+
+uint32_t volatil_flags;
+TPMSizedBuffer volatil;
+
+uint32_t savestate_flags;
+TPMSizedBuffer savestate;
+} TPMBlobBuffers;
+
 typedef struct TPMEmulator {
 TPMBackend parent;
 
@@ -64,6 +77,8 @@ typedef struct TPMEmulator {
 
 unsigned int established_flag:1;
 unsigned int established_flag_cached:1;
+
+TPMBlobBuffers state_blobs;
 } TPMEmulator;
 
 
@@ -293,7 +308,8 @@ static int tpm_emulator_set_buffer_size(TPMBackend *tb,
 return 0;
 }
 
-static int tpm_emulator_startup_tpm(TPMBackend *tb, size_t buffersize)
+static int tpm_emulator_startup_tpm_resume(TPMBackend *tb, size_t buffersize,
+ bool is_resume)
 {
 TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
 ptm_init init = {
@@ -301,12 +317,17 @@ static int tpm_emulator_startup_tpm(TPMBackend *tb, 
size_t buffersize)
 };
 ptm_res res;
 
+trace_tpm_emulator_startup_tpm_resume(is_resume, buffersize);
+
 if (buffersize != 0 &&
 tpm_emulator_set_buffer_size(tb, buffersize, NULL) < 0) {
 goto err_exit;
 }
 
-trace_tpm_emulator_startup_tpm();
+if (is_resume) {
+init.u.req.init_flags |= cpu_to_be32(PTM_INIT_FLAG_DELETE_VOLATILE);
+}
+
 if (tpm_emulator_ctrlcmd(tpm_emu, CMD_INIT, , sizeof(init),
  sizeof(init)) < 0) {
 error_report("tpm-emulator: could not send INIT: %s",
@@ -325,6 +346,11 @@ err_exit:
 return -1;
 }
 
+static int tpm_emulator_startup_tpm(TPMBackend *tb, size_t buffersize)
+{
+return tpm_emulator_startup_tpm_resume(tb, buffersize, false);
+}
+
 static bool tpm_emulator_get_tpm_established_flag(TPMBackend *tb)
 {
 TPMEmulator *tpm_emu = TPM_EMULATOR(tb);
@@ -423,16 +449,21 @@ static size_t tpm_emulator_get_buffer_size(TPMBackend *tb)
 static int tpm_emulator_block_migration(TPMEmulator *tpm_emu)
 {
 Error *err = NULL;
+ptm_cap caps = PTM_CAP_GET_STATEBLOB | PTM_CAP_SET_STATEBLOB |
+   PTM_CAP_STOP;
 
-error_setg(_emu->migration_blocker,
-   "Migration disabled: TPM emulator not yet migratable");
-migrate_add_blocker(tpm_emu->migration_blocker, );
-if (err) {
-error_report_err(err);
-error_free(tpm_emu->migration_blocker);
-tpm_emu->migration_blocker = NULL;
+if (!TPM_EMULATOR_IMPLEMENTS_ALL_CAPS(tpm_emu, caps)) {
+error_setg(_emu->migration_blocker,
+   "Migration disabled: TPM emulator does not support "
+   "migration");
+migrate_add_blocker(tpm_emu->migration_blocker, );
+if (err) {
+error_report_err(err);
+error_free(tpm_emu->migration_blocker);
+tpm_emu->migration_blocker = NULL;
 
-return -1;
+return -1;
+}
 }
 
 return 0;
@@ -570,6 +601,267 @@ static const QemuOptDesc tpm_emulator_cmdline_opts[] = {
 { /* end of list */ },
 };
 
+/*
+ * Transfer a TPM state blob from the TPM into a provided buffer.
+ *
+ * @tpm_emu: TPMEmulator
+ * @type: the type of blob to transfer
+ * @tsb: the TPMSizeBuffer to fill with the blob
+ * @flags: the flags to return to the caller
+ */
+static int tpm_emulator_get_state_blob(TPMEmulator *tpm_emu,
+   uint8_t type,
+   TPMSizedBuffer *tsb,
+   uint32_t *flags)
+{
+ptm_getstate pgs;
+ptm_res res;
+ssize_t n;
+uint32_t 

Re: [Qemu-devel] [PATCH v3 00/22] More fully implement ARM PMUv3

2018-03-16 Thread no-reply
Hi,

This series seems to have some coding style problems. See output below for
more information:

Type: series
Message-id: 1521232280-13089-1-git-send-email-alind...@codeaurora.org
Subject: [Qemu-devel] [PATCH v3 00/22] More fully implement ARM PMUv3

=== TEST SCRIPT BEGIN ===
#!/bin/bash

BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0

git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram

commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
failed=1
echo
fi
n=$((n+1))
done

exit $failed
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 * [new tag]   
patchew/1521232280-13089-1-git-send-email-alind...@codeaurora.org -> 
patchew/1521232280-13089-1-git-send-email-alind...@codeaurora.org
Switched to a new branch 'test'
d81791b184 target/arm: Implement PMSWINC
512124d018 target/arm: PMU: Set PMCR.N to 4
b748e97306 target/arm: PMU: Add instruction and cycle events
7e46a77f89 target/arm: Finish implementation of PM[X]EVCNTR and PM[X]EVTYPER
82cffef855 target/arm: Add array for supported PMU events, generate PMCEID[01]
d635021d0a target/arm: Split arm_ccnt_enabled into generic pmu_counter_enabled
3e1b438deb target/arm: Implement PMOVSSET
c13c832988 target/arm: Add ARM_FEATURE_V7VE for v7 Virtualization Extensions
9c80af4d82 target/arm: Make PMOVSCLR 64 bits wide
8ffbcd3dd8 target/arm: Allow AArch32 access for PMCCFILTR
7dc4ec9715 target/arm: Filter cycle counter based on PMCCFILTR_EL0
f1e40f9fff target/arm: Fix bitmask for PMCCFILTR writes
eb142b42b4 target/arm: Allow EL change hooks to do IO
d37186abdd target/arm: Add pre-EL change hooks
ae12e161da target/arm: Support multiple EL change hooks
9bfa99805d target/arm: Fetch GICv3 state directly from CPUARMState
881bee5e96 target/arm: Mask PMU register writes based on PMCR_EL0.N
890ad6472b target/arm: Reorganize PMCCNTR read, write, sync
922eec023b target/arm: Treat PMCCNTR as alias of PMCCNTR_EL0
5b1ce33c0b target/arm: Check PMCNTEN for whether PMCCNTR is enabled
2ecb09ae04 target/arm: A15 PMCEID0 initialization style nit
0f26a1568a target/arm: A53: Initialize PMCEID[01]

=== OUTPUT BEGIN ===
Checking PATCH 1/22: target/arm: A53: Initialize PMCEID[01]...
Checking PATCH 2/22: target/arm: A15 PMCEID0 initialization style nit...
Checking PATCH 3/22: target/arm: Check PMCNTEN for whether PMCCNTR is enabled...
Checking PATCH 4/22: target/arm: Treat PMCCNTR as alias of PMCCNTR_EL0...
Checking PATCH 5/22: target/arm: Reorganize PMCCNTR read, write, sync...
Checking PATCH 6/22: target/arm: Mask PMU register writes based on PMCR_EL0.N...
Checking PATCH 7/22: target/arm: Fetch GICv3 state directly from CPUARMState...
Checking PATCH 8/22: target/arm: Support multiple EL change hooks...
ERROR: space prohibited between function name and open parenthesis '('
#26: FILE: target/arm/cpu.c:62:
+entry = g_malloc0(sizeof (*entry));

total: 1 errors, 0 warnings, 87 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 9/22: target/arm: Add pre-EL change hooks...
ERROR: space prohibited between function name and open parenthesis '('
#26: FILE: target/arm/cpu.c:62:
+entry = g_malloc0(sizeof (*entry));

total: 1 errors, 0 warnings, 110 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 10/22: target/arm: Allow EL change hooks to do IO...
Checking PATCH 11/22: target/arm: Fix bitmask for PMCCFILTR writes...
Checking PATCH 12/22: target/arm: Filter cycle counter based on PMCCFILTR_EL0...
Checking PATCH 13/22: target/arm: Allow AArch32 access for PMCCFILTR...
Checking PATCH 14/22: target/arm: Make PMOVSCLR 64 bits wide...
Checking PATCH 15/22: target/arm: Add ARM_FEATURE_V7VE for v7 Virtualization 
Extensions...
Checking PATCH 16/22: target/arm: Implement PMOVSSET...
WARNING: line over 80 characters
#39: FILE: target/arm/helper.c:1417:
+  .access = PL0_RW, .fieldoffset = offsetoflow32(CPUARMState, 
cp15.c9_pmovsr),

total: 0 errors, 1 warnings, 59 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
Checking PATCH 17/22: target/arm: Split arm_ccnt_enabled into generic 
pmu_counter_enabled...
Checking PATCH 18/22: target/arm: Add array for supported PMU events, generate 
PMCEID[01]...
Checking PATCH 19/22: target/arm: Finish implementation of PM[X]EVCNTR and 
PM[X]EVTYPER...
Checking PATCH 20/22: target/arm: PMU: Add instruction and cycle events...

Re: [Qemu-devel] [PATCH v2] RISC-V: Fix riscv_isa_string, use popcount to count bits

2018-03-16 Thread Michael Clark
On Fri, Mar 16, 2018 at 10:03 AM, Michael Clark  wrote:

>
> On Thu, Mar 15, 2018 at 12:27 PM, Peter Maydell 
> wrote:
>
>> On 10 March 2018 at 21:25, Philippe Mathieu-Daudé 
>> wrote:
>> > On 03/09/2018 10:01 PM, Michael Clark wrote:
>> >> Logic bug caused the string size calculation for the RISC-V
>> >> format ISA string to be small. This fix allows slack for rv128.
>> >>
>> >> Cc: Palmer Dabbelt 
>> >> Cc: Peter Maydell 
>> >> Cc: Eric Blake 
>> >> Signed-off-by: Michael Clark 
>> >> ---
>> >>  target/riscv/cpu.c | 2 +-
>> >>  1 file changed, 1 insertion(+), 1 deletion(-)
>> >>
>> >> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
>> >> index 4851890..1456535 100644
>> >> --- a/target/riscv/cpu.c
>> >> +++ b/target/riscv/cpu.c
>> >> @@ -391,7 +391,7 @@ static const TypeInfo riscv_cpu_type_info = {
>> >>  char *riscv_isa_string(RISCVCPU *cpu)
>> >>  {
>> >>  int i;
>> >> -size_t maxlen = 5 + ctz32(cpu->env.misa);
>> >> +size_t maxlen = 8 + ctpop64(cpu->env.misa);
>> >
>> > Can you document the magic 5/8?
>> >
>> > This looks nice, but this seems to me too much optimization to save few
>> > bytes, using sizeof(riscv_exts) is overflow-free.
>> >
>> > Maybe this is enough and self-explanatory:
>> >
>> >const size_t maxlen = sizeof("rv128") + sizeof(riscv_exts);
>> >
>> >>  char *isa_string = g_new0(char, maxlen);
>> >>  snprintf(isa_string, maxlen, "rv%d", TARGET_LONG_BITS);
>> >
>> > Also, if you keep the snprintf() return value, you can (naming it 'n')
>> > simplify (also easier to review):
>> >
>> >>  for (i = 0; i < sizeof(riscv_exts); i++) {
>> >>
>> > if (cpu->env.misa & RV(riscv_exts[i])) {
>> > -   isa_string[strlen(isa_string)] = riscv_exts[i] - 'A' + 'a';
>> > +   isa_string[n++] = tolower(riscv_exts[i]);
>> > }
>> > }
>> >
>> > and simply use g_new() with:
>> >
>> > +   isa_string[n] = '\0';
>> >
>> > return isa_string;
>> > }
>>
>> Hi -- any chance of a respin of this patch that addresses Philippe's
>> review comments so we can fix it before rc0? This is causing
>> my merge-build tests to fail about 50% of the time on OpenBSD
>> at the moment...
>
>
> I'll respin asap.
>
> I was out earlier this week as I was at the RISC-V Hackathon at the
> Embedded Linux Conference in Portland. I also have to go through the review
> backlog for the post merge spec conformance and cleanup series...
>

I've sent out the riscv_isa_string fix patch as well as the RISC-V
Post-merge spec conformance and cleanup series independently. I could
combine them so we have one post-merge PR that contains the riscv_isa_string
string fix, the spec conformance fixes and cleanup. Many of the cleanup
patches have been reviewed by Phil, but the patches that haven't been
reviewed are spec conformance fixes and likely require a reading of the
RISC-V Privileged ISA Specification, which may not happen, unless anyone
with RISC-V knowledge has time. They have sign off.

If I submit a PR it will include the checkpatch fixes that I noticed after
sending the patches. The series has been tested pretty extensively and the
earlier revision is what we have in the riscv.org repo and in SiFive's
freedom-u-sdk. i.e. it is what folk are using. I've been working inside of
QEMU RISC-V quite a lot with this series applied, running the latest Fedora
image with SMP Linux, building QEMU inside of QEMU as I'm working on a TCG
backend for RISC-V that I started this Monday during the RISC-V Hackathon.

FYI: This is the work in progress branch on the TCG backend for RISC-V
(it's not quite complete but the bones are there):

- https://github.com/michaeljclark/riscv-qemu/tree/riscv-tcg-backend


[Qemu-devel] [PATCH v3 20/22] target/arm: PMU: Add instruction and cycle events

2018-03-16 Thread Aaron Lindsay
The instruction event is only enabled when icount is used, cycles are
always supported. Always defining get_cycle_count (but altering its
behavior depending on CONFIG_USER_ONLY) allows us to remove some
CONFIG_USER_ONLY #defines throughout the rest of the code.

Signed-off-by: Aaron Lindsay 
---
 target/arm/helper.c | 99 -
 1 file changed, 52 insertions(+), 47 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index 2fa8308..679897a 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -15,6 +15,7 @@
 #include "arm_ldst.h"
 #include  /* For crc32 */
 #include "exec/semihost.h"
+#include "sysemu/cpus.h"
 #include "sysemu/kvm.h"
 #include "fpu/softfloat.h"
 
@@ -935,8 +936,54 @@ typedef struct pm_event {
 uint64_t (*get_count)(CPUARMState *, uint64_t cycles);
 } pm_event;
 
+/*
+ * Return the underlying cycle count for the PMU cycle counters. If we're in
+ * usermode, simply return 0.
+ */
+static uint64_t get_cycle_count(CPUARMState *env)
+{
+#ifndef CONFIG_USER_ONLY
+return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
+   ARM_CPU_FREQ, NANOSECONDS_PER_SECOND);
+#else
+return 0;
+#endif
+}
+
+static bool event_always_supported(CPUARMState *env)
+{
+return true;
+}
+
+#ifndef CONFIG_USER_ONLY
+static uint64_t cycles_get_count(CPUARMState *env, uint64_t cycles)
+{
+return cycles;
+}
+
+static bool instructions_supported(CPUARMState *env)
+{
+return use_icount == 1 /* Precise instruction counting */;
+}
+
+static uint64_t instructions_get_count(CPUARMState *env, uint64_t cycles)
+{
+return (uint64_t)cpu_get_icount_raw();
+}
+#endif
+
 #define SUPPORTED_EVENT_SENTINEL UINT16_MAX
 static const pm_event pm_events[] = {
+#ifndef CONFIG_USER_ONLY
+{ .number = 0x008, /* INST_RETIRED */
+  .supported = instructions_supported,
+  .get_count = instructions_get_count
+},
+{ .number = 0x011, /* CPU_CYCLES */
+  .supported = event_always_supported,
+  .get_count = cycles_get_count
+},
+#endif
 { .number = SUPPORTED_EVENT_SENTINEL }
 };
 static uint16_t supported_event_map[0x3f];
@@ -1016,8 +1063,6 @@ static CPAccessResult pmreg_access_swinc(CPUARMState *env,
 return pmreg_access(env, ri, isread);
 }
 
-#ifndef CONFIG_USER_ONLY
-
 static CPAccessResult pmreg_access_selr(CPUARMState *env,
 const ARMCPRegInfo *ri,
 bool isread)
@@ -1126,11 +1171,7 @@ static inline bool pmu_counter_filtered(CPUARMState 
*env, uint64_t pmxevtyper)
  */
 uint64_t pmccntr_op_start(CPUARMState *env)
 {
-uint64_t cycles = 0;
-#ifndef CONFIG_USER_ONLY
-cycles = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
-  ARM_CPU_FREQ, NANOSECONDS_PER_SECOND);
-#endif
+uint64_t cycles = get_cycle_count(env);
 
 if (arm_ccnt_enabled(env) &&
   !pmu_counter_filtered(env, env->cp15.pmccfiltr_el0)) {
@@ -1268,26 +1309,6 @@ static void pmccntr_write32(CPUARMState *env, const 
ARMCPRegInfo *ri,
 pmccntr_write(env, ri, deposit64(cur_val, 0, 32, value));
 }
 
-#else /* CONFIG_USER_ONLY */
-
-uint64_t pmccntr_op_start(CPUARMState *env)
-{
-}
-
-void pmccntr_op_finish(CPUARMState *env, uint64_t prev_cycles)
-{
-}
-
-uint64_t pmu_op_start(CPUARMState *env)
-{
-}
-
-void pmu_op_finish(CPUARMState *env, uint64_t prev_cycles)
-{
-}
-
-#endif
-
 static void pmccfiltr_write(CPUARMState *env, const ARMCPRegInfo *ri,
 uint64_t value)
 {
@@ -1346,11 +1367,7 @@ static void pmevtyper_write(CPUARMState *env, const 
ARMCPRegInfo *ri,
 if (counter == 0x1f) {
 pmccfiltr_write(env, ri, value);
 } else if (counter < PMU_NUM_COUNTERS(env)) {
-uint64_t cycles = 0;
-#ifndef CONFIG_USER_ONLY
-cycles = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
-  ARM_CPU_FREQ, NANOSECONDS_PER_SECOND);
-#endif
+uint64_t cycles = get_cycle_count(env);
 pmu_sync_counter(env, counter, cycles);
 env->cp15.c14_pmevtyper[counter] = value & 0xfe0003ff;
 pmu_sync_counter(env, counter, cycles);
@@ -1404,11 +1421,7 @@ static void pmevcntr_write(CPUARMState *env, const 
ARMCPRegInfo *ri,
  uint64_t value, uint8_t counter)
 {
 if (counter < PMU_NUM_COUNTERS(env)) {
-uint64_t cycles = 0;
-#ifndef CONFIG_USER_ONLY
-cycles = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
-  ARM_CPU_FREQ, NANOSECONDS_PER_SECOND);
-#endif
+uint64_t cycles = get_cycle_count(env);
 env->cp15.c14_pmevcntr[counter] = value;
 pmu_sync_counter(env, counter, cycles);
 }
@@ -1420,12 +1433,8 @@ static uint64_t pmevcntr_read(CPUARMState *env, const 
ARMCPRegInfo *ri,
   uint8_t counter)
 {
 if (counter < PMU_NUM_COUNTERS(env)) {
-uint64_t ret;
-uint64_t cycles = 0;

[Qemu-devel] [PATCH v3 15/22] target/arm: Add ARM_FEATURE_V7VE for v7 Virtualization Extensions

2018-03-16 Thread Aaron Lindsay
Signed-off-by: Aaron Lindsay 
---
 target/arm/cpu.c | 3 +++
 target/arm/cpu.h | 1 +
 2 files changed, 4 insertions(+)

diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index b0d032c..e544f1d 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -765,6 +765,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error 
**errp)
 /* Some features automatically imply others: */
 if (arm_feature(env, ARM_FEATURE_V8)) {
 set_feature(env, ARM_FEATURE_V7);
+set_feature(env, ARM_FEATURE_V7VE);
 set_feature(env, ARM_FEATURE_ARM_DIV);
 set_feature(env, ARM_FEATURE_LPAE);
 }
@@ -1481,6 +1482,7 @@ static void cortex_a7_initfn(Object *obj)
 
 cpu->dtb_compatible = "arm,cortex-a7";
 set_feature(>env, ARM_FEATURE_V7);
+set_feature(>env, ARM_FEATURE_V7VE);
 set_feature(>env, ARM_FEATURE_VFP4);
 set_feature(>env, ARM_FEATURE_NEON);
 set_feature(>env, ARM_FEATURE_THUMB2EE);
@@ -1526,6 +1528,7 @@ static void cortex_a15_initfn(Object *obj)
 
 cpu->dtb_compatible = "arm,cortex-a15";
 set_feature(>env, ARM_FEATURE_V7);
+set_feature(>env, ARM_FEATURE_V7VE);
 set_feature(>env, ARM_FEATURE_VFP4);
 set_feature(>env, ARM_FEATURE_NEON);
 set_feature(>env, ARM_FEATURE_THUMB2EE);
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index fb2f983..cc1e2fb 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -1439,6 +1439,7 @@ enum arm_features {
 ARM_FEATURE_OMAPCP, /* OMAP specific CP15 ops handling.  */
 ARM_FEATURE_THUMB2EE,
 ARM_FEATURE_V7MP,/* v7 Multiprocessing Extensions */
+ARM_FEATURE_V7VE,/* v7 with Virtualization Extensions */
 ARM_FEATURE_V4T,
 ARM_FEATURE_V5,
 ARM_FEATURE_STRONGARM,
-- 
Qualcomm Datacenter Technologies as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.




[Qemu-devel] [PATCH v3 12/22] target/arm: Filter cycle counter based on PMCCFILTR_EL0

2018-03-16 Thread Aaron Lindsay
The pmu_counter_filtered and pmu_op_start/finish functions are generic
(as opposed to PMCCNTR-specific) to allow for the implementation of
other events.

Signed-off-by: Aaron Lindsay 
---
 target/arm/cpu.c|  3 ++
 target/arm/cpu.h| 37 +++
 target/arm/helper.c | 87 ++---
 3 files changed, 116 insertions(+), 11 deletions(-)

diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index a2cb21e..b0d032c 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -887,6 +887,9 @@ static void arm_cpu_realizefn(DeviceState *dev, Error 
**errp)
 if (!cpu->has_pmu) {
 unset_feature(env, ARM_FEATURE_PMU);
 cpu->id_aa64dfr0 &= ~0xf00;
+} else {
+arm_register_pre_el_change_hook(cpu, _pre_el_change, 0);
+arm_register_el_change_hook(cpu, _post_el_change, 0);
 }
 
 if (!arm_feature(env, ARM_FEATURE_EL2)) {
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index b0ef727..9c3b5ef 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -458,6 +458,11 @@ typedef struct CPUARMState {
  * was reset. Otherwise it stores the counter value
  */
 uint64_t c15_ccnt;
+/* ccnt_cached_cycles is used to hold the last cycle count when
+ * c15_ccnt holds the guest-visible count instead of the delta during
+ * PMU operations which require this.
+ */
+uint64_t ccnt_cached_cycles;
 uint64_t pmccfiltr_el0; /* Performance Monitor Filter Register */
 uint64_t vpidr_el2; /* Virtualization Processor ID Register */
 uint64_t vmpidr_el2; /* Virtualization Multiprocessor ID Register */
@@ -896,15 +901,35 @@ int cpu_arm_signal_handler(int host_signum, void *pinfo,
void *puc);
 
 /**
- * pmccntr_sync
+ * pmccntr_op_start/finish
  * @env: CPUARMState
  *
- * Synchronises the counter in the PMCCNTR. This must always be called twice,
- * once before any action that might affect the timer and again afterwards.
- * The function is used to swap the state of the register if required.
- * This only happens when not in user mode (!CONFIG_USER_ONLY)
+ * Convert the counter in the PMCCNTR between its delta form (the typical mode
+ * when it's enabled) and the guest-visible value. These two calls must always
+ * surround any action which might affect the counter, and the return value
+ * from pmccntr_op_start must be supplied as the second argument to
+ * pmccntr_op_finish.
+ */
+uint64_t pmccntr_op_start(CPUARMState *env);
+void pmccntr_op_finish(CPUARMState *env, uint64_t prev_cycles);
+
+/**
+ * pmu_op_start/finish
+ * @env: CPUARMState
+ *
+ * Convert all PMU counters between their delta form (the typical mode when
+ * they are enabled) and the guest-visible values. These two calls must
+ * surround any action which might affect the counters, and the return value
+ * from pmu_op_start must be supplied as the second argument to pmu_op_finish.
+ */
+uint64_t pmu_op_start(CPUARMState *env);
+void pmu_op_finish(CPUARMState *env, uint64_t prev_cycles);
+
+/**
+ * Functions to register as EL change hooks for PMU mode filtering
  */
-void pmccntr_sync(CPUARMState *env);
+void pmu_pre_el_change(ARMCPU *cpu, void *ignored);
+void pmu_post_el_change(ARMCPU *cpu, void *ignored);
 
 /* SCTLR bit meanings. Several bits have been reused in newer
  * versions of the architecture; in that case we define constants
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 0102357..95b09d6 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -908,6 +908,15 @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
 #define PMCRC   0x4
 #define PMCRE   0x1
 
+#define PMXEVTYPER_P  0x8000
+#define PMXEVTYPER_U  0x4000
+#define PMXEVTYPER_NSK0x2000
+#define PMXEVTYPER_NSU0x1000
+#define PMXEVTYPER_NSH0x0800
+#define PMXEVTYPER_M  0x0400
+#define PMXEVTYPER_MT 0x0200
+#define PMXEVTYPER_EVTCOUNT   0x03ff
+
 #define PMU_NUM_COUNTERS(env) ((env->cp15.c9_pmcr & PMCRN_MASK) >> PMCRN_SHIFT)
 /* Bits allowed to be set/cleared for PMCNTEN* and PMINTEN* */
 #define PMU_COUNTER_MASK(env) ((1 << 31) | ((1 << PMU_NUM_COUNTERS(env)) - 1))
@@ -998,7 +1007,7 @@ static CPAccessResult pmreg_access_ccntr(CPUARMState *env,
 
 static inline bool arm_ccnt_enabled(CPUARMState *env)
 {
-/* This does not support checking PMCCFILTR_EL0 register */
+/* Does not check PMCCFILTR_EL0, which is handled by pmu_counter_filtered 
*/
 
 if (!(env->cp15.c9_pmcr & PMCRE) || !(env->cp15.c9_pmcnten & (1 << 31))) {
 return false;
@@ -1006,6 +1015,44 @@ static inline bool arm_ccnt_enabled(CPUARMState *env)
 
 return true;
 }
+
+/* Returns true if the counter corresponding to the passed-in pmevtyper or
+ * pmccfiltr value is filtered using the current state */
+static inline bool pmu_counter_filtered(CPUARMState *env, uint64_t pmxevtyper)
+{
+bool secure 

Re: [Qemu-devel] [PATCH v8 19/23] SiFive RISC-V UART Device

2018-03-16 Thread Bastian Koppelmann
On 03/16/2018 07:36 PM, Michael Clark wrote:
> On Fri, Mar 16, 2018 at 11:30 AM, Michael Clark  wrote:
> 
>>
>>
>> On Sun, Mar 11, 2018 at 4:43 AM, Bastian Koppelmann <
>> kbast...@mail.uni-paderborn.de> wrote:
>>
>>> Hi Mark,
>>>
>>> On 03/10/2018 10:40 AM, Mark Cave-Ayland wrote:
 On 10/03/18 03:02, Michael Clark wrote:

> On Sat, Mar 10, 2018 at 1:39 AM, Philippe Mathieu-Daudé <
>>> f4...@amsat.org>
> wrote:
>
>>> [...]
 Another general note: for each of the main QEMU platforms supported
 there is a home page on the official wiki, so do make sure that you set
 yourself a template for RiscV and add some information to help people
 get started.

>>> Thanks for the pointer. I went ahead and created a basic page for RISC-V
>>> with instructions on how to build QEMU and boot Fedora.
>>>
>>
>> Thanks Bastian! I'll add a link back to the official QEMU RISC-V
>> Architecture page from the riscv-qemu repo wiki...
>>
> 
> I noticed there is a spelling mistake in the description: "implented"
> instead of "implemented"

Woops, fixed :).

Cheers,
Bastian



[Qemu-devel] [PATCH v3 11/22] target/arm: Fix bitmask for PMCCFILTR writes

2018-03-16 Thread Aaron Lindsay
It was shifted to the left one bit too few.

Signed-off-by: Aaron Lindsay 
---
 target/arm/helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index 50eaed7..0102357 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -1123,7 +1123,7 @@ static void pmccfiltr_write(CPUARMState *env, const 
ARMCPRegInfo *ri,
 uint64_t value)
 {
 uint64_t saved_cycles = pmccntr_op_start(env);
-env->cp15.pmccfiltr_el0 = value & 0x7E00;
+env->cp15.pmccfiltr_el0 = value & 0xfc00;
 pmccntr_op_finish(env, saved_cycles);
 }
 
-- 
Qualcomm Datacenter Technologies as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.




[Qemu-devel] [PATCH v3 19/22] target/arm: Finish implementation of PM[X]EVCNTR and PM[X]EVTYPER

2018-03-16 Thread Aaron Lindsay
Add arrays to hold the registers, the definitions themselves, access
functions, and add logic to reset counters when PMCR.P is set.

Signed-off-by: Aaron Lindsay 
---
 target/arm/cpu.h|   7 +-
 target/arm/helper.c | 219 
 2 files changed, 207 insertions(+), 19 deletions(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 19f005d..7a74966 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -454,8 +454,9 @@ typedef struct CPUARMState {
 uint64_t oslsr_el1; /* OS Lock Status */
 uint64_t mdcr_el2;
 uint64_t mdcr_el3;
-/* If the counter is enabled, this stores the last time the counter
- * was reset. Otherwise it stores the counter value
+/* If the pmccntr and pmevcntr counters are enabled, they store the
+ * offset the last time the counter was reset. Otherwise they store the
+ * counter value.
  */
 uint64_t c15_ccnt;
 /* ccnt_cached_cycles is used to hold the last cycle count when
@@ -463,6 +464,8 @@ typedef struct CPUARMState {
  * PMU operations which require this.
  */
 uint64_t ccnt_cached_cycles;
+uint64_t c14_pmevcntr[31];
+uint64_t c14_pmevtyper[31];
 uint64_t pmccfiltr_el0; /* Performance Monitor Filter Register */
 uint64_t vpidr_el2; /* Virtualization Processor ID Register */
 uint64_t vmpidr_el2; /* Virtualization Multiprocessor ID Register */
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 6a4f900..2fa8308 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -906,6 +906,7 @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
 #define PMCRN_SHIFT 11
 #define PMCRD   0x8
 #define PMCRC   0x4
+#define PMCRP   0x2
 #define PMCRE   0x1
 
 #define PMXEVTYPER_P  0x8000
@@ -931,7 +932,7 @@ typedef struct pm_event {
 bool (*supported)(CPUARMState *);
 /* Retrieve the current count of the underlying event. The programmed
  * counters hold a difference from the return value from this function */
-uint64_t (*get_count)(CPUARMState *);
+uint64_t (*get_count)(CPUARMState *, uint64_t cycles);
 } pm_event;
 
 #define SUPPORTED_EVENT_SENTINEL UINT16_MAX
@@ -1054,6 +1055,21 @@ static inline bool pmu_counter_enabled(CPUARMState *env, 
uint8_t counter)
 return false;
 }
 
+if (counter != 31) {
+/* If not checking PMCCNTR, ensure the counter is setup to an event we
+ * support */
+uint16_t event = env->cp15.c14_pmevtyper[counter] & 
PMXEVTYPER_EVTCOUNT;
+if (event > 0x3f) {
+return false; /* We only support common architectural and
+ microarchitectural events */
+}
+
+uint16_t event_idx = supported_event_map[event];
+if (event_idx == SUPPORTED_EVENT_SENTINEL) {
+return false;
+}
+}
+
 return true;
 }
 
@@ -1149,14 +1165,37 @@ void pmccntr_op_finish(CPUARMState *env, uint64_t 
prev_cycles)
 }
 }
 
+static void pmu_sync_counter(CPUARMState *env, uint8_t counter, uint64_t 
cycles)
+{
+if (pmu_counter_enabled(env, counter) &&
+!pmu_counter_filtered(env, env->cp15.c14_pmevtyper[counter])) {
+
+uint16_t event = env->cp15.c14_pmevtyper[counter] & 
PMXEVTYPER_EVTCOUNT;
+uint16_t event_idx = supported_event_map[event];
+
+uint64_t count = pm_events[event_idx].get_count(env, cycles);
+env->cp15.c14_pmevcntr[counter] =
+count - env->cp15.c14_pmevcntr[counter];
+}
+}
+
 uint64_t pmu_op_start(CPUARMState *env)
 {
-return pmccntr_op_start(env);
+uint64_t saved_cycles = pmccntr_op_start(env);
+unsigned int i;
+for (i = 0; i < PMU_NUM_COUNTERS(env); i++) {
+pmu_sync_counter(env, i, saved_cycles);
+}
+return saved_cycles;
 }
 
 void pmu_op_finish(CPUARMState *env, uint64_t prev_cycles)
 {
 pmccntr_op_finish(env, prev_cycles);
+unsigned int i;
+for (i = 0; i < PMU_NUM_COUNTERS(env); i++) {
+pmu_sync_counter(env, i, prev_cycles);
+}
 }
 
 void pmu_pre_el_change(ARMCPU *cpu, void *ignored)
@@ -1179,6 +1218,13 @@ static void pmcr_write(CPUARMState *env, const 
ARMCPRegInfo *ri,
 env->cp15.c15_ccnt = 0;
 }
 
+if (value & PMCRP) {
+unsigned int i;
+for (i = 0; i < PMU_NUM_COUNTERS(env); i++) {
+env->cp15.c14_pmevcntr[i] = 0;
+}
+}
+
 /* only the DP, X, D and E bits are writable */
 env->cp15.c9_pmcr &= ~0x39;
 env->cp15.c9_pmcr |= (value & 0x39);
@@ -1294,30 +1340,127 @@ static void pmovsset_write(CPUARMState *env, const 
ARMCPRegInfo *ri,
 env->cp15.c9_pmovsr |= value;
 }
 
-static void pmxevtyper_write(CPUARMState *env, const ARMCPRegInfo *ri,
- uint64_t value)
+static void pmevtyper_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value, const uint8_t 

[Qemu-devel] [PATCH v3 10/22] target/arm: Allow EL change hooks to do IO

2018-03-16 Thread Aaron Lindsay
During code generation, surround CPSR writes and exception returns which
call the EL change hooks with gen_io_start/end. The immediate need is
for the PMU to access the clock and icount during EL change to support
mode filtering.

Signed-off-by: Aaron Lindsay 
---
 target/arm/translate-a64.c | 2 ++
 target/arm/translate.c | 4 
 2 files changed, 6 insertions(+)

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index 31ff047..e1ae676 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -1919,7 +1919,9 @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t 
insn)
 unallocated_encoding(s);
 return;
 }
+gen_io_start();
 gen_helper_exception_return(cpu_env);
+gen_io_end();
 /* Must exit loop to check un-masked IRQs */
 s->base.is_jmp = DISAS_EXIT;
 return;
diff --git a/target/arm/translate.c b/target/arm/translate.c
index ba6ab7d..fd5871e 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -4536,7 +4536,9 @@ static void gen_rfe(DisasContext *s, TCGv_i32 pc, 
TCGv_i32 cpsr)
  * appropriately depending on the new Thumb bit, so it must
  * be called after storing the new PC.
  */
+gen_io_start();
 gen_helper_cpsr_write_eret(cpu_env, cpsr);
+gen_io_end();
 tcg_temp_free_i32(cpsr);
 /* Must exit loop to check un-masked IRQs */
 s->base.is_jmp = DISAS_EXIT;
@@ -9828,7 +9830,9 @@ static void disas_arm_insn(DisasContext *s, unsigned int 
insn)
 if (exc_return) {
 /* Restore CPSR from SPSR.  */
 tmp = load_cpu_field(spsr);
+gen_io_start();
 gen_helper_cpsr_write_eret(cpu_env, tmp);
+gen_io_end();
 tcg_temp_free_i32(tmp);
 /* Must exit loop to check un-masked IRQs */
 s->base.is_jmp = DISAS_EXIT;
-- 
Qualcomm Datacenter Technologies as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.




[Qemu-devel] [PATCH v3 21/22] target/arm: PMU: Set PMCR.N to 4

2018-03-16 Thread Aaron Lindsay
This both advertises that we support four counters and adds them to the
implementation because the PMU_NUM_COUNTERS macro reads this value from
the PMCR.

Signed-off-by: Aaron Lindsay 
---
 target/arm/helper.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index 679897a..06e2e2c 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -1575,7 +1575,7 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
   .access = PL1_W, .type = ARM_CP_NOP },
 /* Performance monitors are implementation defined in v7,
  * but with an ARM recommended set of registers, which we
- * follow (although we don't actually implement any counters)
+ * follow.
  *
  * Performance registers fall into three categories:
  *  (a) always UNDEF in PL0, RW in PL1 (PMINTENSET, PMINTENCLR)
@@ -5192,7 +5192,8 @@ void register_cp_regs_for_features(ARMCPU *cpu)
 .access = PL0_RW, .accessfn = pmreg_access,
 .type = ARM_CP_IO,
 .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcr),
-.resetvalue = cpu->midr & 0xff00,
+/* 4 counters enabled */
+.resetvalue = (cpu->midr & 0xff00) | (0x4 << PMCRN_SHIFT),
 .writefn = pmcr_write, .raw_writefn = raw_write,
 };
 define_one_arm_cp_reg(cpu, );
-- 
Qualcomm Datacenter Technologies as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.




[Qemu-devel] [PATCH v3 22/22] target/arm: Implement PMSWINC

2018-03-16 Thread Aaron Lindsay
Signed-off-by: Aaron Lindsay 
---
 target/arm/helper.c | 44 ++--
 1 file changed, 42 insertions(+), 2 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index 06e2e2c..4f8d11c 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -955,6 +955,15 @@ static bool event_always_supported(CPUARMState *env)
 return true;
 }
 
+static uint64_t swinc_get_count(CPUARMState *env, uint64_t cycles)
+{
+/*
+ * SW_INCR events are written directly to the pmevcntr's by writes to
+ * PMSWINC, so there is no underlying count maintained by the PMU itself
+ */
+return 0;
+}
+
 #ifndef CONFIG_USER_ONLY
 static uint64_t cycles_get_count(CPUARMState *env, uint64_t cycles)
 {
@@ -974,6 +983,10 @@ static uint64_t instructions_get_count(CPUARMState *env, 
uint64_t cycles)
 
 #define SUPPORTED_EVENT_SENTINEL UINT16_MAX
 static const pm_event pm_events[] = {
+{ .number = 0x000, /* SW_INCR */
+  .supported = event_always_supported,
+  .get_count = swinc_get_count
+},
 #ifndef CONFIG_USER_ONLY
 { .number = 0x008, /* INST_RETIRED */
   .supported = instructions_supported,
@@ -1273,6 +1286,29 @@ static void pmcr_write(CPUARMState *env, const 
ARMCPRegInfo *ri,
 pmu_op_finish(env, saved_cycles);
 }
 
+static void pmswinc_write(CPUARMState *env, const ARMCPRegInfo *ri,
+  uint64_t value)
+{
+unsigned int i;
+for (i = 0; i < PMU_NUM_COUNTERS(env); i++) {
+/* Increment a counter's count iff: */
+if ((value & (1 << i)) && /* counter's bit is set */
+/* counter is enabled and not filtered */
+pmu_counter_enabled(env, i) &&
+!pmu_counter_filtered(env, env->cp15.c14_pmevtyper[i]) &&
+/* counter is SW_INCR */
+(env->cp15.c14_pmevtyper[i] & PMXEVTYPER_EVTCOUNT) == 0x0) {
+uint64_t cycles = 0;
+#ifndef CONFIG_USER_ONLY
+cycles = get_cycle_count(env);
+#endif
+pmu_sync_counter(env, i, cycles);
+env->cp15.c14_pmevcntr[i]++;
+pmu_sync_counter(env, i, cycles);
+}
+}
+}
+
 static uint64_t pmccntr_read(CPUARMState *env, const ARMCPRegInfo *ri)
 {
 uint64_t ret;
@@ -1619,9 +1655,13 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
   .fieldoffset = offsetof(CPUARMState, cp15.c9_pmovsr),
   .writefn = pmovsr_write,
   .raw_writefn = raw_write },
-/* Unimplemented so WI. */
 { .name = "PMSWINC", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 4,
-  .access = PL0_W, .accessfn = pmreg_access_swinc, .type = ARM_CP_NOP },
+  .access = PL0_W, .accessfn = pmreg_access_swinc, .type = ARM_CP_NO_RAW,
+  .writefn = pmswinc_write },
+{ .name = "PMSWINC_EL0", .state = ARM_CP_STATE_AA64,
+  .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 4,
+  .access = PL0_W, .accessfn = pmreg_access_swinc, .type = ARM_CP_NO_RAW,
+  .writefn = pmswinc_write },
 { .name = "PMSELR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 5,
   .access = PL0_RW, .type = ARM_CP_ALIAS,
   .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmselr),
-- 
Qualcomm Datacenter Technologies as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.




[Qemu-devel] [PATCH v3 16/22] target/arm: Implement PMOVSSET

2018-03-16 Thread Aaron Lindsay
Adding an array for v7VE+ CP registers was necessary so that PMOVSSET
wasn't defined for all v7 processors.

Signed-off-by: Aaron Lindsay 
---
 target/arm/helper.c | 32 +++-
 1 file changed, 31 insertions(+), 1 deletion(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index d4f06e6..f5e800e 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -1241,9 +1241,17 @@ static void pmcntenclr_write(CPUARMState *env, const 
ARMCPRegInfo *ri,
 static void pmovsr_write(CPUARMState *env, const ARMCPRegInfo *ri,
  uint64_t value)
 {
+value &= PMU_COUNTER_MASK(env);
 env->cp15.c9_pmovsr &= ~value;
 }
 
+static void pmovsset_write(CPUARMState *env, const ARMCPRegInfo *ri,
+ uint64_t value)
+{
+value &= PMU_COUNTER_MASK(env);
+env->cp15.c9_pmovsr |= value;
+}
+
 static void pmxevtyper_write(CPUARMState *env, const ARMCPRegInfo *ri,
  uint64_t value)
 {
@@ -1406,7 +1414,7 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
   .fieldoffset = offsetof(CPUARMState, cp15.c9_pmcnten),
   .writefn = pmcntenclr_write },
 { .name = "PMOVSR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 3,
-  .access = PL0_RW, .fieldoffset = offsetof(CPUARMState, cp15.c9_pmovsr),
+  .access = PL0_RW, .fieldoffset = offsetoflow32(CPUARMState, 
cp15.c9_pmovsr),
   .accessfn = pmreg_access,
   .writefn = pmovsr_write,
   .raw_writefn = raw_write },
@@ -1592,6 +1600,25 @@ static const ARMCPRegInfo v7mp_cp_reginfo[] = {
 REGINFO_SENTINEL
 };
 
+static const ARMCPRegInfo v7ve_cp_reginfo[] = {
+/* Performance monitor registers which are not implemented in v7 before
+ * v7ve:
+ */
+{ .name = "PMOVSSET", .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 3,
+  .access = PL0_RW, .accessfn = pmreg_access,
+  .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmovsr),
+  .writefn = pmovsset_write,
+  .raw_writefn = raw_write },
+{ .name = "PMOVSSET_EL0", .state = ARM_CP_STATE_AA64,
+  .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 14, .opc2 = 3,
+  .access = PL0_RW, .accessfn = pmreg_access,
+  .type = ARM_CP_ALIAS,
+  .fieldoffset = offsetof(CPUARMState, cp15.c9_pmovsr),
+  .writefn = pmovsset_write,
+  .raw_writefn = raw_write },
+REGINFO_SENTINEL
+};
+
 static void teecr_write(CPUARMState *env, const ARMCPRegInfo *ri,
 uint64_t value)
 {
@@ -4943,6 +4970,9 @@ void register_cp_regs_for_features(ARMCPU *cpu)
 !arm_feature(env, ARM_FEATURE_PMSA)) {
 define_arm_cp_regs(cpu, v7mp_cp_reginfo);
 }
+if (arm_feature(env, ARM_FEATURE_V7VE)) {
+define_arm_cp_regs(cpu, v7ve_cp_reginfo);
+}
 if (arm_feature(env, ARM_FEATURE_V7)) {
 /* v7 performance monitor control register: same implementor
  * field as main ID register, and we implement only the cycle
-- 
Qualcomm Datacenter Technologies as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.




[Qemu-devel] [PATCH v3 09/22] target/arm: Add pre-EL change hooks

2018-03-16 Thread Aaron Lindsay
Because the design of the PMU requires that the counter values be
converted between their delta and guest-visible forms for mode
filtering, an additional hook which occurs before the EL is changed is
necessary.

Signed-off-by: Aaron Lindsay 
---
 target/arm/cpu.c   | 13 +
 target/arm/cpu.h   | 12 
 target/arm/helper.c| 14 --
 target/arm/internals.h |  7 +++
 target/arm/op_helper.c |  8 
 5 files changed, 44 insertions(+), 10 deletions(-)

diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 5f782bf..a2cb21e 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -55,6 +55,18 @@ static bool arm_cpu_has_work(CPUState *cs)
  | CPU_INTERRUPT_EXITTB);
 }
 
+void arm_register_pre_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook,
+ void *opaque)
+{
+ARMELChangeHook *entry;
+entry = g_malloc0(sizeof (*entry));
+
+entry->hook = hook;
+entry->opaque = opaque;
+
+QLIST_INSERT_HEAD(>pre_el_change_hooks, entry, node);
+}
+
 void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook,
  void *opaque)
 {
@@ -747,6 +759,7 @@ static void arm_cpu_realizefn(DeviceState *dev, Error 
**errp)
 return;
 }
 
+QLIST_INIT(>pre_el_change_hooks);
 QLIST_INIT(>el_change_hooks);
 
 /* Some features automatically imply others: */
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 3b45d3d..b0ef727 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -832,6 +832,7 @@ struct ARMCPU {
  */
 bool cfgend;
 
+QLIST_HEAD(, ARMELChangeHook) pre_el_change_hooks;
 QLIST_HEAD(, ARMELChangeHook) el_change_hooks;
 
 int32_t node_id; /* NUMA node this CPU belongs to */
@@ -2895,12 +2896,15 @@ static inline AddressSpace *arm_addressspace(CPUState 
*cs, MemTxAttrs attrs)
 #endif
 
 /**
+ * arm_register_pre_el_change_hook:
  * arm_register_el_change_hook:
- * Register a hook function which will be called back whenever this
- * CPU changes exception level or mode. The hook function will be
- * passed a pointer to the ARMCPU and the opaque data pointer passed
- * to this function when the hook was registered.
+ * Register a hook function which will be called back before or after this CPU
+ * changes exception level or mode. The hook function will be passed a pointer
+ * to the ARMCPU and the opaque data pointer passed to this function when the
+ * hook was registered.
  */
+void arm_register_pre_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook,
+ void *opaque);
 void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook,
  void *opaque);
 
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 5d5c738..50eaed7 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -8253,6 +8253,14 @@ void arm_cpu_do_interrupt(CPUState *cs)
 return;
 }
 
+/* Hooks may change global state so BQL should be held, also the
+ * BQL needs to be held for any modification of
+ * cs->interrupt_request.
+ */
+g_assert(qemu_mutex_iothread_locked());
+
+arm_call_pre_el_change_hook(cpu);
+
 assert(!excp_is_internal(cs->exception_index));
 if (arm_el_is_aa64(env, new_el)) {
 arm_cpu_do_interrupt_aarch64(cs);
@@ -8260,12 +8268,6 @@ void arm_cpu_do_interrupt(CPUState *cs)
 arm_cpu_do_interrupt_aarch32(cs);
 }
 
-/* Hooks may change global state so BQL should be held, also the
- * BQL needs to be held for any modification of
- * cs->interrupt_request.
- */
-g_assert(qemu_mutex_iothread_locked());
-
 arm_call_el_change_hook(cpu);
 
 if (!kvm_enabled()) {
diff --git a/target/arm/internals.h b/target/arm/internals.h
index 7df3eda..6ea6766 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -728,6 +728,13 @@ void arm_cpu_do_transaction_failed(CPUState *cs, hwaddr 
physaddr,
MemTxResult response, uintptr_t retaddr);
 
 /* Call any registered EL change hooks */
+static inline void arm_call_pre_el_change_hook(ARMCPU *cpu)
+{
+ARMELChangeHook *hook, *next;
+QLIST_FOREACH_SAFE(hook, >pre_el_change_hooks, node, next) {
+hook->hook(cpu, hook->opaque);
+}
+}
 static inline void arm_call_el_change_hook(ARMCPU *cpu)
 {
 ARMELChangeHook *hook, *next;
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
index 7a88fd2..be417ce 100644
--- a/target/arm/op_helper.c
+++ b/target/arm/op_helper.c
@@ -496,6 +496,10 @@ void HELPER(cpsr_write)(CPUARMState *env, uint32_t val, 
uint32_t mask)
 /* Write the CPSR for a 32-bit exception return */
 void HELPER(cpsr_write_eret)(CPUARMState *env, uint32_t val)
 {
+qemu_mutex_lock_iothread();
+arm_call_pre_el_change_hook(arm_env_get_cpu(env));
+qemu_mutex_unlock_iothread();
+
 cpsr_write(env, val, CPSR_ERET_MASK, CPSRWriteExceptionReturn);
 
 /* 

[Qemu-devel] [PATCH v3 18/22] target/arm: Add array for supported PMU events, generate PMCEID[01]

2018-03-16 Thread Aaron Lindsay
This commit doesn't add any supported events, but provides the framework
for adding them. We store the pm_event structs in a simple array, and
provide the mapping from the event numbers to array indexes in
the supported_event_map array.

Signed-off-by: Aaron Lindsay 
---
 target/arm/cpu.c|  4 
 target/arm/cpu.h| 10 ++
 target/arm/helper.c | 37 +
 3 files changed, 51 insertions(+)

diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index e544f1d..69d6a80 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -889,6 +889,10 @@ static void arm_cpu_realizefn(DeviceState *dev, Error 
**errp)
 unset_feature(env, ARM_FEATURE_PMU);
 cpu->id_aa64dfr0 &= ~0xf00;
 } else {
+uint64_t pmceid = get_pmceid(>env);
+cpu->pmceid0 = pmceid & 0x;
+cpu->pmceid1 = (pmceid >> 32) & 0x;
+
 arm_register_pre_el_change_hook(cpu, _pre_el_change, 0);
 arm_register_el_change_hook(cpu, _post_el_change, 0);
 }
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index cc1e2fb..19f005d 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -931,6 +931,16 @@ void pmu_op_finish(CPUARMState *env, uint64_t prev_cycles);
 void pmu_pre_el_change(ARMCPU *cpu, void *ignored);
 void pmu_post_el_change(ARMCPU *cpu, void *ignored);
 
+/*
+ * get_pmceid
+ * @env: CPUARMState
+ *
+ * Return the PMCEID[01] register values corresponding to the counters which
+ * are supported given the current configuration (0 is low 32, 1 is high 32
+ * bits)
+ */
+uint64_t get_pmceid(CPUARMState *env);
+
 /* SCTLR bit meanings. Several bits have been reused in newer
  * versions of the architecture; in that case we define constants
  * for both old and new bit meanings. Code which tests against those
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 2073d56..6a4f900 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -925,6 +925,43 @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
 /* Bits allowed to be set/cleared for PMCNTEN* and PMINTEN* */
 #define PMU_COUNTER_MASK(env) ((1 << 31) | ((1 << PMU_NUM_COUNTERS(env)) - 1))
 
+typedef struct pm_event {
+uint16_t number; /* PMEVTYPER.evtCount is 10 bits wide */
+/* If the event is supported on this CPU (used to generate PMCEID[01]) */
+bool (*supported)(CPUARMState *);
+/* Retrieve the current count of the underlying event. The programmed
+ * counters hold a difference from the return value from this function */
+uint64_t (*get_count)(CPUARMState *);
+} pm_event;
+
+#define SUPPORTED_EVENT_SENTINEL UINT16_MAX
+static const pm_event pm_events[] = {
+{ .number = SUPPORTED_EVENT_SENTINEL }
+};
+static uint16_t supported_event_map[0x3f];
+
+/*
+ * Called upon initialization to build PMCEID0 (low 32 bits) and PMCEID1 (high
+ * 32). We also use it to build a map of ARM event numbers to indices in
+ * our pm_events array.
+ */
+uint64_t get_pmceid(CPUARMState *env)
+{
+uint64_t pmceid = 0;
+unsigned int i = 0;
+while (pm_events[i].number != SUPPORTED_EVENT_SENTINEL) {
+const pm_event *cnt = _events[i];
+if (cnt->number < 0x3f && cnt->supported(env)) {
+pmceid |= (1 << cnt->number);
+supported_event_map[cnt->number] = i;
+} else {
+supported_event_map[cnt->number] = SUPPORTED_EVENT_SENTINEL;
+}
+i++;
+}
+return pmceid;
+}
+
 static CPAccessResult pmreg_access(CPUARMState *env, const ARMCPRegInfo *ri,
bool isread)
 {
-- 
Qualcomm Datacenter Technologies as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.




[Qemu-devel] [PATCH v3 17/22] target/arm: Split arm_ccnt_enabled into generic pmu_counter_enabled

2018-03-16 Thread Aaron Lindsay
Signed-off-by: Aaron Lindsay 
Reviewed-by: Peter Maydell 
---
 target/arm/helper.c | 11 ---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index f5e800e..2073d56 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -1009,17 +1009,22 @@ static CPAccessResult pmreg_access_ccntr(CPUARMState 
*env,
 return pmreg_access(env, ri, isread);
 }
 
-static inline bool arm_ccnt_enabled(CPUARMState *env)
+static inline bool pmu_counter_enabled(CPUARMState *env, uint8_t counter)
 {
 /* Does not check PMCCFILTR_EL0, which is handled by pmu_counter_filtered 
*/
-
-if (!(env->cp15.c9_pmcr & PMCRE) || !(env->cp15.c9_pmcnten & (1 << 31))) {
+if (!(env->cp15.c9_pmcr & PMCRE) ||
+!(env->cp15.c9_pmcnten & (1 << counter))) {
 return false;
 }
 
 return true;
 }
 
+static inline bool arm_ccnt_enabled(CPUARMState *env)
+{
+return pmu_counter_enabled(env, 31);
+}
+
 /* Returns true if the counter corresponding to the passed-in pmevtyper or
  * pmccfiltr value is filtered using the current state */
 static inline bool pmu_counter_filtered(CPUARMState *env, uint64_t pmxevtyper)
-- 
Qualcomm Datacenter Technologies as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.




Re: [Qemu-devel] [patches] Re: [PATCH v3 00/24] RISC-V Post-merge spec conformance and cleanup

2018-03-16 Thread Michael Clark
On Fri, Mar 16, 2018 at 1:06 PM,  wrote:

> Hi,
>
> This series seems to have some coding style problems. See output below for
> more information:
>
> Type: series
> Message-id: 1521229281-73637-1-git-send-email-...@sifive.com
> Subject: [Qemu-devel] [PATCH v3 00/24] RISC-V Post-merge spec conformance
> and cleanup
>
> === TEST SCRIPT BEGIN ===
> #!/bin/bash
>
> BASE=base
> n=1
> total=$(git log --oneline $BASE.. | wc -l)
> failed=0
>
> git config --local diff.renamelimit 0
> git config --local diff.renames True
> git config --local diff.algorithm histogram
>
> commits="$(git log --format=%H --reverse $BASE..)"
> for c in $commits; do
> echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
> if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback
> -; then
> failed=1
> echo
> fi
> n=$((n+1))
> done
>
> exit $failed
> === TEST SCRIPT END ===
>
> Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
> From https://github.com/patchew-project/qemu
>  * [new tag]   patchew/1521229281-73637-1-
> git-send-email-...@sifive.com -> patchew/1521229281-73637-1-
> git-send-email-...@sifive.com
> Switched to a new branch 'test'
> cf9ad8471c RISC-V: Clear mtval/stval on exceptions without info
> e0eb5ad03f RISC-V: Convert cpu definition towards future model
> cb986bd661 RISC-V: Remove support for adhoc X_COP interrupt
> c1bea999fe RISC-V: No traps on writes to misa, minstret, mcycle
> c45005f71d RISC-V: vectored traps are optional
> 23dccf73aa RISC-V: riscv-qemu port supports sv39 and sv48
> 9beecddea0 RISC-V: Remove braces from satp case statement
> db362a77b9 RISC-V: Hardwire satp to 0 for no-mmu case
> c696060959 RISC-V: Remove EM_RISCV ELF_MACHINE indirection
> e48c09d25a RISC-V: Use memory_region_is_ram in pte update
> eaa01d4e61 RISC-V: Make virt header comment title consistent
> 9435045fd8 RISC-V: Make some header guards more specific
> 23973a84f7 RISC-V: Update E order and I extension order
> 6efbb781e4 RISC-V: Improve page table walker spec compliance
> 924e46b0b8 RISC-V: Hold rcu_read_lock when accessing memory
> eef95b067f RISC-V: Include intruction hex in disassembly
> 3884a14086 RISC-V: Make sure rom has space for fdt
> 49ad774612 RISC-V: Remove unused class definitions
> 4b771876d8 RISC-V: Mark ROM read-only after copying in code
> 646a8d2508 RISC-V: Remove identity_translate from load_elf
> c582b7bbf0 RISC-V: Use ROM base address and size from memmap
> 8a3ef54b0d RISC-V: Make virt board description match spike
> ba0cbace2d RISC-V: Replace hardcoded constants with enum values
> ec0c0eea8c RISC-V: Make virt create_fdt interface consistent
>
> === OUTPUT BEGIN ===
> Checking PATCH 1/24: RISC-V: Make virt create_fdt interface consistent...
> Checking PATCH 2/24: RISC-V: Replace hardcoded constants with enum
> values...
> Checking PATCH 3/24: RISC-V: Make virt board description match spike...
> Checking PATCH 4/24: RISC-V: Use ROM base address and size from memmap...
> Checking PATCH 5/24: RISC-V: Remove identity_translate from load_elf...
> Checking PATCH 6/24: RISC-V: Mark ROM read-only after copying in code...
> Checking PATCH 7/24: RISC-V: Remove unused class definitions...
> Checking PATCH 8/24: RISC-V: Make sure rom has space for fdt...
> Checking PATCH 9/24: RISC-V: Include intruction hex in disassembly...
> Checking PATCH 10/24: RISC-V: Hold rcu_read_lock when accessing memory...
> ERROR: switch and case should be at the same indent
> #50: FILE: target/riscv/helper.c:240:
> +switch (action) {
> +case success: break;
> +case translate_fail: return TRANSLATE_FAIL;
> +case restart_walk: goto restart;
>
> ERROR: trailing statements should be on next line
> #51: FILE: target/riscv/helper.c:241:
> +case success: break;
>
> ERROR: trailing statements should be on next line
> #53: FILE: target/riscv/helper.c:243:
> +case restart_walk: goto restart;
>
> total: 3 errors, 0 warnings, 32 lines checked
>
> Your patch has style problems, please review.  If any of these errors
> are false positives report them to the maintainer, see
> CHECKPATCH in MAINTAINERS.
>
> Checking PATCH 11/24: RISC-V: Improve page table walker spec compliance...
> Checking PATCH 12/24: RISC-V: Update E order and I extension order...
> Checking PATCH 13/24: RISC-V: Make some header guards more specific...
> Checking PATCH 14/24: RISC-V: Make virt header comment title consistent...
> Checking PATCH 15/24: RISC-V: Use memory_region_is_ram in pte update...
> Checking PATCH 16/24: RISC-V: Remove EM_RISCV ELF_MACHINE indirection...
> Checking PATCH 17/24: RISC-V: Hardwire satp to 0 for no-mmu case...
> Checking PATCH 18/24: RISC-V: Remove braces from satp case statement...
> Checking PATCH 19/24: RISC-V: riscv-qemu port supports sv39 and sv48...
> Checking PATCH 20/24: RISC-V: vectored traps are optional...
> ERROR: trailing whitespace
> #27: 

[Qemu-devel] [PATCH v3 06/22] target/arm: Mask PMU register writes based on PMCR_EL0.N

2018-03-16 Thread Aaron Lindsay
This is in preparation for enabling counters other than PMCCNTR

Signed-off-by: Aaron Lindsay 
---
 target/arm/helper.c | 24 +++-
 1 file changed, 15 insertions(+), 9 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index 6480b80..5d5c738 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -52,11 +52,6 @@ typedef struct V8M_SAttributes {
 static void v8m_security_lookup(CPUARMState *env, uint32_t address,
 MMUAccessType access_type, ARMMMUIdx mmu_idx,
 V8M_SAttributes *sattrs);
-
-/* Definitions for the PMCCNTR and PMCR registers */
-#define PMCRD   0x8
-#define PMCRC   0x4
-#define PMCRE   0x1
 #endif
 
 static int vfp_gdb_get_reg(CPUARMState *env, uint8_t *buf, int reg)
@@ -906,6 +901,17 @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
 REGINFO_SENTINEL
 };
 
+/* Definitions for the PMU registers */
+#define PMCRN_MASK  0xf800
+#define PMCRN_SHIFT 11
+#define PMCRD   0x8
+#define PMCRC   0x4
+#define PMCRE   0x1
+
+#define PMU_NUM_COUNTERS(env) ((env->cp15.c9_pmcr & PMCRN_MASK) >> PMCRN_SHIFT)
+/* Bits allowed to be set/cleared for PMCNTEN* and PMINTEN* */
+#define PMU_COUNTER_MASK(env) ((1 << 31) | ((1 << PMU_NUM_COUNTERS(env)) - 1))
+
 static CPAccessResult pmreg_access(CPUARMState *env, const ARMCPRegInfo *ri,
bool isread)
 {
@@ -1124,14 +1130,14 @@ static void pmccfiltr_write(CPUARMState *env, const 
ARMCPRegInfo *ri,
 static void pmcntenset_write(CPUARMState *env, const ARMCPRegInfo *ri,
 uint64_t value)
 {
-value &= (1 << 31);
+value &= PMU_COUNTER_MASK(env);
 env->cp15.c9_pmcnten |= value;
 }
 
 static void pmcntenclr_write(CPUARMState *env, const ARMCPRegInfo *ri,
  uint64_t value)
 {
-value &= (1 << 31);
+value &= PMU_COUNTER_MASK(env);
 env->cp15.c9_pmcnten &= ~value;
 }
 
@@ -1179,14 +1185,14 @@ static void pmintenset_write(CPUARMState *env, const 
ARMCPRegInfo *ri,
  uint64_t value)
 {
 /* We have no event counters so only the C bit can be changed */
-value &= (1 << 31);
+value &= PMU_COUNTER_MASK(env);
 env->cp15.c9_pminten |= value;
 }
 
 static void pmintenclr_write(CPUARMState *env, const ARMCPRegInfo *ri,
  uint64_t value)
 {
-value &= (1 << 31);
+value &= PMU_COUNTER_MASK(env);
 env->cp15.c9_pminten &= ~value;
 }
 
-- 
Qualcomm Datacenter Technologies as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.




[Qemu-devel] [PATCH v3 08/22] target/arm: Support multiple EL change hooks

2018-03-16 Thread Aaron Lindsay
Signed-off-by: Aaron Lindsay 
---
 target/arm/cpu.c   | 15 ++-
 target/arm/cpu.h   | 23 ---
 target/arm/internals.h |  7 ---
 3 files changed, 26 insertions(+), 19 deletions(-)

diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 072cbbf..5f782bf 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -55,13 +55,16 @@ static bool arm_cpu_has_work(CPUState *cs)
  | CPU_INTERRUPT_EXITTB);
 }
 
-void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHook *hook,
+void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook,
  void *opaque)
 {
-/* We currently only support registering a single hook function */
-assert(!cpu->el_change_hook);
-cpu->el_change_hook = hook;
-cpu->el_change_hook_opaque = opaque;
+ARMELChangeHook *entry;
+entry = g_malloc0(sizeof (*entry));
+
+entry->hook = hook;
+entry->opaque = opaque;
+
+QLIST_INSERT_HEAD(>el_change_hooks, entry, node);
 }
 
 static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque)
@@ -744,6 +747,8 @@ static void arm_cpu_realizefn(DeviceState *dev, Error 
**errp)
 return;
 }
 
+QLIST_INIT(>el_change_hooks);
+
 /* Some features automatically imply others: */
 if (arm_feature(env, ARM_FEATURE_V8)) {
 set_feature(env, ARM_FEATURE_V7);
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index f17592b..3b45d3d 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -633,11 +633,17 @@ typedef struct CPUARMState {
 
 /**
  * ARMELChangeHook:
- * type of a function which can be registered via arm_register_el_change_hook()
- * to get callbacks when the CPU changes its exception level or mode.
+ * Support registering functions with ARMELChangeHookFn's signature via
+ * arm_register_el_change_hook() to get callbacks when the CPU changes its
+ * exception level or mode.
  */
-typedef void ARMELChangeHook(ARMCPU *cpu, void *opaque);
-
+typedef void ARMELChangeHookFn(ARMCPU *cpu, void *opaque);
+typedef struct ARMELChangeHook ARMELChangeHook;
+struct ARMELChangeHook {
+ARMELChangeHookFn *hook;
+void *opaque;
+QLIST_ENTRY(ARMELChangeHook) node;
+};
 
 /* These values map onto the return values for
  * QEMU_PSCI_0_2_FN_AFFINITY_INFO */
@@ -826,8 +832,7 @@ struct ARMCPU {
  */
 bool cfgend;
 
-ARMELChangeHook *el_change_hook;
-void *el_change_hook_opaque;
+QLIST_HEAD(, ARMELChangeHook) el_change_hooks;
 
 int32_t node_id; /* NUMA node this CPU belongs to */
 
@@ -2895,12 +2900,8 @@ static inline AddressSpace *arm_addressspace(CPUState 
*cs, MemTxAttrs attrs)
  * CPU changes exception level or mode. The hook function will be
  * passed a pointer to the ARMCPU and the opaque data pointer passed
  * to this function when the hook was registered.
- *
- * Note that we currently only support registering a single hook function,
- * and will assert if this function is called twice.
- * This facility is intended for the use of the GICv3 emulation.
  */
-void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHook *hook,
+void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook,
  void *opaque);
 
 /**
diff --git a/target/arm/internals.h b/target/arm/internals.h
index 47cc224..7df3eda 100644
--- a/target/arm/internals.h
+++ b/target/arm/internals.h
@@ -727,11 +727,12 @@ void arm_cpu_do_transaction_failed(CPUState *cs, hwaddr 
physaddr,
int mmu_idx, MemTxAttrs attrs,
MemTxResult response, uintptr_t retaddr);
 
-/* Call the EL change hook if one has been registered */
+/* Call any registered EL change hooks */
 static inline void arm_call_el_change_hook(ARMCPU *cpu)
 {
-if (cpu->el_change_hook) {
-cpu->el_change_hook(cpu, cpu->el_change_hook_opaque);
+ARMELChangeHook *hook, *next;
+QLIST_FOREACH_SAFE(hook, >el_change_hooks, node, next) {
+hook->hook(cpu, hook->opaque);
 }
 }
 
-- 
Qualcomm Datacenter Technologies as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.




[Qemu-devel] [PATCH v3 07/22] target/arm: Fetch GICv3 state directly from CPUARMState

2018-03-16 Thread Aaron Lindsay
This eliminates the need for fetching it from el_change_hook_opaque, and
allows for supporting multiple el_change_hooks without having to hack
something together to find the registered opaque belonging to GICv3.

Signed-off-by: Aaron Lindsay 
---
 hw/intc/arm_gicv3_cpuif.c | 10 ++
 target/arm/cpu.h  | 10 --
 2 files changed, 2 insertions(+), 18 deletions(-)

diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
index 5cbafaf..801f91b 100644
--- a/hw/intc/arm_gicv3_cpuif.c
+++ b/hw/intc/arm_gicv3_cpuif.c
@@ -29,11 +29,7 @@ void gicv3_set_gicv3state(CPUState *cpu, GICv3CPUState *s)
 
 static GICv3CPUState *icc_cs_from_env(CPUARMState *env)
 {
-/* Given the CPU, find the right GICv3CPUState struct.
- * Since we registered the CPU interface with the EL change hook as
- * the opaque pointer, we can just directly get from the CPU to it.
- */
-return arm_get_el_change_hook_opaque(arm_env_get_cpu(env));
+return env->gicv3state;
 }
 
 static bool gicv3_use_ns_bank(CPUARMState *env)
@@ -2615,9 +2611,7 @@ void gicv3_init_cpuif(GICv3State *s)
  * it might be with code translated by CPU 0 but run by CPU 1, in
  * which case we'd get the wrong value.
  * So instead we define the regs with no ri->opaque info, and
- * get back to the GICv3CPUState from the ARMCPU by reading back
- * the opaque pointer from the el_change_hook, which we're going
- * to need to register anyway.
+ * get back to the GICv3CPUState from the CPUARMState.
  */
 define_arm_cp_regs(cpu, gicv3_cpuif_reginfo);
 if (arm_feature(>env, ARM_FEATURE_EL2)
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 1e7e1f8..f17592b 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -2904,16 +2904,6 @@ void arm_register_el_change_hook(ARMCPU *cpu, 
ARMELChangeHook *hook,
  void *opaque);
 
 /**
- * arm_get_el_change_hook_opaque:
- * Return the opaque data that will be used by the el_change_hook
- * for this CPU.
- */
-static inline void *arm_get_el_change_hook_opaque(ARMCPU *cpu)
-{
-return cpu->el_change_hook_opaque;
-}
-
-/**
  * aa32_vfp_dreg:
  * Return a pointer to the Dn register within env in 32-bit mode.
  */
-- 
Qualcomm Datacenter Technologies as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.




[Qemu-devel] [PATCH v3 13/22] target/arm: Allow AArch32 access for PMCCFILTR

2018-03-16 Thread Aaron Lindsay
Signed-off-by: Aaron Lindsay 
---
 target/arm/helper.c | 27 ++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index 95b09d6..d4f06e6 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -917,6 +917,10 @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
 #define PMXEVTYPER_MT 0x0200
 #define PMXEVTYPER_EVTCOUNT   0x03ff
 
+#define PMCCFILTR 0xf800
+#define PMCCFILTR_M   PMXEVTYPER_M
+#define PMCCFILTR_EL0 (PMCCFILTR | PMCCFILTR_M)
+
 #define PMU_NUM_COUNTERS(env) ((env->cp15.c9_pmcr & PMCRN_MASK) >> PMCRN_SHIFT)
 /* Bits allowed to be set/cleared for PMCNTEN* and PMINTEN* */
 #define PMU_COUNTER_MASK(env) ((1 << 31) | ((1 << PMU_NUM_COUNTERS(env)) - 1))
@@ -1200,10 +1204,26 @@ static void pmccfiltr_write(CPUARMState *env, const 
ARMCPRegInfo *ri,
 uint64_t value)
 {
 uint64_t saved_cycles = pmccntr_op_start(env);
-env->cp15.pmccfiltr_el0 = value & 0xfc00;
+env->cp15.pmccfiltr_el0 = value & PMCCFILTR_EL0;
+pmccntr_op_finish(env, saved_cycles);
+}
+
+static void pmccfiltr_write_a32(CPUARMState *env, const ARMCPRegInfo *ri,
+uint64_t value)
+{
+uint64_t saved_cycles = pmccntr_op_start(env);
+/* M is not accessible from AArch32 */
+env->cp15.pmccfiltr_el0 = (env->cp15.pmccfiltr_el0 & PMCCFILTR_M) |
+(value & PMCCFILTR);
 pmccntr_op_finish(env, saved_cycles);
 }
 
+static uint64_t pmccfiltr_read_a32(CPUARMState *env, const ARMCPRegInfo *ri)
+{
+/* M is not visible in AArch32 */
+return env->cp15.pmccfiltr_el0 & PMCCFILTR;
+}
+
 static void pmcntenset_write(CPUARMState *env, const ARMCPRegInfo *ri,
 uint64_t value)
 {
@@ -1421,6 +1441,11 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
   .type = ARM_CP_IO,
   .readfn = pmccntr_read, .writefn = pmccntr_write, },
 #endif
+{ .name = "PMCCFILTR", .cp = 15, .opc1 = 0, .crn = 14, .crm = 15, .opc2 = 
7,
+  .writefn = pmccfiltr_write_a32, .readfn = pmccfiltr_read_a32,
+  .access = PL0_RW, .accessfn = pmreg_access,
+  .type = ARM_CP_ALIAS | ARM_CP_IO,
+  .resetvalue = 0, },
 { .name = "PMCCFILTR_EL0", .state = ARM_CP_STATE_AA64,
   .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 15, .opc2 = 7,
   .writefn = pmccfiltr_write,
-- 
Qualcomm Datacenter Technologies as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.




[Qemu-devel] [PATCH v3 14/22] target/arm: Make PMOVSCLR 64 bits wide

2018-03-16 Thread Aaron Lindsay
This is a bug fix to ensure 64-bit reads of this register don't read
adjacent data.

Signed-off-by: Aaron Lindsay 
---
 target/arm/cpu.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 9c3b5ef..fb2f983 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -367,7 +367,7 @@ typedef struct CPUARMState {
 uint32_t c9_data;
 uint64_t c9_pmcr; /* performance monitor control register */
 uint64_t c9_pmcnten; /* perf monitor counter enables */
-uint32_t c9_pmovsr; /* perf monitor overflow status */
+uint64_t c9_pmovsr; /* perf monitor overflow status */
 uint32_t c9_pmuserenr; /* perf monitor user enable */
 uint64_t c9_pmselr; /* perf monitor counter selection register */
 uint64_t c9_pminten; /* perf monitor interrupt enables */
-- 
Qualcomm Datacenter Technologies as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.




[Qemu-devel] [PATCH v3 05/22] target/arm: Reorganize PMCCNTR read, write, sync

2018-03-16 Thread Aaron Lindsay
pmccntr_read and pmccntr_write contained duplicate code that was already
being handled by pmccntr_sync. Split pmccntr_sync into pmccntr_op_start
and pmccntr_op_finish, passing the clock value between the two, to avoid
losing time between the two calls.

Signed-off-by: Aaron Lindsay 
---
 target/arm/helper.c | 101 +---
 1 file changed, 56 insertions(+), 45 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index 5634561..6480b80 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -1000,28 +1000,58 @@ static inline bool arm_ccnt_enabled(CPUARMState *env)
 
 return true;
 }
-
-void pmccntr_sync(CPUARMState *env)
+/*
+ * Ensure c15_ccnt is the guest-visible count so that operations such as
+ * enabling/disabling the counter or filtering, modifying the count itself,
+ * etc. can be done logically. This is essentially a no-op if the counter is
+ * not enabled at the time of the call.
+ *
+ * The current cycle count is returned so that it can be passed into the paired
+ * pmccntr_op_finish() call which must follow each call to pmccntr_op_start().
+ */
+uint64_t pmccntr_op_start(CPUARMState *env)
 {
-uint64_t temp_ticks;
-
-temp_ticks = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
+uint64_t cycles = 0;
+#ifndef CONFIG_USER_ONLY
+cycles = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
   ARM_CPU_FREQ, NANOSECONDS_PER_SECOND);
+#endif
+
+if (arm_ccnt_enabled(env)) {
 
-if (env->cp15.c9_pmcr & PMCRD) {
-/* Increment once every 64 processor clock cycles */
-temp_ticks /= 64;
+uint64_t eff_cycles = cycles;
+if (env->cp15.c9_pmcr & PMCRD) {
+/* Increment once every 64 processor clock cycles */
+eff_cycles /= 64;
+}
+
+env->cp15.c15_ccnt = eff_cycles - env->cp15.c15_ccnt;
 }
+return cycles;
+}
 
+/*
+ * If enabled, convert c15_ccnt back into the delta between the clock and the
+ * guest-visible count. A call to pmccntr_op_finish should follow every call to
+ * pmccntr_op_start.
+ */
+void pmccntr_op_finish(CPUARMState *env, uint64_t prev_cycles)
+{
 if (arm_ccnt_enabled(env)) {
-env->cp15.c15_ccnt = temp_ticks - env->cp15.c15_ccnt;
+
+if (env->cp15.c9_pmcr & PMCRD) {
+/* Increment once every 64 processor clock cycles */
+prev_cycles /= 64;
+}
+
+env->cp15.c15_ccnt = prev_cycles - env->cp15.c15_ccnt;
 }
 }
 
 static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
uint64_t value)
 {
-pmccntr_sync(env);
+uint64_t saved_cycles = pmccntr_op_start(env);
 
 if (value & PMCRC) {
 /* The counter has been reset */
@@ -1032,26 +1062,16 @@ static void pmcr_write(CPUARMState *env, const 
ARMCPRegInfo *ri,
 env->cp15.c9_pmcr &= ~0x39;
 env->cp15.c9_pmcr |= (value & 0x39);
 
-pmccntr_sync(env);
+pmccntr_op_finish(env, saved_cycles);
 }
 
 static uint64_t pmccntr_read(CPUARMState *env, const ARMCPRegInfo *ri)
 {
-uint64_t total_ticks;
-
-if (!arm_ccnt_enabled(env)) {
-/* Counter is disabled, do not change value */
-return env->cp15.c15_ccnt;
-}
-
-total_ticks = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
-   ARM_CPU_FREQ, NANOSECONDS_PER_SECOND);
-
-if (env->cp15.c9_pmcr & PMCRD) {
-/* Increment once every 64 processor clock cycles */
-total_ticks /= 64;
-}
-return total_ticks - env->cp15.c15_ccnt;
+uint64_t ret;
+uint64_t saved_cycles = pmccntr_op_start(env);
+ret = env->cp15.c15_ccnt;
+pmccntr_op_finish(env, saved_cycles);
+return ret;
 }
 
 static void pmselr_write(CPUARMState *env, const ARMCPRegInfo *ri,
@@ -1068,22 +1088,9 @@ static void pmselr_write(CPUARMState *env, const 
ARMCPRegInfo *ri,
 static void pmccntr_write(CPUARMState *env, const ARMCPRegInfo *ri,
 uint64_t value)
 {
-uint64_t total_ticks;
-
-if (!arm_ccnt_enabled(env)) {
-/* Counter is disabled, set the absolute value */
-env->cp15.c15_ccnt = value;
-return;
-}
-
-total_ticks = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
-   ARM_CPU_FREQ, NANOSECONDS_PER_SECOND);
-
-if (env->cp15.c9_pmcr & PMCRD) {
-/* Increment once every 64 processor clock cycles */
-total_ticks /= 64;
-}
-env->cp15.c15_ccnt = total_ticks - value;
+uint64_t saved_cycles = pmccntr_op_start(env);
+env->cp15.c15_ccnt = value;
+pmccntr_op_finish(env, saved_cycles);
 }
 
 static void pmccntr_write32(CPUARMState *env, const ARMCPRegInfo *ri,
@@ -1096,7 +1103,11 @@ static void pmccntr_write32(CPUARMState *env, const 
ARMCPRegInfo *ri,
 
 #else /* CONFIG_USER_ONLY */
 
-void pmccntr_sync(CPUARMState *env)
+uint64_t pmccntr_op_start(CPUARMState *env)
+{
+}
+
+void pmccntr_op_finish(CPUARMState *env, 

[Qemu-devel] [PATCH v3 04/22] target/arm: Treat PMCCNTR as alias of PMCCNTR_EL0

2018-03-16 Thread Aaron Lindsay
They share the same underlying state

Signed-off-by: Aaron Lindsay 
---
 target/arm/helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index 5e48982..5634561 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -1318,7 +1318,7 @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
   .fieldoffset = offsetof(CPUARMState, cp15.c9_pmselr),
   .writefn = pmselr_write, .raw_writefn = raw_write, },
 { .name = "PMCCNTR", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 0,
-  .access = PL0_RW, .resetvalue = 0, .type = ARM_CP_IO,
+  .access = PL0_RW, .resetvalue = 0, .type = ARM_CP_ALIAS | ARM_CP_IO,
   .readfn = pmccntr_read, .writefn = pmccntr_write32,
   .accessfn = pmreg_access_ccntr },
 { .name = "PMCCNTR_EL0", .state = ARM_CP_STATE_AA64,
-- 
Qualcomm Datacenter Technologies as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.




[Qemu-devel] [PATCH v3 02/22] target/arm: A15 PMCEID0 initialization style nit

2018-03-16 Thread Aaron Lindsay
Signed-off-by: Aaron Lindsay 
---
 target/arm/cpu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 022d8c5..072cbbf 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1524,7 +1524,7 @@ static void cortex_a15_initfn(Object *obj)
 cpu->id_pfr0 = 0x1131;
 cpu->id_pfr1 = 0x00011011;
 cpu->id_dfr0 = 0x02010555;
-cpu->pmceid0 = 0x000;
+cpu->pmceid0 = 0x;
 cpu->pmceid1 = 0x;
 cpu->id_afr0 = 0x;
 cpu->id_mmfr0 = 0x10201105;
-- 
Qualcomm Datacenter Technologies as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.




[Qemu-devel] [PATCH v3 01/22] target/arm: A53: Initialize PMCEID[01]

2018-03-16 Thread Aaron Lindsay
A53 advertises ARM_FEATURE_PMU, but wasn't initializing pmceid[01].
pmceid[01] are already being initialized to zero for both A15 and A57.

Signed-off-by: Aaron Lindsay 
---
 target/arm/cpu64.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 991d764..8c4db31 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -201,6 +201,8 @@ static void aarch64_a53_initfn(Object *obj)
 cpu->id_isar5 = 0x00011121;
 cpu->id_aa64pfr0 = 0x;
 cpu->id_aa64dfr0 = 0x10305106;
+cpu->pmceid0 = 0x;
+cpu->pmceid1 = 0x;
 cpu->id_aa64isar0 = 0x00011120;
 cpu->id_aa64mmfr0 = 0x1122; /* 40 bit physical addr */
 cpu->dbgdidr = 0x3516d000;
-- 
Qualcomm Datacenter Technologies as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.




[Qemu-devel] [PATCH v3 03/22] target/arm: Check PMCNTEN for whether PMCCNTR is enabled

2018-03-16 Thread Aaron Lindsay
Signed-off-by: Aaron Lindsay 
Reviewed-by: Peter Maydell 
---
 target/arm/helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index 09893e3..5e48982 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -994,7 +994,7 @@ static inline bool arm_ccnt_enabled(CPUARMState *env)
 {
 /* This does not support checking PMCCFILTR_EL0 register */
 
-if (!(env->cp15.c9_pmcr & PMCRE)) {
+if (!(env->cp15.c9_pmcr & PMCRE) || !(env->cp15.c9_pmcnten & (1 << 31))) {
 return false;
 }
 
-- 
Qualcomm Datacenter Technologies as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.




[Qemu-devel] [PATCH v3 00/22] More fully implement ARM PMUv3

2018-03-16 Thread Aaron Lindsay
The ARM PMU implementation currently contains a basic cycle counter, but it is
often useful to gather counts of other events and filter them based on
execution mode. These patches flesh out the implementations of various PMU
registers including PM[X]EVCNTR and PM[X]EVTYPER, add a struct definition to
represent arbitrary counter types, implement mode filtering, and add
instruction, cycle, and software increment events.

I aim to eventually add raising interrupts on counter overflow, but that is not
covered by this patchset. I think I have a reasonable grasp of the mechanics of
*how* to raise them, but am curious if anyone has thoughts on how to determine
*when* to raise them - we don't want to call into PMU code every time an
instruction is executed to check if any instruction counters have overflowed,
etc. The main candidate I've seen for doing this so far would be to set up a
QEMUTimer, but I haven't fully explored it. Does that seem plausible? Any
other/better ideas?


Changes from v2:

* Many minor fixups (splitting patches, style/comment fixes, etc.)
* Save off current cycle count during operations which may change whether a
  counter is enabled, ensuring time isn't lost (update to patch 5)
* Added the ability to have more than one el_change_hook, added hooks before EL
  changes (patches 7-9)
* Added proper handling of can_do_io during code-gen before and after the
  el_change_hooks (patch 8)
* Split off PMOVSSET register definitions so they are only enabled for v7ve+
  (added patch 15, update to 16)

Thanks for any feedback,
Aaron
 

Aaron Lindsay (22):
  target/arm: A53: Initialize PMCEID[01]
  target/arm: A15 PMCEID0 initialization style nit
  target/arm: Check PMCNTEN for whether PMCCNTR is enabled
  target/arm: Treat PMCCNTR as alias of PMCCNTR_EL0
  target/arm: Reorganize PMCCNTR read, write, sync
  target/arm: Mask PMU register writes based on PMCR_EL0.N
  target/arm: Fetch GICv3 state directly from CPUARMState
  target/arm: Support multiple EL change hooks
  target/arm: Add pre-EL change hooks
  target/arm: Allow EL change hooks to do IO
  target/arm: Fix bitmask for PMCCFILTR writes
  target/arm: Filter cycle counter based on PMCCFILTR_EL0
  target/arm: Allow AArch32 access for PMCCFILTR
  target/arm: Make PMOVSCLR 64 bits wide
  target/arm: Add ARM_FEATURE_V7VE for v7 Virtualization Extensions
  target/arm: Implement PMOVSSET
  target/arm: Split arm_ccnt_enabled into generic pmu_counter_enabled
  target/arm: Add array for supported PMU events, generate PMCEID[01]
  target/arm: Finish implementation of PM[X]EVCNTR and PM[X]EVTYPER
  target/arm: PMU: Add instruction and cycle events
  target/arm: PMU: Set PMCR.N to 4
  target/arm: Implement PMSWINC

 hw/intc/arm_gicv3_cpuif.c  |  10 +-
 target/arm/cpu.c   |  40 ++-
 target/arm/cpu.h   | 102 +---
 target/arm/cpu64.c |   2 +
 target/arm/helper.c| 616 ++---
 target/arm/internals.h |  14 +-
 target/arm/op_helper.c |   8 +
 target/arm/translate-a64.c |   2 +
 target/arm/translate.c |   4 +
 9 files changed, 651 insertions(+), 147 deletions(-)

-- 
Qualcomm Datacenter Technologies as an affiliate of Qualcomm Technologies, Inc.
Qualcomm Technologies, Inc. is a member of the
Code Aurora Forum, a Linux Foundation Collaborative Project.




[Qemu-devel] [PATCH] migration: Fix block migration flag case

2018-03-16 Thread Dr. David Alan Gilbert (git)
From: "Dr. David Alan Gilbert" 

Fix the case where when a migration with a bad protocol is tried,
we leave the block migration capability set.

(This is a cut down version of my 'migration: Fix block failure cases'
where it's other case was fixed by Peter's dd0ee30caeebbd )

Signed-off-by: Dr. David Alan Gilbert 
---
 migration/migration.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/migration/migration.c b/migration/migration.c
index 1f22f463d3..20084b32dd 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -1423,6 +1423,7 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk,
"a valid migration protocol");
 migrate_set_state(>state, MIGRATION_STATUS_SETUP,
   MIGRATION_STATUS_FAILED);
+block_cleanup_parameters(s);
 return;
 }
 
-- 
2.14.3




Re: [Qemu-devel] [PATCH v3 00/24] RISC-V Post-merge spec conformance and cleanup

2018-03-16 Thread no-reply
Hi,

This series seems to have some coding style problems. See output below for
more information:

Type: series
Message-id: 1521229281-73637-1-git-send-email-...@sifive.com
Subject: [Qemu-devel] [PATCH v3 00/24] RISC-V Post-merge spec conformance and 
cleanup

=== TEST SCRIPT BEGIN ===
#!/bin/bash

BASE=base
n=1
total=$(git log --oneline $BASE.. | wc -l)
failed=0

git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram

commits="$(git log --format=%H --reverse $BASE..)"
for c in $commits; do
echo "Checking PATCH $n/$total: $(git log -n 1 --format=%s $c)..."
if ! git show $c --format=email | ./scripts/checkpatch.pl --mailback -; then
failed=1
echo
fi
n=$((n+1))
done

exit $failed
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 * [new tag]   
patchew/1521229281-73637-1-git-send-email-...@sifive.com -> 
patchew/1521229281-73637-1-git-send-email-...@sifive.com
Switched to a new branch 'test'
cf9ad8471c RISC-V: Clear mtval/stval on exceptions without info
e0eb5ad03f RISC-V: Convert cpu definition towards future model
cb986bd661 RISC-V: Remove support for adhoc X_COP interrupt
c1bea999fe RISC-V: No traps on writes to misa, minstret, mcycle
c45005f71d RISC-V: vectored traps are optional
23dccf73aa RISC-V: riscv-qemu port supports sv39 and sv48
9beecddea0 RISC-V: Remove braces from satp case statement
db362a77b9 RISC-V: Hardwire satp to 0 for no-mmu case
c696060959 RISC-V: Remove EM_RISCV ELF_MACHINE indirection
e48c09d25a RISC-V: Use memory_region_is_ram in pte update
eaa01d4e61 RISC-V: Make virt header comment title consistent
9435045fd8 RISC-V: Make some header guards more specific
23973a84f7 RISC-V: Update E order and I extension order
6efbb781e4 RISC-V: Improve page table walker spec compliance
924e46b0b8 RISC-V: Hold rcu_read_lock when accessing memory
eef95b067f RISC-V: Include intruction hex in disassembly
3884a14086 RISC-V: Make sure rom has space for fdt
49ad774612 RISC-V: Remove unused class definitions
4b771876d8 RISC-V: Mark ROM read-only after copying in code
646a8d2508 RISC-V: Remove identity_translate from load_elf
c582b7bbf0 RISC-V: Use ROM base address and size from memmap
8a3ef54b0d RISC-V: Make virt board description match spike
ba0cbace2d RISC-V: Replace hardcoded constants with enum values
ec0c0eea8c RISC-V: Make virt create_fdt interface consistent

=== OUTPUT BEGIN ===
Checking PATCH 1/24: RISC-V: Make virt create_fdt interface consistent...
Checking PATCH 2/24: RISC-V: Replace hardcoded constants with enum values...
Checking PATCH 3/24: RISC-V: Make virt board description match spike...
Checking PATCH 4/24: RISC-V: Use ROM base address and size from memmap...
Checking PATCH 5/24: RISC-V: Remove identity_translate from load_elf...
Checking PATCH 6/24: RISC-V: Mark ROM read-only after copying in code...
Checking PATCH 7/24: RISC-V: Remove unused class definitions...
Checking PATCH 8/24: RISC-V: Make sure rom has space for fdt...
Checking PATCH 9/24: RISC-V: Include intruction hex in disassembly...
Checking PATCH 10/24: RISC-V: Hold rcu_read_lock when accessing memory...
ERROR: switch and case should be at the same indent
#50: FILE: target/riscv/helper.c:240:
+switch (action) {
+case success: break;
+case translate_fail: return TRANSLATE_FAIL;
+case restart_walk: goto restart;

ERROR: trailing statements should be on next line
#51: FILE: target/riscv/helper.c:241:
+case success: break;

ERROR: trailing statements should be on next line
#53: FILE: target/riscv/helper.c:243:
+case restart_walk: goto restart;

total: 3 errors, 0 warnings, 32 lines checked

Your patch has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

Checking PATCH 11/24: RISC-V: Improve page table walker spec compliance...
Checking PATCH 12/24: RISC-V: Update E order and I extension order...
Checking PATCH 13/24: RISC-V: Make some header guards more specific...
Checking PATCH 14/24: RISC-V: Make virt header comment title consistent...
Checking PATCH 15/24: RISC-V: Use memory_region_is_ram in pte update...
Checking PATCH 16/24: RISC-V: Remove EM_RISCV ELF_MACHINE indirection...
Checking PATCH 17/24: RISC-V: Hardwire satp to 0 for no-mmu case...
Checking PATCH 18/24: RISC-V: Remove braces from satp case statement...
Checking PATCH 19/24: RISC-V: riscv-qemu port supports sv39 and sv48...
Checking PATCH 20/24: RISC-V: vectored traps are optional...
ERROR: trailing whitespace
#27: FILE: target/riscv/op_helper.c:265:
+/* we do not support vectored traps for asynchrounous interrupts */ $

ERROR: trailing whitespace
#42: FILE: target/riscv/op_helper.c:286:
+/* we do not support vectored traps for asynchrounous interrupts */ $

total: 2 

[Qemu-devel] [PATCH v3 23/24] RISC-V: Convert cpu definition towards future model

2018-03-16 Thread Michael Clark
- Model borrowed from target/sh4/cpu.c
- Rewrote riscv_cpu_list to use object_class_get_list
- Dropped 'struct RISCVCPUInfo' and used TypeInfo array
- Replaced riscv_cpu_register_types with DEFINE_TYPES
- Marked base class as abstract

Cc: Igor Mammedov 
Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Signed-off-by: Palmer Dabbelt 
Signed-off-by: Michael Clark 
Reviewed-by: Philippe Mathieu-Daudé 
---
 target/riscv/cpu.c | 123 ++---
 1 file changed, 69 insertions(+), 54 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index d2ae56a..1f25968 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -115,6 +115,8 @@ static void riscv_any_cpu_init(Object *obj)
 set_resetvec(env, DEFAULT_RSTVEC);
 }
 
+#if defined(TARGET_RISCV32)
+
 static void rv32gcsu_priv1_09_1_cpu_init(Object *obj)
 {
 CPURISCVState *env = _CPU(obj)->env;
@@ -141,6 +143,8 @@ static void rv32imacu_nommu_cpu_init(Object *obj)
 set_resetvec(env, DEFAULT_RSTVEC);
 }
 
+#elif defined(TARGET_RISCV64)
+
 static void rv64gcsu_priv1_09_1_cpu_init(Object *obj)
 {
 CPURISCVState *env = _CPU(obj)->env;
@@ -167,20 +171,7 @@ static void rv64imacu_nommu_cpu_init(Object *obj)
 set_resetvec(env, DEFAULT_RSTVEC);
 }
 
-static const RISCVCPUInfo riscv_cpus[] = {
-{ 96, TYPE_RISCV_CPU_ANY,  riscv_any_cpu_init },
-{ 32, TYPE_RISCV_CPU_RV32GCSU_V1_09_1, rv32gcsu_priv1_09_1_cpu_init },
-{ 32, TYPE_RISCV_CPU_RV32GCSU_V1_10_0, rv32gcsu_priv1_10_0_cpu_init },
-{ 32, TYPE_RISCV_CPU_RV32IMACU_NOMMU,  rv32imacu_nommu_cpu_init },
-{ 32, TYPE_RISCV_CPU_SIFIVE_E31,   rv32imacu_nommu_cpu_init },
-{ 32, TYPE_RISCV_CPU_SIFIVE_U34,   rv32gcsu_priv1_10_0_cpu_init },
-{ 64, TYPE_RISCV_CPU_RV64GCSU_V1_09_1, rv64gcsu_priv1_09_1_cpu_init },
-{ 64, TYPE_RISCV_CPU_RV64GCSU_V1_10_0, rv64gcsu_priv1_10_0_cpu_init },
-{ 64, TYPE_RISCV_CPU_RV64IMACU_NOMMU,  rv64imacu_nommu_cpu_init },
-{ 64, TYPE_RISCV_CPU_SIFIVE_E51,   rv64imacu_nommu_cpu_init },
-{ 64, TYPE_RISCV_CPU_SIFIVE_U54,   rv64gcsu_priv1_10_0_cpu_init },
-{ 0, NULL, NULL }
-};
+#endif
 
 static ObjectClass *riscv_cpu_class_by_name(const char *cpu_model)
 {
@@ -366,28 +357,6 @@ static void riscv_cpu_class_init(ObjectClass *c, void 
*data)
 cc->vmsd = _riscv_cpu;
 }
 
-static void cpu_register(const RISCVCPUInfo *info)
-{
-TypeInfo type_info = {
-.name = info->name,
-.parent = TYPE_RISCV_CPU,
-.instance_size = sizeof(RISCVCPU),
-.instance_init = info->initfn,
-};
-
-type_register(_info);
-}
-
-static const TypeInfo riscv_cpu_type_info = {
-.name = TYPE_RISCV_CPU,
-.parent = TYPE_CPU,
-.instance_size = sizeof(RISCVCPU),
-.instance_init = riscv_cpu_init,
-.abstract = false,
-.class_size = sizeof(RISCVCPUClass),
-.class_init = riscv_cpu_class_init,
-};
-
 char *riscv_isa_string(RISCVCPU *cpu)
 {
 int i;
@@ -403,30 +372,76 @@ char *riscv_isa_string(RISCVCPU *cpu)
 return isa_string;
 }
 
-void riscv_cpu_list(FILE *f, fprintf_function cpu_fprintf)
+typedef struct RISCVCPUListState {
+fprintf_function cpu_fprintf;
+FILE *file;
+} RISCVCPUListState;
+
+static gint riscv_cpu_list_compare(gconstpointer a, gconstpointer b)
 {
-const RISCVCPUInfo *info = riscv_cpus;
+ObjectClass *class_a = (ObjectClass *)a;
+ObjectClass *class_b = (ObjectClass *)b;
+const char *name_a, *name_b;
 
-while (info->name) {
-if (info->bit_widths & TARGET_LONG_BITS) {
-(*cpu_fprintf)(f, "%s\n", info->name);
-}
-info++;
-}
+name_a = object_class_get_name(class_a);
+name_b = object_class_get_name(class_b);
+return strcmp(name_a, name_b);
 }
 
-static void riscv_cpu_register_types(void)
+static void riscv_cpu_list_entry(gpointer data, gpointer user_data)
 {
-const RISCVCPUInfo *info = riscv_cpus;
+RISCVCPUListState *s = user_data;
+const char *typename = object_class_get_name(OBJECT_CLASS(data));
+int len = strlen(typename) - strlen(RISCV_CPU_TYPE_SUFFIX);
 
-type_register_static(_cpu_type_info);
+(*s->cpu_fprintf)(s->file, "%.*s\n", len, typename);
+}
 
-while (info->name) {
-if (info->bit_widths & TARGET_LONG_BITS) {
-cpu_register(info);
-}
-info++;
-}
+void riscv_cpu_list(FILE *f, fprintf_function cpu_fprintf)
+{
+RISCVCPUListState s = {
+.cpu_fprintf = cpu_fprintf,
+.file = f,
+};
+GSList *list;
+
+list = object_class_get_list(TYPE_RISCV_CPU, false);
+list = g_slist_sort(list, riscv_cpu_list_compare);
+g_slist_foreach(list, riscv_cpu_list_entry, );
+g_slist_free(list);
 }
 
-type_init(riscv_cpu_register_types)
+#define DEFINE_CPU(type_name, initfn)  \
+{  \
+ 

[Qemu-devel] [PATCH v3 19/24] RISC-V: riscv-qemu port supports sv39 and sv48

2018-03-16 Thread Michael Clark
Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Signed-off-by: Michael Clark 
Signed-off-by: Palmer Dabbelt 
---
 target/riscv/cpu.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 7c4482b..f47fc9c 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -24,8 +24,8 @@
 #define TARGET_PAGE_BITS 12 /* 4 KiB Pages */
 #if defined(TARGET_RISCV64)
 #define TARGET_LONG_BITS 64
-#define TARGET_PHYS_ADDR_SPACE_BITS 50
-#define TARGET_VIRT_ADDR_SPACE_BITS 39
+#define TARGET_PHYS_ADDR_SPACE_BITS 52
+#define TARGET_VIRT_ADDR_SPACE_BITS 48
 #elif defined(TARGET_RISCV32)
 #define TARGET_LONG_BITS 32
 #define TARGET_PHYS_ADDR_SPACE_BITS 34
-- 
2.7.0




[Qemu-devel] [PATCH v3 16/24] RISC-V: Remove EM_RISCV ELF_MACHINE indirection

2018-03-16 Thread Michael Clark
Pointless indirection. Other ports use EM_ constants directly.

Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Signed-off-by: Michael Clark 
Signed-off-by: Palmer Dabbelt 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/riscv/sifive_e.c | 2 +-
 hw/riscv/sifive_u.c | 2 +-
 hw/riscv/spike.c| 2 +-
 hw/riscv/virt.c | 2 +-
 target/riscv/cpu.h  | 1 -
 5 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
index 4872b68..39e4cb4 100644
--- a/hw/riscv/sifive_e.c
+++ b/hw/riscv/sifive_e.c
@@ -88,7 +88,7 @@ static uint64_t load_kernel(const char *kernel_filename)
 
 if (load_elf(kernel_filename, NULL, NULL,
  _entry, NULL, _high,
- 0, ELF_MACHINE, 1, 0) < 0) {
+ 0, EM_RISCV, 1, 0) < 0) {
 error_report("qemu: could not load kernel '%s'", kernel_filename);
 exit(1);
 }
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 57b4f4f..0e633a0 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -74,7 +74,7 @@ static uint64_t load_kernel(const char *kernel_filename)
 
 if (load_elf(kernel_filename, NULL, NULL,
  _entry, NULL, _high,
- 0, ELF_MACHINE, 1, 0) < 0) {
+ 0, EM_RISCV, 1, 0) < 0) {
 error_report("qemu: could not load kernel '%s'", kernel_filename);
 exit(1);
 }
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
index c7d937b..70e697c 100644
--- a/hw/riscv/spike.c
+++ b/hw/riscv/spike.c
@@ -64,7 +64,7 @@ static uint64_t load_kernel(const char *kernel_filename)
 uint64_t kernel_entry, kernel_high;
 
 if (load_elf_ram_sym(kernel_filename, NULL, NULL,
-_entry, NULL, _high, 0, ELF_MACHINE, 1, 0,
+_entry, NULL, _high, 0, EM_RISCV, 1, 0,
 NULL, true, htif_symbol_callback) < 0) {
 error_report("qemu: could not load kernel '%s'", kernel_filename);
 exit(1);
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index d680cbd..e3f8bb7 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -68,7 +68,7 @@ static uint64_t load_kernel(const char *kernel_filename)
 
 if (load_elf(kernel_filename, NULL, NULL,
  _entry, NULL, _high,
- 0, ELF_MACHINE, 1, 0) < 0) {
+ 0, EM_RISCV, 1, 0) < 0) {
 error_report("qemu: could not load kernel '%s'", kernel_filename);
 exit(1);
 }
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 3a0ca2f..7c4482b 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -34,7 +34,6 @@
 
 #define TCG_GUEST_DEFAULT_MO 0
 
-#define ELF_MACHINE EM_RISCV
 #define CPUArchState struct CPURISCVState
 
 #include "qemu-common.h"
-- 
2.7.0




[Qemu-devel] [PATCH v3 15/24] RISC-V: Use memory_region_is_ram in pte update

2018-03-16 Thread Michael Clark
After reading cpu_physical_memory_write and friends, it seems
that memory_region_is_ram is a more appropriate interface,
and matches the intent of the code that is calling it.

Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Signed-off-by: Michael Clark 
Signed-off-by: Palmer Dabbelt 
---
 target/riscv/helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/riscv/helper.c b/target/riscv/helper.c
index 523a275..c430e95 100644
--- a/target/riscv/helper.c
+++ b/target/riscv/helper.c
@@ -237,7 +237,7 @@ restart:
 rcu_read_lock();
 mr = address_space_translate(cs->as, pte_addr,
 , , false);
-if (memory_access_is_direct(mr, true)) {
+if (memory_region_is_ram(mr)) {
 target_ulong *pte_pa =
 qemu_map_ram_ptr(mr->ram_block, addr1);
 #if TCG_OVERSIZED_GUEST
-- 
2.7.0




[Qemu-devel] [PATCH v3 21/24] RISC-V: No traps on writes to misa, minstret, mcycle

2018-03-16 Thread Michael Clark
These fields are marked WARL in the specification so illegal
writes are silently dropped.

Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Signed-off-by: Michael Clark 
Signed-off-by: Palmer Dabbelt 
---
 target/riscv/op_helper.c | 26 +-
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index aa101cc..f8595a6 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -200,17 +200,19 @@ void csr_write_helper(CPURISCVState *env, target_ulong 
val_to_write,
 break;
 }
 case CSR_MINSTRET:
-qemu_log_mask(LOG_UNIMP, "CSR_MINSTRET: write not implemented");
-goto do_illegal;
+/* minstret is WARL so unsupported writes are ignored */
+break;
 case CSR_MCYCLE:
-qemu_log_mask(LOG_UNIMP, "CSR_MCYCLE: write not implemented");
-goto do_illegal;
+/* mcycle is WARL so unsupported writes are ignored */
+break;
+#if defined(TARGET_RISCV32)
 case CSR_MINSTRETH:
-qemu_log_mask(LOG_UNIMP, "CSR_MINSTRETH: write not implemented");
-goto do_illegal;
+/* minstreth is WARL so unsupported writes are ignored */
+break;
 case CSR_MCYCLEH:
-qemu_log_mask(LOG_UNIMP, "CSR_MCYCLEH: write not implemented");
-goto do_illegal;
+/* mcycleh is WARL so unsupported writes are ignored */
+break;
+#endif
 case CSR_MUCOUNTEREN:
 env->mucounteren = val_to_write;
 break;
@@ -300,10 +302,9 @@ void csr_write_helper(CPURISCVState *env, target_ulong 
val_to_write,
 case CSR_MBADADDR:
 env->mbadaddr = val_to_write;
 break;
-case CSR_MISA: {
-qemu_log_mask(LOG_UNIMP, "CSR_MISA: misa writes not supported");
-goto do_illegal;
-}
+case CSR_MISA:
+/* misa is WARL so unsupported writes are ignored */
+break;
 case CSR_PMPCFG0:
 case CSR_PMPCFG1:
 case CSR_PMPCFG2:
@@ -328,7 +329,6 @@ void csr_write_helper(CPURISCVState *env, target_ulong 
val_to_write,
 case CSR_PMPADDR15:
pmpaddr_csr_write(env, csrno - CSR_PMPADDR0, val_to_write);
break;
-do_illegal:
 #endif
 default:
 do_raise_exception_err(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
-- 
2.7.0




[Qemu-devel] [PATCH v3 14/24] RISC-V: Make virt header comment title consistent

2018-03-16 Thread Michael Clark
Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Signed-off-by: Michael Clark 
Signed-off-by: Palmer Dabbelt 
Reviewed-by: Philippe Mathieu-Daudé 
---
 include/hw/riscv/virt.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
index 3a4f23e..91163d6 100644
--- a/include/hw/riscv/virt.h
+++ b/include/hw/riscv/virt.h
@@ -1,5 +1,5 @@
 /*
- * SiFive VirtIO Board
+ * QEMU RISC-V VirtIO machine interface
  *
  * Copyright (c) 2017 SiFive, Inc.
  *
-- 
2.7.0




[Qemu-devel] [PATCH v3 22/24] RISC-V: Remove support for adhoc X_COP interrupt

2018-03-16 Thread Michael Clark
This is essentially dead-code elimination. Support for more
local interrupts will be added in a future revision, as they
will be defined in a future version of the Privileged ISA
specification.

Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Signed-off-by: Michael Clark 
Signed-off-by: Palmer Dabbelt 
---
 target/riscv/cpu_bits.h  | 1 -
 target/riscv/op_helper.c | 2 +-
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 12b4757..133e070 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -346,7 +346,6 @@
 #define IRQ_S_EXT   9
 #define IRQ_H_EXT   10 /* until: priv-1.9.1 */
 #define IRQ_M_EXT   11 /* until: priv-1.9.1 */
-#define IRQ_X_COP   12 /* non-standard */
 
 /* Default addresses */
 #define DEFAULT_RSTVEC 0x1000
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index f8595a6..f543e61 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -90,7 +90,7 @@ void csr_write_helper(CPURISCVState *env, target_ulong 
val_to_write,
 target_ulong csrno)
 {
 #ifndef CONFIG_USER_ONLY
-uint64_t delegable_ints = MIP_SSIP | MIP_STIP | MIP_SEIP | (1 << 
IRQ_X_COP);
+uint64_t delegable_ints = MIP_SSIP | MIP_STIP | MIP_SEIP;
 uint64_t all_ints = delegable_ints | MIP_MSIP | MIP_MTIP;
 #endif
 
-- 
2.7.0




[Qemu-devel] [PATCH v3 13/24] RISC-V: Make some header guards more specific

2018-03-16 Thread Michael Clark
Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Signed-off-by: Michael Clark 
Signed-off-by: Palmer Dabbelt 
Reviewed-by: Philippe Mathieu-Daudé 
---
 include/hw/riscv/spike.h | 4 ++--
 include/hw/riscv/virt.h  | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/include/hw/riscv/spike.h b/include/hw/riscv/spike.h
index 8410430..641b70d 100644
--- a/include/hw/riscv/spike.h
+++ b/include/hw/riscv/spike.h
@@ -16,8 +16,8 @@
  * this program.  If not, see .
  */
 
-#ifndef HW_SPIKE_H
-#define HW_SPIKE_H
+#ifndef HW_RISCV_SPIKE_H
+#define HW_RISCV_SPIKE_H
 
 typedef struct {
 /*< private >*/
diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
index b91a412..3a4f23e 100644
--- a/include/hw/riscv/virt.h
+++ b/include/hw/riscv/virt.h
@@ -16,8 +16,8 @@
  * this program.  If not, see .
  */
 
-#ifndef HW_VIRT_H
-#define HW_VIRT_H
+#ifndef HW_RISCV_VIRT_H
+#define HW_RISCV_VIRT_H
 
 typedef struct {
 /*< private >*/
-- 
2.7.0




[Qemu-devel] [PATCH v3 20/24] RISC-V: vectored traps are optional

2018-03-16 Thread Michael Clark
Vectored traps for asynchrounous interrupts are optional.
The mtvec/stvec mode field is WARL and hence does not trap
if an illegal value is written. Illegal values are ignored.

Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Signed-off-by: Michael Clark 
Signed-off-by: Palmer Dabbelt 
---
 target/riscv/op_helper.c | 14 ++
 1 file changed, 6 insertions(+), 8 deletions(-)

diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index f79716a..aa101cc 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -262,11 +262,10 @@ void csr_write_helper(CPURISCVState *env, target_ulong 
val_to_write,
 env->sepc = val_to_write;
 break;
 case CSR_STVEC:
-if (val_to_write & 1) {
-qemu_log_mask(LOG_UNIMP, "CSR_STVEC: vectored traps not 
supported");
-goto do_illegal;
+/* we do not support vectored traps for asynchrounous interrupts */ 
+if ((val_to_write & 3) == 0) {
+env->stvec = val_to_write >> 2 << 2;
 }
-env->stvec = val_to_write >> 2 << 2;
 break;
 case CSR_SCOUNTEREN:
 env->scounteren = val_to_write;
@@ -284,11 +283,10 @@ void csr_write_helper(CPURISCVState *env, target_ulong 
val_to_write,
 env->mepc = val_to_write;
 break;
 case CSR_MTVEC:
-if (val_to_write & 1) {
-qemu_log_mask(LOG_UNIMP, "CSR_MTVEC: vectored traps not 
supported");
-goto do_illegal;
+/* we do not support vectored traps for asynchrounous interrupts */ 
+if ((val_to_write & 3) == 0) {
+env->mtvec = val_to_write >> 2 << 2;
 }
-env->mtvec = val_to_write >> 2 << 2;
 break;
 case CSR_MCOUNTEREN:
 env->mcounteren = val_to_write;
-- 
2.7.0




[Qemu-devel] [PATCH v3 17/24] RISC-V: Hardwire satp to 0 for no-mmu case

2018-03-16 Thread Michael Clark
satp is WARL so it should not trap on illegal writes, rather
it can be hardwired to zero and silently ignore illegal writes.

It seems the RISC-V WARL behaviour is preferred to having to
trap overhead versus simply reading back the value and checking
if the write took (saves hundreds of cycles and more complex
trap handling code).

Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Signed-off-by: Michael Clark 
Signed-off-by: Palmer Dabbelt 
---
 target/riscv/op_helper.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index e34715d..dd3e417 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -242,7 +242,7 @@ void csr_write_helper(CPURISCVState *env, target_ulong 
val_to_write,
 }
 case CSR_SATP: /* CSR_SPTBR */ {
 if (!riscv_feature(env, RISCV_FEATURE_MMU)) {
-goto do_illegal;
+break;
 }
 if (env->priv_ver <= PRIV_VERSION_1_09_1 && (val_to_write ^ 
env->sptbr))
 {
@@ -452,7 +452,10 @@ target_ulong csr_read_helper(CPURISCVState *env, 
target_ulong csrno)
 return env->scounteren;
 case CSR_SCAUSE:
 return env->scause;
-case CSR_SPTBR:
+case CSR_SATP: /* CSR_SPTBR */
+if (!riscv_feature(env, RISCV_FEATURE_MMU)) {
+return 0;
+}
 if (env->priv_ver >= PRIV_VERSION_1_10_0) {
 return env->satp;
 } else {
-- 
2.7.0




[Qemu-devel] [PATCH v3 12/24] RISC-V: Update E order and I extension order

2018-03-16 Thread Michael Clark
Section 22.8 Subset Naming Convention of the RISC-V ISA Specification
defines the canonical order for extensions in the ISA string. It is
silent on the position of the E extension however E is a substitute
for I so it must come early in the extension list order. A comment
is added to state E and I are mutually exclusive, as the E extension
will be added to the RISC-V port in the future.

Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Signed-off-by: Michael Clark 
Signed-off-by: Palmer Dabbelt 
---
 target/riscv/cpu.c | 2 +-
 target/riscv/cpu.h | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 4851890..d2ae56a 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -26,7 +26,7 @@
 
 /* RISC-V CPU definitions */
 
-static const char riscv_exts[26] = "IMAFDQECLBJTPVNSUHKORWXYZG";
+static const char riscv_exts[26] = "IEMAFDQCLBJTPVNSUHKORWXYZG";
 
 const char * const riscv_int_regnames[] = {
   "zero", "ra  ", "sp  ", "gp  ", "tp  ", "t0  ", "t1  ", "t2  ",
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index cff02a2..3a0ca2f 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -71,6 +71,7 @@
 #define RV(x) ((target_ulong)1 << (x - 'A'))
 
 #define RVI RV('I')
+#define RVE RV('E') /* E and I are mutually exclusive */
 #define RVM RV('M')
 #define RVA RV('A')
 #define RVF RV('F')
-- 
2.7.0




[Qemu-devel] [PATCH v3 24/24] RISC-V: Clear mtval/stval on exceptions without info

2018-03-16 Thread Michael Clark
mtval/stval must be set on all exceptions but zero is
a legal value if there is no exception specific info.
Placing the instruction bytes for illegal instruction
exceptions in mtval/stval is an optional feature and
is currently not supported by QEMU RISC-V.

Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Signed-off-by: Palmer Dabbelt 
Signed-off-by: Michael Clark 
---
 target/riscv/helper.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/target/riscv/helper.c b/target/riscv/helper.c
index c430e95..54d4ff7 100644
--- a/target/riscv/helper.c
+++ b/target/riscv/helper.c
@@ -499,6 +499,10 @@ void riscv_cpu_do_interrupt(CPUState *cs)
 ": badaddr 0x" TARGET_FMT_lx, env->mhartid, env->badaddr);
 }
 env->sbadaddr = env->badaddr;
+} else {
+/* otherwise we must clear sbadaddr/stval
+ * todo: support populating stval on illegal instructions */
+env->sbadaddr = 0;
 }
 
 target_ulong s = env->mstatus;
@@ -520,6 +524,10 @@ void riscv_cpu_do_interrupt(CPUState *cs)
 ": badaddr 0x" TARGET_FMT_lx, env->mhartid, env->badaddr);
 }
 env->mbadaddr = env->badaddr;
+} else {
+/* otherwise we must clear mbadaddr/mtval
+ * todo: support populating mtval on illegal instructions */
+env->mbadaddr = 0;
 }
 
 target_ulong s = env->mstatus;
-- 
2.7.0




[Qemu-devel] [PATCH v3 18/24] RISC-V: Remove braces from satp case statement

2018-03-16 Thread Michael Clark
Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Signed-off-by: Michael Clark 
Signed-off-by: Palmer Dabbelt 
Reviewed-by: Philippe Mathieu-Daudé 
---
 target/riscv/op_helper.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index dd3e417..f79716a 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -240,7 +240,7 @@ void csr_write_helper(CPURISCVState *env, target_ulong 
val_to_write,
 csr_write_helper(env, next_mie, CSR_MIE);
 break;
 }
-case CSR_SATP: /* CSR_SPTBR */ {
+case CSR_SATP: /* CSR_SPTBR */
 if (!riscv_feature(env, RISCV_FEATURE_MMU)) {
 break;
 }
@@ -258,7 +258,6 @@ void csr_write_helper(CPURISCVState *env, target_ulong 
val_to_write,
 env->satp = val_to_write;
 }
 break;
-}
 case CSR_SEPC:
 env->sepc = val_to_write;
 break;
-- 
2.7.0




[Qemu-devel] [PATCH v3 10/24] RISC-V: Hold rcu_read_lock when accessing memory

2018-03-16 Thread Michael Clark
>From reading other code that accesses memory regions directly,
it appears that the rcu_read_lock needs to be held. Note: the
original code for accessing RAM directly was added because
there is no other way to use atomic_cmpxchg on guest physical
address space.

Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Signed-off-by: Michael Clark 
Signed-off-by: Palmer Dabbelt 
---
 target/riscv/helper.c | 14 --
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/target/riscv/helper.c b/target/riscv/helper.c
index 02cbcea..e71633a 100644
--- a/target/riscv/helper.c
+++ b/target/riscv/helper.c
@@ -209,6 +209,9 @@ restart:
as the PTE is no longer valid */
 MemoryRegion *mr;
 hwaddr l = sizeof(target_ulong), addr1;
+enum { success, translate_fail, restart_walk} action = success;
+
+rcu_read_lock();
 mr = address_space_translate(cs->as, pte_addr,
 , , false);
 if (memory_access_is_direct(mr, true)) {
@@ -222,7 +225,7 @@ restart:
 target_ulong old_pte =
 atomic_cmpxchg(pte_pa, pte, updated_pte);
 if (old_pte != pte) {
-goto restart;
+action = restart_walk;
 } else {
 pte = updated_pte;
 }
@@ -230,7 +233,14 @@ restart:
 } else {
 /* misconfigured PTE in ROM (AD bits are not preset) or
  * PTE is in IO space and can't be updated atomically */
-return TRANSLATE_FAIL;
+action = translate_fail;
+}
+rcu_read_unlock();
+
+switch (action) {
+case success: break;
+case translate_fail: return TRANSLATE_FAIL;
+case restart_walk: goto restart;
 }
 }
 
-- 
2.7.0




[Qemu-devel] [PATCH v3 05/24] RISC-V: Remove identity_translate from load_elf

2018-03-16 Thread Michael Clark
When load_elf is called with NULL as an argument to the
address translate callback, it does an identity translation.
This commit removes the redundant identity_translate callback.

Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Signed-off-by: Michael Clark 
Signed-off-by: Palmer Dabbelt 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/riscv/sifive_e.c | 7 +--
 hw/riscv/sifive_u.c | 7 +--
 hw/riscv/spike.c| 7 +--
 hw/riscv/virt.c | 7 +--
 4 files changed, 4 insertions(+), 24 deletions(-)

diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
index 19eca36..09c9d49 100644
--- a/hw/riscv/sifive_e.c
+++ b/hw/riscv/sifive_e.c
@@ -82,16 +82,11 @@ static void copy_le32_to_phys(hwaddr pa, uint32_t *rom, 
size_t len)
 }
 }
 
-static uint64_t identity_translate(void *opaque, uint64_t addr)
-{
-return addr;
-}
-
 static uint64_t load_kernel(const char *kernel_filename)
 {
 uint64_t kernel_entry, kernel_high;
 
-if (load_elf(kernel_filename, identity_translate, NULL,
+if (load_elf(kernel_filename, NULL, NULL,
  _entry, NULL, _high,
  0, ELF_MACHINE, 1, 0) < 0) {
 error_report("qemu: could not load kernel '%s'", kernel_filename);
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index f3f7615..6116c38 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -68,16 +68,11 @@ static void copy_le32_to_phys(hwaddr pa, uint32_t *rom, 
size_t len)
 }
 }
 
-static uint64_t identity_translate(void *opaque, uint64_t addr)
-{
-return addr;
-}
-
 static uint64_t load_kernel(const char *kernel_filename)
 {
 uint64_t kernel_entry, kernel_high;
 
-if (load_elf(kernel_filename, identity_translate, NULL,
+if (load_elf(kernel_filename, NULL, NULL,
  _entry, NULL, _high,
  0, ELF_MACHINE, 1, 0) < 0) {
 error_report("qemu: could not load kernel '%s'", kernel_filename);
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
index 4c233ec..7710333 100644
--- a/hw/riscv/spike.c
+++ b/hw/riscv/spike.c
@@ -59,16 +59,11 @@ static void copy_le32_to_phys(hwaddr pa, uint32_t *rom, 
size_t len)
 }
 }
 
-static uint64_t identity_translate(void *opaque, uint64_t addr)
-{
-return addr;
-}
-
 static uint64_t load_kernel(const char *kernel_filename)
 {
 uint64_t kernel_entry, kernel_high;
 
-if (load_elf_ram_sym(kernel_filename, identity_translate, NULL,
+if (load_elf_ram_sym(kernel_filename, NULL, NULL,
 _entry, NULL, _high, 0, ELF_MACHINE, 1, 0,
 NULL, true, htif_symbol_callback) < 0) {
 error_report("qemu: could not load kernel '%s'", kernel_filename);
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 0d101fc..f8c19b4 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -62,16 +62,11 @@ static void copy_le32_to_phys(hwaddr pa, uint32_t *rom, 
size_t len)
 }
 }
 
-static uint64_t identity_translate(void *opaque, uint64_t addr)
-{
-return addr;
-}
-
 static uint64_t load_kernel(const char *kernel_filename)
 {
 uint64_t kernel_entry, kernel_high;
 
-if (load_elf(kernel_filename, identity_translate, NULL,
+if (load_elf(kernel_filename, NULL, NULL,
  _entry, NULL, _high,
  0, ELF_MACHINE, 1, 0) < 0) {
 error_report("qemu: could not load kernel '%s'", kernel_filename);
-- 
2.7.0




[Qemu-devel] [PATCH v3 09/24] RISC-V: Include intruction hex in disassembly

2018-03-16 Thread Michael Clark
This was added to help debug issues using -d in_asm. It is
useful to see the instruction bytes, as one can detect if
one is trying to execute ASCII or device-tree magic.

Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Signed-off-by: Michael Clark 
Signed-off-by: Palmer Dabbelt 
Reviewed-by: Philippe Mathieu-Daudé 
---
 disas/riscv.c | 39 ---
 1 file changed, 20 insertions(+), 19 deletions(-)

diff --git a/disas/riscv.c b/disas/riscv.c
index 3c17501..4580308 100644
--- a/disas/riscv.c
+++ b/disas/riscv.c
@@ -2769,25 +2769,6 @@ static void format_inst(char *buf, size_t buflen, size_t 
tab, rv_decode *dec)
 char tmp[64];
 const char *fmt;
 
-if (dec->op == rv_op_illegal) {
-size_t len = inst_length(dec->inst);
-switch (len) {
-case 2:
-snprintf(buf, buflen, "(0x%04" PRIx64 ")", dec->inst);
-break;
-case 4:
-snprintf(buf, buflen, "(0x%08" PRIx64 ")", dec->inst);
-break;
-case 6:
-snprintf(buf, buflen, "(0x%012" PRIx64 ")", dec->inst);
-break;
-default:
-snprintf(buf, buflen, "(0x%016" PRIx64 ")", dec->inst);
-break;
-}
-return;
-}
-
 fmt = opcode_data[dec->op].format;
 while (*fmt) {
 switch (*fmt) {
@@ -3004,6 +2985,11 @@ disasm_inst(char *buf, size_t buflen, rv_isa isa, 
uint64_t pc, rv_inst inst)
 format_inst(buf, buflen, 16, );
 }
 
+#define INST_FMT_2 "%04" PRIx64 "  "
+#define INST_FMT_4 "%08" PRIx64 "  "
+#define INST_FMT_6 "%012" PRIx64 "  "
+#define INST_FMT_8 "%016" PRIx64 "  "
+
 static int
 print_insn_riscv(bfd_vma memaddr, struct disassemble_info *info, rv_isa isa)
 {
@@ -3031,6 +3017,21 @@ print_insn_riscv(bfd_vma memaddr, struct 
disassemble_info *info, rv_isa isa)
 }
 }
 
+switch (len) {
+case 2:
+(*info->fprintf_func)(info->stream, INST_FMT_2, inst);
+break;
+case 4:
+(*info->fprintf_func)(info->stream, INST_FMT_4, inst);
+break;
+case 6:
+(*info->fprintf_func)(info->stream, INST_FMT_6, inst);
+break;
+default:
+(*info->fprintf_func)(info->stream, INST_FMT_8, inst);
+break;
+}
+
 disasm_inst(buf, sizeof(buf), isa, memaddr, inst);
 (*info->fprintf_func)(info->stream, "%s", buf);
 
-- 
2.7.0




[Qemu-devel] [PATCH v3 11/24] RISC-V: Improve page table walker spec compliance

2018-03-16 Thread Michael Clark
- Inline PTE_TABLE check for better readability
- Improve readibility of User page U mode and SUM test
- Disallow non U mode from fetching from User pages
- Add reserved PTE flag check: W or W|X
- Add misaligned PPN check
- Set READ flag for PTE X flag if mstatus.mxr is in effect
- Change access checks from ternary operator to if statements
- Improves page walker comments
- No measurable performance impact on dd test

Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Signed-off-by: Michael Clark 
Signed-off-by: Palmer Dabbelt 
---
 target/riscv/cpu_bits.h |  2 --
 target/riscv/helper.c   | 59 ++---
 2 files changed, 41 insertions(+), 20 deletions(-)

diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 64aa097..12b4757 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -407,5 +407,3 @@
 #define PTE_SOFT  0x300 /* Reserved for Software */
 
 #define PTE_PPN_SHIFT 10
-
-#define PTE_TABLE(PTE) (((PTE) & (PTE_V | PTE_R | PTE_W | PTE_X)) == PTE_V)
diff --git a/target/riscv/helper.c b/target/riscv/helper.c
index e71633a..523a275 100644
--- a/target/riscv/helper.c
+++ b/target/riscv/helper.c
@@ -185,16 +185,36 @@ restart:
 #endif
 target_ulong ppn = pte >> PTE_PPN_SHIFT;
 
-if (PTE_TABLE(pte)) { /* next level of page table */
+if (!(pte & PTE_V)) {
+/* Invalid PTE */
+return TRANSLATE_FAIL;
+} else if (!(pte & (PTE_R | PTE_W | PTE_X))) {
+/* Inner PTE, continue walking */
 base = ppn << PGSHIFT;
-} else if ((pte & PTE_U) ? (mode == PRV_S) && !sum : !(mode == PRV_S)) 
{
-break;
-} else if (!(pte & PTE_V) || (!(pte & PTE_R) && (pte & PTE_W))) {
-break;
-} else if (access_type == MMU_INST_FETCH ? !(pte & PTE_X) :
-  access_type == MMU_DATA_LOAD ?  !(pte & PTE_R) &&
-  !(mxr && (pte & PTE_X)) : !((pte & PTE_R) && (pte & PTE_W))) 
{
-break;
+} else if ((pte & (PTE_R | PTE_W | PTE_X)) == PTE_W) {
+/* Reserved leaf PTE flags: PTE_W */
+return TRANSLATE_FAIL;
+} else if ((pte & (PTE_R | PTE_W | PTE_X)) == (PTE_W | PTE_X)) {
+/* Reserved leaf PTE flags: PTE_W + PTE_X */
+return TRANSLATE_FAIL;
+} else if ((pte & PTE_U) && ((mode != PRV_U) &&
+   (!sum || access_type == MMU_INST_FETCH))) {
+/* User PTE flags when not U mode and mstatus.SUM is not set,
+   or the access type is an instruction fetch */
+return TRANSLATE_FAIL;
+} else if (ppn & ((1ULL << ptshift) - 1)) {
+/* Misasligned PPN */
+return TRANSLATE_FAIL;
+} else if (access_type == MMU_DATA_LOAD && !((pte & PTE_R) ||
+   ((pte & PTE_X) && mxr))) {
+/* Read access check failed */
+return TRANSLATE_FAIL;
+} else if (access_type == MMU_DATA_STORE && !(pte & PTE_W)) {
+/* Write access check failed */
+return TRANSLATE_FAIL;
+} else if (access_type == MMU_INST_FETCH && !(pte & PTE_X)) {
+/* Fetch access check failed */
+return TRANSLATE_FAIL;
 } else {
 /* if necessary, set accessed and dirty bits. */
 target_ulong updated_pte = pte | PTE_A |
@@ -202,11 +222,14 @@ restart:
 
 /* Page table updates need to be atomic with MTTCG enabled */
 if (updated_pte != pte) {
-/* if accessed or dirty bits need updating, and the PTE is
- * in RAM, then we do so atomically with a compare and swap.
- * if the PTE is in IO space, then it can't be updated.
- * if the PTE changed, then we must re-walk the page table
-   as the PTE is no longer valid */
+/*
+ * - if accessed or dirty bits need updating, and the PTE is
+ *   in RAM, then we do so atomically with a compare and swap.
+ * - if the PTE is in IO space or ROM, then it can't be updated
+ *   and we return TRANSLATE_FAIL.
+ * - if the PTE changed by the time we went to update it, then
+ *   it is no longer valid and we must re-walk the page table.
+ */
 MemoryRegion *mr;
 hwaddr l = sizeof(target_ulong), addr1;
 enum { success, translate_fail, restart_walk} action = success;
@@ -249,15 +272,15 @@ restart:
 target_ulong vpn = addr >> PGSHIFT;
 *physical = (ppn | (vpn & ((1L << ptshift) - 1))) << PGSHIFT;
 
-if ((pte & PTE_R)) {
+/* set permissions on the TLB entry */
+if ((pte & PTE_R) || (mode != PRV_U && (pte & PTE_X) && mxr)) {
 *prot |= PAGE_READ;
  

[Qemu-devel] [PATCH v3 07/24] RISC-V: Remove unused class definitions

2018-03-16 Thread Michael Clark
Removes a whole lot of unnecessary boilerplate code. Machines
don't need to be objects. The expansion of the SOC object model
for the RISC-V machines will happen in the future as SiFive
plans to add their FE310 and FU540 SOCs to QEMU. However, it
seems that this present boilerplate is complete unnecessary.

Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Signed-off-by: Michael Clark 
Signed-off-by: Palmer Dabbelt 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/riscv/riscv_hart.c   |  6 --
 hw/riscv/sifive_e.c | 25 -
 hw/riscv/sifive_u.c | 25 -
 hw/riscv/spike.c| 20 
 hw/riscv/virt.c | 25 -
 include/hw/riscv/sifive_e.h |  5 -
 include/hw/riscv/sifive_u.h |  5 -
 include/hw/riscv/spike.h|  7 ---
 include/hw/riscv/virt.h |  5 -
 9 files changed, 4 insertions(+), 119 deletions(-)

diff --git a/hw/riscv/riscv_hart.c b/hw/riscv/riscv_hart.c
index 14e3c18..75ba7ed 100644
--- a/hw/riscv/riscv_hart.c
+++ b/hw/riscv/riscv_hart.c
@@ -68,16 +68,10 @@ static void riscv_harts_class_init(ObjectClass *klass, void 
*data)
 dc->realize = riscv_harts_realize;
 }
 
-static void riscv_harts_init(Object *obj)
-{
-/* RISCVHartArrayState *s = SIFIVE_COREPLEX(obj); */
-}
-
 static const TypeInfo riscv_harts_info = {
 .name  = TYPE_RISCV_HART_ARRAY,
 .parent= TYPE_SYS_BUS_DEVICE,
 .instance_size = sizeof(RISCVHartArrayState),
-.instance_init = riscv_harts_init,
 .class_init= riscv_harts_class_init,
 };
 
diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
index 09c9d49..4872b68 100644
--- a/hw/riscv/sifive_e.c
+++ b/hw/riscv/sifive_e.c
@@ -194,24 +194,6 @@ static void riscv_sifive_e_init(MachineState *machine)
 }
 }
 
-static int riscv_sifive_e_sysbus_device_init(SysBusDevice *sysbusdev)
-{
-return 0;
-}
-
-static void riscv_sifive_e_class_init(ObjectClass *klass, void *data)
-{
-SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-k->init = riscv_sifive_e_sysbus_device_init;
-}
-
-static const TypeInfo riscv_sifive_e_device = {
-.name  = TYPE_SIFIVE_E,
-.parent= TYPE_SYS_BUS_DEVICE,
-.instance_size = sizeof(SiFiveEState),
-.class_init= riscv_sifive_e_class_init,
-};
-
 static void riscv_sifive_e_machine_init(MachineClass *mc)
 {
 mc->desc = "RISC-V Board compatible with SiFive E SDK";
@@ -220,10 +202,3 @@ static void riscv_sifive_e_machine_init(MachineClass *mc)
 }
 
 DEFINE_MACHINE("sifive_e", riscv_sifive_e_machine_init)
-
-static void riscv_sifive_e_register_types(void)
-{
-type_register_static(_sifive_e_device);
-}
-
-type_init(riscv_sifive_e_register_types);
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 25df16c..083043a 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -302,31 +302,6 @@ static void riscv_sifive_u_init(MachineState *machine)
 SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE);
 }
 
-static int riscv_sifive_u_sysbus_device_init(SysBusDevice *sysbusdev)
-{
-return 0;
-}
-
-static void riscv_sifive_u_class_init(ObjectClass *klass, void *data)
-{
-SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-k->init = riscv_sifive_u_sysbus_device_init;
-}
-
-static const TypeInfo riscv_sifive_u_device = {
-.name  = TYPE_SIFIVE_U,
-.parent= TYPE_SYS_BUS_DEVICE,
-.instance_size = sizeof(SiFiveUState),
-.class_init= riscv_sifive_u_class_init,
-};
-
-static void riscv_sifive_u_register_types(void)
-{
-type_register_static(_sifive_u_device);
-}
-
-type_init(riscv_sifive_u_register_types);
-
 static void riscv_sifive_u_machine_init(MachineClass *mc)
 {
 mc->desc = "RISC-V Board compatible with SiFive U SDK";
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
index 74edf33..64e585e 100644
--- a/hw/riscv/spike.c
+++ b/hw/riscv/spike.c
@@ -336,18 +336,6 @@ static void spike_v1_09_1_board_init(MachineState *machine)
 smp_cpus, SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE);
 }
 
-static const TypeInfo spike_v_1_09_1_device = {
-.name  = TYPE_RISCV_SPIKE_V1_09_1_BOARD,
-.parent= TYPE_SYS_BUS_DEVICE,
-.instance_size = sizeof(SpikeState),
-};
-
-static const TypeInfo spike_v_1_10_0_device = {
-.name  = TYPE_RISCV_SPIKE_V1_10_0_BOARD,
-.parent= TYPE_SYS_BUS_DEVICE,
-.instance_size = sizeof(SpikeState),
-};
-
 static void spike_v1_09_1_machine_init(MachineClass *mc)
 {
 mc->desc = "RISC-V Spike Board (Privileged ISA v1.9.1)";
@@ -365,11 +353,3 @@ static void spike_v1_10_0_machine_init(MachineClass *mc)
 
 DEFINE_MACHINE("spike_v1.9.1", spike_v1_09_1_machine_init)
 DEFINE_MACHINE("spike_v1.10", spike_v1_10_0_machine_init)
-
-static void riscv_spike_board_register_types(void)
-{
-

[Qemu-devel] [PATCH v3 01/24] RISC-V: Make virt create_fdt interface consistent

2018-03-16 Thread Michael Clark
create_fdt sets the fdt variable on RISCVVirtState and this is
used to access the fdt. This reverts a change introduced in
https://github.com/riscv/riscv-qemu/pull/109 which introduced
a redundant return value, overlooking the RISCVVirtState
structure member that made create_fdt inconsistent with the
other RISC-V machines. The other alternative is to change
the other boards to return the fdt. Note: the RISCVVirtState
also contains fdt_size.

Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Signed-off-by: Michael Clark 
Signed-off-by: Palmer Dabbelt 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/riscv/virt.c | 13 +
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index e2c214e..37968d2 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -108,7 +108,7 @@ static hwaddr load_initrd(const char *filename, uint64_t 
mem_size,
 return *start + size;
 }
 
-static void *create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
+static void create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
 uint64_t mem_size, const char *cmdline)
 {
 void *fdt;
@@ -264,8 +264,6 @@ static void *create_fdt(RISCVVirtState *s, const struct 
MemmapEntry *memmap,
 qemu_fdt_setprop_string(fdt, "/chosen", "stdout-path", nodename);
 qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", cmdline);
 g_free(nodename);
-
-return fdt;
 }
 
 static void riscv_virt_board_init(MachineState *machine)
@@ -279,7 +277,6 @@ static void riscv_virt_board_init(MachineState *machine)
 char *plic_hart_config;
 size_t plic_hart_config_len;
 int i;
-void *fdt;
 
 /* Initialize SOC */
 object_initialize(>soc, sizeof(s->soc), TYPE_RISCV_HART_ARRAY);
@@ -299,7 +296,7 @@ static void riscv_virt_board_init(MachineState *machine)
 main_mem);
 
 /* create device tree */
-fdt = create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline);
+create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline);
 
 /* boot rom */
 memory_region_init_ram(boot_rom, NULL, "riscv_virt_board.bootrom",
@@ -314,9 +311,9 @@ static void riscv_virt_board_init(MachineState *machine)
 hwaddr end = load_initrd(machine->initrd_filename,
  machine->ram_size, kernel_entry,
  );
-qemu_fdt_setprop_cell(fdt, "/chosen",
-  "linux,initrd-start", start);
-qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end",
+qemu_fdt_setprop_cell(s->fdt, "/chosen", "linux,initrd-start",
+  start);
+qemu_fdt_setprop_cell(s->fdt, "/chosen", "linux,initrd-end",
   end);
 }
 }
-- 
2.7.0




[Qemu-devel] [PATCH v3 08/24] RISC-V: Make sure rom has space for fdt

2018-03-16 Thread Michael Clark
Remove a potential buffer overflow (not seen in practice).
Perhaps cpu_physical_memory_write already has bound checks.
This change however makes space for the maximum device tree
size and adds an explicit bounds check and error message.
It doesn't trigger, but it may help in the future if the
device-tree size is exceeded. e.g. large bootargs.

Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Signed-off-by: Michael Clark 
Signed-off-by: Palmer Dabbelt 
---
 hw/riscv/sifive_u.c | 20 
 hw/riscv/spike.c| 16 +++-
 hw/riscv/virt.c | 13 +
 3 files changed, 32 insertions(+), 17 deletions(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 083043a..57b4f4f 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -52,7 +52,7 @@ static const struct MemmapEntry {
 hwaddr size;
 } sifive_u_memmap[] = {
 [SIFIVE_U_DEBUG] ={0x0,  0x100 },
-[SIFIVE_U_MROM] = { 0x1000, 0x2000 },
+[SIFIVE_U_MROM] = { 0x1000,0x11000 },
 [SIFIVE_U_CLINT] ={  0x200,0x1 },
 [SIFIVE_U_PLIC] = {  0xc00,  0x400 },
 [SIFIVE_U_UART0] ={ 0x10013000, 0x1000 },
@@ -221,7 +221,7 @@ static void riscv_sifive_u_init(MachineState *machine)
 const struct MemmapEntry *memmap = sifive_u_memmap;
 
 SiFiveUState *s = g_new0(SiFiveUState, 1);
-MemoryRegion *sys_memory = get_system_memory();
+MemoryRegion *system_memory = get_system_memory();
 MemoryRegion *main_mem = g_new(MemoryRegion, 1);
 MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
 
@@ -239,7 +239,7 @@ static void riscv_sifive_u_init(MachineState *machine)
 /* register RAM */
 memory_region_init_ram(main_mem, NULL, "riscv.sifive.u.ram",
machine->ram_size, _fatal);
-memory_region_add_subregion(sys_memory, memmap[SIFIVE_U_DRAM].base,
+memory_region_add_subregion(system_memory, memmap[SIFIVE_U_DRAM].base,
 main_mem);
 
 /* create device tree */
@@ -247,9 +247,9 @@ static void riscv_sifive_u_init(MachineState *machine)
 
 /* boot rom */
 memory_region_init_ram(mask_rom, NULL, "riscv.sifive.u.mrom",
-   memmap[SIFIVE_U_MROM].base, _fatal);
-memory_region_set_readonly(mask_rom, true);
-memory_region_add_subregion(sys_memory, 0x0, mask_rom);
+   memmap[SIFIVE_U_MROM].size, _fatal);
+memory_region_add_subregion(system_memory, memmap[SIFIVE_U_MROM].base,
+mask_rom);
 
 if (machine->kernel_filename) {
 load_kernel(machine->kernel_filename);
@@ -276,6 +276,10 @@ static void riscv_sifive_u_init(MachineState *machine)
 copy_le32_to_phys(memmap[SIFIVE_U_MROM].base, reset_vec, 
sizeof(reset_vec));
 
 /* copy in the device tree */
+if (s->fdt_size >= memmap[SIFIVE_U_MROM].size - sizeof(reset_vec)) {
+error_report("qemu: not enough space to store device-tree");
+exit(1);
+}
 qemu_fdt_dumpdtb(s->fdt, s->fdt_size);
 cpu_physical_memory_write(memmap[SIFIVE_U_MROM].base +
 sizeof(reset_vec), s->fdt, s->fdt_size);
@@ -293,9 +297,9 @@ static void riscv_sifive_u_init(MachineState *machine)
 SIFIVE_U_PLIC_CONTEXT_BASE,
 SIFIVE_U_PLIC_CONTEXT_STRIDE,
 memmap[SIFIVE_U_PLIC].size);
-sifive_uart_create(sys_memory, memmap[SIFIVE_U_UART0].base,
+sifive_uart_create(system_memory, memmap[SIFIVE_U_UART0].base,
 serial_hds[0], SIFIVE_PLIC(s->plic)->irqs[SIFIVE_U_UART0_IRQ]);
-/* sifive_uart_create(sys_memory, memmap[SIFIVE_U_UART1].base,
+/* sifive_uart_create(system_memory, memmap[SIFIVE_U_UART1].base,
 serial_hds[1], SIFIVE_PLIC(s->plic)->irqs[SIFIVE_U_UART1_IRQ]); */
 sifive_clint_create(memmap[SIFIVE_U_CLINT].base,
 memmap[SIFIVE_U_CLINT].size, smp_cpus,
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
index 64e585e..c7d937b 100644
--- a/hw/riscv/spike.c
+++ b/hw/riscv/spike.c
@@ -46,7 +46,7 @@ static const struct MemmapEntry {
 hwaddr base;
 hwaddr size;
 } spike_memmap[] = {
-[SPIKE_MROM] = { 0x1000, 0x2000 },
+[SPIKE_MROM] = { 0x1000,0x11000 },
 [SPIKE_CLINT] ={  0x200,0x1 },
 [SPIKE_DRAM] = { 0x8000,0x0 },
 };
@@ -197,8 +197,9 @@ static void spike_v1_10_0_board_init(MachineState *machine)
 
 /* boot rom */
 memory_region_init_ram(mask_rom, NULL, "riscv.spike.mrom",
-   s->fdt_size + 0x2000, _fatal);
-memory_region_add_subregion(system_memory, 0x0, mask_rom);
+   memmap[SPIKE_MROM].size, _fatal);
+memory_region_add_subregion(system_memory, memmap[SPIKE_MROM].base,
+mask_rom);
 
 if (machine->kernel_filename) {
 load_kernel(machine->kernel_filename);
@@ -225,6 +226,10 @@ static void 

[Qemu-devel] [PATCH v3 06/24] RISC-V: Mark ROM read-only after copying in code

2018-03-16 Thread Michael Clark
The sifive_u machine already marks its ROM readonly. This fixes
the remaining boards.

Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Signed-off-by: Michael Clark 
Signed-off-by: Palmer Dabbelt 
---
 hw/riscv/sifive_u.c  |  9 +
 hw/riscv/spike.c | 18 ++
 hw/riscv/virt.c  |  7 ---
 include/hw/riscv/spike.h |  8 
 4 files changed, 19 insertions(+), 23 deletions(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 6116c38..25df16c 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -223,7 +223,7 @@ static void riscv_sifive_u_init(MachineState *machine)
 SiFiveUState *s = g_new0(SiFiveUState, 1);
 MemoryRegion *sys_memory = get_system_memory();
 MemoryRegion *main_mem = g_new(MemoryRegion, 1);
-MemoryRegion *boot_rom = g_new(MemoryRegion, 1);
+MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
 
 /* Initialize SOC */
 object_initialize(>soc, sizeof(s->soc), TYPE_RISCV_HART_ARRAY);
@@ -246,10 +246,10 @@ static void riscv_sifive_u_init(MachineState *machine)
 create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline);
 
 /* boot rom */
-memory_region_init_ram(boot_rom, NULL, "riscv.sifive.u.mrom",
+memory_region_init_ram(mask_rom, NULL, "riscv.sifive.u.mrom",
memmap[SIFIVE_U_MROM].base, _fatal);
-memory_region_set_readonly(boot_rom, true);
-memory_region_add_subregion(sys_memory, 0x0, boot_rom);
+memory_region_set_readonly(mask_rom, true);
+memory_region_add_subregion(sys_memory, 0x0, mask_rom);
 
 if (machine->kernel_filename) {
 load_kernel(machine->kernel_filename);
@@ -279,6 +279,7 @@ static void riscv_sifive_u_init(MachineState *machine)
 qemu_fdt_dumpdtb(s->fdt, s->fdt_size);
 cpu_physical_memory_write(memmap[SIFIVE_U_MROM].base +
 sizeof(reset_vec), s->fdt, s->fdt_size);
+memory_region_set_readonly(mask_rom, true);
 
 /* MMIO */
 s->plic = sifive_plic_create(memmap[SIFIVE_U_PLIC].base,
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
index 7710333..74edf33 100644
--- a/hw/riscv/spike.c
+++ b/hw/riscv/spike.c
@@ -173,7 +173,7 @@ static void spike_v1_10_0_board_init(MachineState *machine)
 SpikeState *s = g_new0(SpikeState, 1);
 MemoryRegion *system_memory = get_system_memory();
 MemoryRegion *main_mem = g_new(MemoryRegion, 1);
-MemoryRegion *boot_rom = g_new(MemoryRegion, 1);
+MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
 
 /* Initialize SOC */
 object_initialize(>soc, sizeof(s->soc), TYPE_RISCV_HART_ARRAY);
@@ -196,9 +196,9 @@ static void spike_v1_10_0_board_init(MachineState *machine)
 create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline);
 
 /* boot rom */
-memory_region_init_ram(boot_rom, NULL, "riscv.spike.bootrom",
+memory_region_init_ram(mask_rom, NULL, "riscv.spike.mrom",
s->fdt_size + 0x2000, _fatal);
-memory_region_add_subregion(system_memory, 0x0, boot_rom);
+memory_region_add_subregion(system_memory, 0x0, mask_rom);
 
 if (machine->kernel_filename) {
 load_kernel(machine->kernel_filename);
@@ -228,9 +228,10 @@ static void spike_v1_10_0_board_init(MachineState *machine)
 qemu_fdt_dumpdtb(s->fdt, s->fdt_size);
 cpu_physical_memory_write(memmap[SPIKE_MROM].base + sizeof(reset_vec),
 s->fdt, s->fdt_size);
+memory_region_set_readonly(mask_rom, true);
 
 /* initialize HTIF using symbols found in load_kernel */
-htif_mm_init(system_memory, boot_rom, >soc.harts[0].env, serial_hds[0]);
+htif_mm_init(system_memory, mask_rom, >soc.harts[0].env, serial_hds[0]);
 
 /* Core Local Interruptor (timer and IPI) */
 sifive_clint_create(memmap[SPIKE_CLINT].base, memmap[SPIKE_CLINT].size,
@@ -244,7 +245,7 @@ static void spike_v1_09_1_board_init(MachineState *machine)
 SpikeState *s = g_new0(SpikeState, 1);
 MemoryRegion *system_memory = get_system_memory();
 MemoryRegion *main_mem = g_new(MemoryRegion, 1);
-MemoryRegion *boot_rom = g_new(MemoryRegion, 1);
+MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
 
 /* Initialize SOC */
 object_initialize(>soc, sizeof(s->soc), TYPE_RISCV_HART_ARRAY);
@@ -264,9 +265,9 @@ static void spike_v1_09_1_board_init(MachineState *machine)
 main_mem);
 
 /* boot rom */
-memory_region_init_ram(boot_rom, NULL, "riscv.spike.bootrom",
+memory_region_init_ram(mask_rom, NULL, "riscv.spike.mrom",
0x4, _fatal);
-memory_region_add_subregion(system_memory, 0x0, boot_rom);
+memory_region_add_subregion(system_memory, 0x0, mask_rom);
 
 if (machine->kernel_filename) {
 load_kernel(machine->kernel_filename);
@@ -325,9 +326,10 @@ static void spike_v1_09_1_board_init(MachineState *machine)
 /* copy in the config string */
 

[Qemu-devel] [PATCH v3 03/24] RISC-V: Make virt board description match spike

2018-03-16 Thread Michael Clark
This makes 'qemu-system-riscv64 -machine help' output more tidy
and consistent.

Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Signed-off-by: Michael Clark 
Signed-off-by: Palmer Dabbelt 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/riscv/virt.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index a402856..0055439 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -404,7 +404,7 @@ static const TypeInfo riscv_virt_board_device = {
 
 static void riscv_virt_board_machine_init(MachineClass *mc)
 {
-mc->desc = "RISC-V VirtIO Board (Privileged spec v1.10)";
+mc->desc = "RISC-V VirtIO Board (Privileged ISA v1.10)";
 mc->init = riscv_virt_board_init;
 mc->max_cpus = 8; /* hardcoded limit in BBL */
 }
-- 
2.7.0




[Qemu-devel] [PATCH v3 00/24] RISC-V Post-merge spec conformance and cleanup

2018-03-16 Thread Michael Clark
This is a series of spec conformance bug fixes and code cleanups
that we would like to get in before the QEMU 2.12 release. This
series does not contain the fix to riscv_isa_string. Previous
versions of this series have been included in the riscv.org QEMU
repository and these changes have had extensive testing running
Fedora for RISC-V, including building QEMU inside of RISC-V QEMU
running SMP Linux.

* Implements WARL behavior for CSRs that don't support writes
* Improves specification conformance of the page table walker
  * Change access checks from ternary operator to if statements
  * Checks for misaligned PPNs
  * Disallow M-mode or S-mode from fetching from User pages
  * Adds reserved PTE flag check: W or W|X
  * Set READ flag for PTE X flag if mstatus.mxr is in effect
  * Improves page walker comments and general readability 
* Several trivial code cleanups to hw/riscv
  * Replacing hard coded constants with reference to enums
or the machine memory maps.
  * Remove unnecessary class initialization boilerplate
* Adds bounds checks when writing device-tree to ROM
* Updates the cpu model to use a more modern interface
* Sets mtval/stval to zero on exceptions without addresses

v2

- remove unused class boilerplate retains qom parent_obj
- convert cpu definition towards future model
- honor mstatus.mxr flag in page table walker

v3

- refactor rcu_read_lock in PTE update to use single unlock
- mstatus.mxr is in effect regardless of privilege mode
- remove unnecessary class init from riscv_hart
- set mtval/stval to zero on exceptions without addresses

Michael Clark (24):
  RISC-V: Make virt create_fdt interface consistent
  RISC-V: Replace hardcoded constants with enum values
  RISC-V: Make virt board description match spike
  RISC-V: Use ROM base address and size from memmap
  RISC-V: Remove identity_translate from load_elf
  RISC-V: Mark ROM read-only after copying in code
  RISC-V: Remove unused class definitions
  RISC-V: Make sure rom has space for fdt
  RISC-V: Include intruction hex in disassembly
  RISC-V: Hold rcu_read_lock when accessing memory
  RISC-V: Improve page table walker spec compliance
  RISC-V: Update E order and I extension order
  RISC-V: Make some header guards more specific
  RISC-V: Make virt header comment title consistent
  RISC-V: Use memory_region_is_ram in pte update
  RISC-V: Remove EM_RISCV ELF_MACHINE indirection
  RISC-V: Hardwire satp to 0 for no-mmu case
  RISC-V: Remove braces from satp case statement
  RISC-V: riscv-qemu port supports sv39 and sv48
  RISC-V: vectored traps are optional
  RISC-V: No traps on writes to misa,minstret,mcycle
  RISC-V: Remove support for adhoc X_COP interrupt
  RISC-V: Convert cpu definition towards future model
  RISC-V: Clear mtval/stval on exceptions without info

 disas/riscv.c   |  39 +++--
 hw/riscv/riscv_hart.c   |   6 --
 hw/riscv/sifive_clint.c |   9 +--
 hw/riscv/sifive_e.c |  34 +--
 hw/riscv/sifive_u.c |  65 +++--
 hw/riscv/spike.c|  65 -
 hw/riscv/virt.c |  77 +
 include/hw/riscv/sifive_clint.h |   4 ++
 include/hw/riscv/sifive_e.h |   5 --
 include/hw/riscv/sifive_u.h |   9 ++-
 include/hw/riscv/spike.h|  15 ++---
 include/hw/riscv/virt.h |  17 +++---
 target/riscv/cpu.c  | 125 ++--
 target/riscv/cpu.h  |   6 +-
 target/riscv/cpu_bits.h |   3 -
 target/riscv/helper.c   |  83 +++---
 target/riscv/op_helper.c|  52 -
 17 files changed, 279 insertions(+), 335 deletions(-)

Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Cc: Philippe Mathieu-Daudé 
Signed-off-by: Michael Clark 
Signed-off-by: Palmer Dabbelt 

-- 
2.7.0




[Qemu-devel] [PATCH v3 02/24] RISC-V: Replace hardcoded constants with enum values

2018-03-16 Thread Michael Clark
The RISC-V device-tree code has a number of hard-coded
constants and this change moves them into header enums.

Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Signed-off-by: Michael Clark 
Signed-off-by: Palmer Dabbelt 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/riscv/sifive_clint.c | 9 +++--
 hw/riscv/sifive_u.c | 6 --
 hw/riscv/spike.c| 6 --
 hw/riscv/virt.c | 6 --
 include/hw/riscv/sifive_clint.h | 4 
 include/hw/riscv/sifive_u.h | 4 
 include/hw/riscv/spike.h| 4 
 include/hw/riscv/virt.h | 4 
 8 files changed, 31 insertions(+), 12 deletions(-)

diff --git a/hw/riscv/sifive_clint.c b/hw/riscv/sifive_clint.c
index 4893453..7cc606e 100644
--- a/hw/riscv/sifive_clint.c
+++ b/hw/riscv/sifive_clint.c
@@ -26,13 +26,10 @@
 #include "hw/riscv/sifive_clint.h"
 #include "qemu/timer.h"
 
-/* See: riscv-pk/machine/sbi_entry.S and arch/riscv/kernel/time.c */
-#define TIMER_FREQ (10 * 1000 * 1000)
-
 static uint64_t cpu_riscv_read_rtc(void)
 {
-return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), TIMER_FREQ,
-NANOSECONDS_PER_SECOND);
+return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
+SIFIVE_CLINT_TIMEBASE_FREQ, NANOSECONDS_PER_SECOND);
 }
 
 /*
@@ -59,7 +56,7 @@ static void sifive_clint_write_timecmp(RISCVCPU *cpu, 
uint64_t value)
 diff = cpu->env.timecmp - rtc_r;
 /* back to ns (note args switched in muldiv64) */
 next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
-muldiv64(diff, NANOSECONDS_PER_SECOND, TIMER_FREQ);
+muldiv64(diff, NANOSECONDS_PER_SECOND, SIFIVE_CLINT_TIMEBASE_FREQ);
 timer_mod(cpu->env.timer, next);
 }
 
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 1c2deef..f3f7615 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -122,7 +122,8 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 g_free(nodename);
 
 qemu_fdt_add_subnode(fdt, "/cpus");
-qemu_fdt_setprop_cell(fdt, "/cpus", "timebase-frequency", 1000);
+qemu_fdt_setprop_cell(fdt, "/cpus", "timebase-frequency",
+SIFIVE_CLINT_TIMEBASE_FREQ);
 qemu_fdt_setprop_cell(fdt, "/cpus", "#size-cells", 0x0);
 qemu_fdt_setprop_cell(fdt, "/cpus", "#address-cells", 0x1);
 
@@ -131,7 +132,8 @@ static void create_fdt(SiFiveUState *s, const struct 
MemmapEntry *memmap,
 char *intc = g_strdup_printf("/cpus/cpu@%d/interrupt-controller", cpu);
 char *isa = riscv_isa_string(>soc.harts[cpu]);
 qemu_fdt_add_subnode(fdt, nodename);
-qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency", 10);
+qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency",
+  SIFIVE_U_CLOCK_FREQ);
 qemu_fdt_setprop_string(fdt, nodename, "mmu-type", "riscv,sv48");
 qemu_fdt_setprop_string(fdt, nodename, "riscv,isa", isa);
 qemu_fdt_setprop_string(fdt, nodename, "compatible", "riscv");
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
index 2d1f114..4c233ec 100644
--- a/hw/riscv/spike.c
+++ b/hw/riscv/spike.c
@@ -115,7 +115,8 @@ static void create_fdt(SpikeState *s, const struct 
MemmapEntry *memmap,
 g_free(nodename);
 
 qemu_fdt_add_subnode(fdt, "/cpus");
-qemu_fdt_setprop_cell(fdt, "/cpus", "timebase-frequency", 1000);
+qemu_fdt_setprop_cell(fdt, "/cpus", "timebase-frequency",
+SIFIVE_CLINT_TIMEBASE_FREQ);
 qemu_fdt_setprop_cell(fdt, "/cpus", "#size-cells", 0x0);
 qemu_fdt_setprop_cell(fdt, "/cpus", "#address-cells", 0x1);
 
@@ -124,7 +125,8 @@ static void create_fdt(SpikeState *s, const struct 
MemmapEntry *memmap,
 char *intc = g_strdup_printf("/cpus/cpu@%d/interrupt-controller", cpu);
 char *isa = riscv_isa_string(>soc.harts[cpu]);
 qemu_fdt_add_subnode(fdt, nodename);
-qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency", 10);
+qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency",
+  SPIKE_CLOCK_FREQ);
 qemu_fdt_setprop_string(fdt, nodename, "mmu-type", "riscv,sv48");
 qemu_fdt_setprop_string(fdt, nodename, "riscv,isa", isa);
 qemu_fdt_setprop_string(fdt, nodename, "compatible", "riscv");
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 37968d2..a402856 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -145,7 +145,8 @@ static void create_fdt(RISCVVirtState *s, const struct 
MemmapEntry *memmap,
 g_free(nodename);
 
 qemu_fdt_add_subnode(fdt, "/cpus");
-qemu_fdt_setprop_cell(fdt, "/cpus", "timebase-frequency", 1000);
+qemu_fdt_setprop_cell(fdt, "/cpus", "timebase-frequency",
+  SIFIVE_CLINT_TIMEBASE_FREQ);
 qemu_fdt_setprop_cell(fdt, "/cpus", "#size-cells", 0x0);
 qemu_fdt_setprop_cell(fdt, "/cpus", "#address-cells", 0x1);
 
@@ 

[Qemu-devel] [PATCH v3 04/24] RISC-V: Use ROM base address and size from memmap

2018-03-16 Thread Michael Clark
Another case of replacing hard coded constants, this time
referring to the definition in the virt machine's memmap.

Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Signed-off-by: Michael Clark 
Signed-off-by: Palmer Dabbelt 
Reviewed-by: Philippe Mathieu-Daudé 
---
 hw/riscv/virt.c | 4 ++--
 include/hw/riscv/virt.h | 2 --
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 0055439..0d101fc 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -338,11 +338,11 @@ static void riscv_virt_board_init(MachineState *machine)
 };
 
 /* copy in the reset vector */
-copy_le32_to_phys(ROM_BASE, reset_vec, sizeof(reset_vec));
+copy_le32_to_phys(memmap[VIRT_MROM].base, reset_vec, sizeof(reset_vec));
 
 /* copy in the device tree */
 qemu_fdt_dumpdtb(s->fdt, s->fdt_size);
-cpu_physical_memory_write(ROM_BASE + sizeof(reset_vec),
+cpu_physical_memory_write(memmap[VIRT_MROM].base + sizeof(reset_vec),
 s->fdt, s->fdt_size);
 
 /* create PLIC hart topology configuration string */
diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
index 2fbe808..655e85d 100644
--- a/include/hw/riscv/virt.h
+++ b/include/hw/riscv/virt.h
@@ -23,8 +23,6 @@
 #define VIRT(obj) \
 OBJECT_CHECK(RISCVVirtState, (obj), TYPE_RISCV_VIRT_BOARD)
 
-enum { ROM_BASE = 0x1000 };
-
 typedef struct {
 /*< private >*/
 SysBusDevice parent_obj;
-- 
2.7.0




[Qemu-devel] [PULL 1/1] pc: correct misspelled CPU model-id for pc 2.2

2018-03-16 Thread Eduardo Habkost
From: Wang Xin 

Signed-off-by: Wang Xin 
Message-Id: <1517367668-25048-1-git-send-email-wangxinxin.w...@huawei.com>
Acked-by: Michael S. Tsirkin 
Signed-off-by: Eduardo Habkost 
---
 include/hw/i386/pc.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 6598d571a0..ffee8413f0 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -601,7 +601,7 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
 
 #define PC_COMPAT_2_2 \
 HW_COMPAT_2_2 \
-PC_CPU_MODEL_IDS("2.3.0") \
+PC_CPU_MODEL_IDS("2.2.0") \
 {\
 .driver = "kvm64" "-" TYPE_X86_CPU,\
 .property = "vme",\
-- 
2.14.3




[Qemu-devel] [PULL 0/1] PC compat bug fix for v2.12

2018-03-16 Thread Eduardo Habkost
Dropped all the other commits from machine-next and kept only the
bug fix below.

The following changes since commit 2bb39a657abeac3f33ab3298177fb27c35f5b50a:

  Merge remote-tracking branch 'remotes/rth/tags/pull-tcg-20180316' into 
staging (2018-03-16 17:25:33 +)

are available in the Git repository at:

  git://github.com/ehabkost/qemu.git tags/machine-next-pull-request

for you to fetch changes up to 0ab126f165b04cce4a6e641d6bfce2ffd8a7cf62:

  pc: correct misspelled CPU model-id for pc 2.2 (2018-03-16 16:29:07 -0300)


PC compat bug fix for 2.12



Queue for Machine Core patches


Wang Xin (1):
  pc: correct misspelled CPU model-id for pc 2.2

 include/hw/i386/pc.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

-- 
2.14.3




Re: [Qemu-devel] [PULL v2 0/7] Machine queue, 2018-03-15

2018-03-16 Thread Eduardo Habkost
On Fri, Mar 16, 2018 at 07:05:29PM +, Peter Maydell wrote:
> On 15 March 2018 at 18:14, Eduardo Habkost  wrote:
> > Changes in v2 (v1 was 2018-03-12):
> > * Fix bsd-user build error
> >
> > The following changes since commit 56e8698ffa8aba9f762f980bc21b5340b006f24b:
> >
> >   Merge remote-tracking branch 
> > 'remotes/stsquad/tags/pull-travis-speedup-130318-1' into staging 
> > (2018-03-15 14:48:09 +)
> >
> > are available in the Git repository at:
> >
> >   git://github.com/ehabkost/qemu.git tags/machine-next-pull-request
> >
> > for you to fetch changes up to 7cbb6fd8926b9b590c0725b9b7d0a11db6aefd08:
> >
> >   cpu: drop unnecessary NULL check and cpu_common_class_by_name() 
> > (2018-03-15 14:52:40 -0300)
> >
> > 
> > Machine queue, 2018-03-15
> >
> 
> Hi. This produces several warning messages running make check:
> 
> WARNING: cpu name for target 'riscv32' isn't defined, add it to cpus_map
> WARNING: cpu name for target 'riscv64' isn't defined, add it to cpus_map

Ouch, another conflict with the commits that added target/riscv
after the original series was submitted.  :(

I will drop all the patches in this pull request except for the
only bug fix there ("pc: correct misspelled CPU model-id for pc
2.2").

Igor, can you resubmit the cpu_model/cpu_type series fixing the
warnings so I can queue it for v2.13?

-- 
Eduardo



Re: [Qemu-devel] [PULL v2 00/44] Block layer patches

2018-03-16 Thread Peter Maydell
On 15 March 2018 at 17:18, Kevin Wolf  wrote:
> The following changes since commit 56e8698ffa8aba9f762f980bc21b5340b006f24b:
>
>   Merge remote-tracking branch 
> 'remotes/stsquad/tags/pull-travis-speedup-130318-1' into staging (2018-03-15 
> 14:48:09 +)
>
> are available in the git repository at:
>
>   git://repo.or.cz/qemu/kevin.git tags/for-upstream
>
> for you to fetch changes up to d3137181e5e1e5e6b651b58484fc8f705a48ee36:
>
>   iscsi: fix iSER compilation (2018-03-15 17:58:26 +0100)
>
> 
> Block layer patches
>

I get merge conflicts trying to apply this; please fix and resend:

Auto-merging tests/qemu-iotests/group
CONFLICT (content): Merge conflict in tests/qemu-iotests/group
Auto-merging tests/qemu-iotests/209.out
CONFLICT (add/add): Merge conflict in tests/qemu-iotests/209.out
Auto-merging tests/qemu-iotests/209
CONFLICT (add/add): Merge conflict in tests/qemu-iotests/209

thanks
-- PMM



Re: [Qemu-devel] [PULL v2 0/7] Machine queue, 2018-03-15

2018-03-16 Thread Peter Maydell
On 15 March 2018 at 18:14, Eduardo Habkost  wrote:
> Changes in v2 (v1 was 2018-03-12):
> * Fix bsd-user build error
>
> The following changes since commit 56e8698ffa8aba9f762f980bc21b5340b006f24b:
>
>   Merge remote-tracking branch 
> 'remotes/stsquad/tags/pull-travis-speedup-130318-1' into staging (2018-03-15 
> 14:48:09 +)
>
> are available in the Git repository at:
>
>   git://github.com/ehabkost/qemu.git tags/machine-next-pull-request
>
> for you to fetch changes up to 7cbb6fd8926b9b590c0725b9b7d0a11db6aefd08:
>
>   cpu: drop unnecessary NULL check and cpu_common_class_by_name() (2018-03-15 
> 14:52:40 -0300)
>
> 
> Machine queue, 2018-03-15
>

Hi. This produces several warning messages running make check:

WARNING: cpu name for target 'riscv32' isn't defined, add it to cpus_map
WARNING: cpu name for target 'riscv64' isn't defined, add it to cpus_map

thanks
-- PMM



Re: [Qemu-devel] [PATCH] gdbstub: send a terminaison packet instead of crashing gdb

2018-03-16 Thread KONRAD Frederic

On 03/16/2018 05:34 PM, Peter Maydell wrote:

On 16 March 2018 at 16:23, KONRAD Frederic  wrote:

Since the commit:
commit 4486e89c219c0d1b9bd8dfa0b1dd5b0d51ff2268
Author: Stefan Hajnoczi 
Date:   Wed Mar 7 14:42:05 2018 +

 vl: introduce vm_shutdown()

GDB crash when qemu exits (at least on sparc-softmmu):
Remote communication error.  Target disconnected.: Connection reset by peer.
Quitting: putpkt: write failed: Broken pipe.

So send a packet to kill GDB before we exit QEMU:
[Inferior 1 (Thread 0) exited normally]

Signed-off-by: KONRAD Frederic 
---
  gdbstub.c  | 7 +++
  include/exec/gdbstub.h | 2 ++
  vl.c   | 2 ++
  3 files changed, 11 insertions(+)


We didn't send an exiting packet before commit 4486e89c219c0,
so do you know why this worked before then? (Telling gdb we're
exiting seems like the right thing, though.)



Hmmm good question, I didn't had time to investigate in detail

Before 4486e89c219c0:

(gdb) tar rem :1234
Remote debugging using :1234
0x4000 in trap_table ()
(gdb) c
Continuing.
Remote connection closed

After 4486e89c219c0:

(gdb) tar rem :1234
Remote debugging using :1234
0x4000 in trap_table ()
(gdb) c
Continuing.
putpkt: write failed: Connection reset by peer.

With the patch:

(gdb) tar rem :1234
Remote debugging using :1234
0x4000 in trap_table ()
(gdb) c
Continuing.
[Inferior 1 (Thread 0) exited normally]

We use to have this patch in our repository to avoid the remote
connection closed above.

Thanks,
Fred


thanks
-- PMM





Re: [Qemu-devel] [PATCH] ide: fix invalid TRIM range abortion for macio

2018-03-16 Thread John Snow


On 03/16/2018 07:20 AM, Mark Cave-Ayland wrote:
> On 05/03/18 21:54, Mark Cave-Ayland wrote:
> 
>> On 02/03/18 17:08, Anton Nefedov wrote:
>>
>>> commit 947858b0 "ide: abort TRIM operation for invalid range"
>>> is incorrect for macio; just ide_dma_error() without doing a callback
>>> is not enough for that errorpath.
>>>
>>> Instead, pass -EINVAL to the callback and handle it there
>>> (see related motivation for read/write in 58ac32113).
>>>
>>> It will however catch possible EINVAL from the block layer too.
>>>
>>> Signed-off-by: Anton Nefedov 
>>> ---
>>>   hw/ide/core.c | 17 +
>>>   1 file changed, 9 insertions(+), 8 deletions(-)
>>>
>>> diff --git a/hw/ide/core.c b/hw/ide/core.c
>>> index 257b429..54510d4 100644
>>> --- a/hw/ide/core.c
>>> +++ b/hw/ide/core.c
>>> @@ -402,7 +402,6 @@ typedef struct TrimAIOCB {
>>>   QEMUIOVector *qiov;
>>>   BlockAIOCB *aiocb;
>>>   int i, j;
>>> -    bool is_invalid;
>>>   } TrimAIOCB;
>>>   static void trim_aio_cancel(BlockAIOCB *acb)
>>> @@ -430,11 +429,8 @@ static void ide_trim_bh_cb(void *opaque)
>>>   {
>>>   TrimAIOCB *iocb = opaque;
>>> -    if (iocb->is_invalid) {
>>> -    ide_dma_error(iocb->s);
>>> -    } else {
>>> -    iocb->common.cb(iocb->common.opaque, iocb->ret);
>>> -    }
>>> +    iocb->common.cb(iocb->common.opaque, iocb->ret);
>>> +
>>>   qemu_bh_delete(iocb->bh);
>>>   iocb->bh = NULL;
>>>   qemu_aio_unref(iocb);
>>> @@ -462,7 +458,7 @@ static void ide_issue_trim_cb(void *opaque, int ret)
>>>   }
>>>   if (!ide_sect_range_ok(s, sector, count)) {
>>> -    iocb->is_invalid = true;
>>> +    iocb->ret = -EINVAL;
>>>   goto done;
>>>   }
>>> @@ -502,7 +498,6 @@ BlockAIOCB *ide_issue_trim(
>>>   iocb->qiov = qiov;
>>>   iocb->i = -1;
>>>   iocb->j = 0;
>>> -    iocb->is_invalid = false;
>>>   ide_issue_trim_cb(iocb, 0);
>>>   return >common;
>>>   }
>>> @@ -848,6 +843,12 @@ static void ide_dma_cb(void *opaque, int ret)
>>>   if (ret == -ECANCELED) {
>>>   return;
>>>   }
>>> +
>>> +    if (ret == -EINVAL) {
>>> +    ide_dma_error(s);
>>> +    return;
>>> +    }
>>> +
>>>   if (ret < 0) {
>>>   if (ide_handle_rw_error(s, -ret,
>>> ide_dma_cmd_to_retry(s->dma_cmd))) {
>>>   s->bus->dma->aiocb = NULL;
>>>
>>
>> Hi Anton,
>>
>> Thanks for this. I applied this patch to git master with my macio
>> patch at
>> https://lists.gnu.org/archive/html/qemu-devel/2018-02/msg06076.html
>> and it allowed to continue all the way through the Debian installer
>> for the PPC g3beige machine so I believe it is working.
>>
>> Tested-by: Mark Cave-Ayland 
> 
> Hi John,
> 
> I know that you're busy, but just wondering if you have managed to
> review these 2 TRIM patches? They are a candidate for 2.12 since they
> prevent a qemu-system-ppc segfault on Mac machines when issuing IDE TRIM
> commands.
> 
> 
> ATB,
> 
> Mark.

Will send a PR once it looks as if Peter Maydell has caught up with all
of the last-minute PR panic for soft freeze -- they're not forgotten, I
promise!

Thank you for checking in on me.

--John



Re: [Qemu-devel] [PATCH v8 19/23] SiFive RISC-V UART Device

2018-03-16 Thread Michael Clark
On Fri, Mar 16, 2018 at 11:30 AM, Michael Clark  wrote:

>
>
> On Sun, Mar 11, 2018 at 4:43 AM, Bastian Koppelmann <
> kbast...@mail.uni-paderborn.de> wrote:
>
>> Hi Mark,
>>
>> On 03/10/2018 10:40 AM, Mark Cave-Ayland wrote:
>> > On 10/03/18 03:02, Michael Clark wrote:
>> >
>> >> On Sat, Mar 10, 2018 at 1:39 AM, Philippe Mathieu-Daudé <
>> f4...@amsat.org>
>> >> wrote:
>> >>
>> [...]
>> > Another general note: for each of the main QEMU platforms supported
>> > there is a home page on the official wiki, so do make sure that you set
>> > yourself a template for RiscV and add some information to help people
>> > get started.
>> >
>> Thanks for the pointer. I went ahead and created a basic page for RISC-V
>> with instructions on how to build QEMU and boot Fedora.
>>
>
> Thanks Bastian! I'll add a link back to the official QEMU RISC-V
> Architecture page from the riscv-qemu repo wiki...
>

I noticed there is a spelling mistake in the description: "implented"
instead of "implemented"

Michael.


Re: [Qemu-devel] [PATCH v8 19/23] SiFive RISC-V UART Device

2018-03-16 Thread Michael Clark
On Sun, Mar 11, 2018 at 4:43 AM, Bastian Koppelmann <
kbast...@mail.uni-paderborn.de> wrote:

> Hi Mark,
>
> On 03/10/2018 10:40 AM, Mark Cave-Ayland wrote:
> > On 10/03/18 03:02, Michael Clark wrote:
> >
> >> On Sat, Mar 10, 2018 at 1:39 AM, Philippe Mathieu-Daudé <
> f4...@amsat.org>
> >> wrote:
> >>
> [...]
> > Another general note: for each of the main QEMU platforms supported
> > there is a home page on the official wiki, so do make sure that you set
> > yourself a template for RiscV and add some information to help people
> > get started.
> >
> Thanks for the pointer. I went ahead and created a basic page for RISC-V
> with instructions on how to build QEMU and boot Fedora.
>

Thanks Bastian! I'll add a link back to the official QEMU RISC-V
Architecture page from the riscv-qemu repo wiki...


Re: [Qemu-devel] qemu master build failure

2018-03-16 Thread Peter Maydell
On 16 March 2018 at 18:12, Christian Borntraeger  wrote:
> Does it make sense to have something like
>
> diff --git a/configure b/configure
> index 831ebf2..67d7ae3 100755
> --- a/configure
> +++ b/configure
> @@ -552,6 +552,10 @@ else
>  pwd_is_source_path="n"
>  fi
>
> +if test -f $source_path\/qemu-version.h -a $pwd_is_source_path = "n" ; then
> +error_exit "source path contains a stale configuration, cannot build outside"
> +fi

We already have an equivalent check to that in Makefile;
it looks for a config-host.mak:

# Check that we're not trying to do an out-of-tree build from
# a tree that's been used for an in-tree build.
ifneq ($(realpath $(SRC_PATH)),$(realpath .))
ifneq ($(wildcard $(SRC_PATH)/config-host.mak),)
$(error This is an out of tree build but your source tree ($(SRC_PATH)) \
seems to have been used for an in-tree build. You can fix this by running \
"$(MAKE) distclean && rm -rf *-linux-user *-softmmu" in your source tree)
endif
endif


Before commit 428952cfa966f it was possible for an accidental
run of 'make -j10' in the source tree to create qemu-options.def
and qemu-version.h in the source tree before the makefile noticed
you were trying it in the wrong directory. I think that after
that it should be much harder to end up with these stale files,
but of course if your tree already had a stale file from
before then the commit won't clean it up for you...

thanks
-- PMM



Re: [Qemu-devel] qemu master build failure

2018-03-16 Thread Daniel P . Berrangé
On Fri, Mar 16, 2018 at 07:12:26PM +0100, Christian Borntraeger wrote:
> Does it make sense to have something like
> 
> diff --git a/configure b/configure
> index 831ebf2..67d7ae3 100755
> --- a/configure
> +++ b/configure
> @@ -552,6 +552,10 @@ else
>  pwd_is_source_path="n"
>  fi
>  
> +if test -f $source_path\/qemu-version.h -a $pwd_is_source_path = "n" ; then
> +error_exit "source path contains a stale configuration, cannot build 
> outside" 
> +fi
> +

Yeah that is a check that autoconf does commonly to detect this
kind of mistake, so I think its good.


Regards,
Daniel
-- 
|: https://berrange.com  -o-https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o-https://fstop138.berrange.com :|
|: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|



[Qemu-devel] [PATCH] vhost-user: avoid misaligned access

2018-03-16 Thread Michael S. Tsirkin
We can't pass a pointer to memory field directly since
it's within a packed structure, so isn't aligned.
Pass a pointer on stack and copy.

Fixes: 30c4cc7 ("vhost: used_memslots refactoring")
Cc: Jay Zhou 
Signed-off-by: Michael S. Tsirkin 
---

I had to apply this to fix make check errors with clang.
Pls review, test and ack.

Thanks!

 hw/virtio/vhost-user.c | 14 +++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index c12fdd9..a44ee7f 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -396,6 +396,7 @@ static int vhost_user_set_mem_table_postcopy(struct 
vhost_dev *dev,
 bool reply_supported = virtio_has_feature(dev->protocol_features,
   VHOST_USER_PROTOCOL_F_REPLY_ACK);
 VhostUserMsg msg_reply;
+VhostUserMemory memory = {};
 int region_i, msg_i;
 
 VhostUserMsg msg = {
@@ -407,10 +408,11 @@ static int vhost_user_set_mem_table_postcopy(struct 
vhost_dev *dev,
 msg.hdr.flags |= VHOST_USER_NEED_REPLY_MASK;
 }
 
-if (vhost_user_prepare_msg(dev, , fds) < 0) {
+if (vhost_user_prepare_msg(dev, , fds) < 0) {
 error_report("Failed preparing vhost-user memory table msg");
 return -1;
 }
+msg.payload.memory = memory;
 
 fd_num = msg.payload.memory.nregions;
 
@@ -549,16 +551,19 @@ static int vhost_user_set_mem_table(struct vhost_dev *dev,
 .hdr.request = VHOST_USER_SET_MEM_TABLE,
 .hdr.flags = VHOST_USER_VERSION,
 };
+VhostUserMemory memory = {};
 
 if (reply_supported) {
 msg.hdr.flags |= VHOST_USER_NEED_REPLY_MASK;
 }
 
-if (vhost_user_prepare_msg(dev, , fds) < 0) {
+if (vhost_user_prepare_msg(dev, , fds) < 0) {
 error_report("Failed preparing vhost-user memory table msg");
 return -1;
 }
 
+msg.payload.memory = memory;
+
 fd_num = msg.payload.memory.nregions;
 
 if (!fd_num) {
@@ -1575,8 +1580,11 @@ static void vhost_user_set_used_memslots(struct 
vhost_dev *dev)
 {
 int fds[VHOST_MEMORY_MAX_NREGIONS];
 VhostUserMsg msg;
+VhostUserMemory memory = {};
+
+vhost_user_prepare_msg(dev, , fds);
 
-vhost_user_prepare_msg(dev, , fds);
+msg.payload.memory = memory;
 }
 
 const VhostOps user_ops = {
-- 
MST



Re: [Qemu-devel] [virtio-dev] Re: [v23 1/2] virtio-crypto: Add virtio crypto device specification

2018-03-16 Thread Halil Pasic


On 03/16/2018 05:27 PM, Michael S. Tsirkin wrote:
> On Tue, Jan 09, 2018 at 06:05:41PM +0100, Halil Pasic wrote:
>>> +\item[\field{max_cipher_key_len}] is the maximum length of cipher key 
>>> supported by the device.
>>
>> I can't find what happens if this limit isn't honored by the driver. Moreover
>> reading it is only SHOULD. Is it undefined behavior or should the device 
>> reject/fail
>> such requests? I think in qemu implementation we fail the request.
>>
>> This question is only about niceness. We are already good enough, IMHO:
>> since the implementer of the driver can't be sure what is going to happen
>> if the driver disregards max_cipher_key_len it is already an implicit
>> SHOULD.
> 
> I am not sure documenting undefined behaviour is always required.

I kind of agree. But I'm afraid I did not get through my point. It's
about clarity. The driver supplying a cipher key larger that
max_cipher_key_len isn't violating any driver normative statement.
I find it strange make obtaining a piece of configuration a driver
normative but have neither a driver normative that says the driver must
(or should) operate according to the same (at least in certain)
circumstances nor a device normative that implicitly educates the driver
implementer what happens if the driver is acting stupid (see below).


> We certainly do not do this for all other devices> 

"""
5.2.6.2 Device Requirements: Device Operation

A device MUST set the status byte to VIRTIO_BLK_S_IOERR for a write request if 
the VIRTIO_BLK_F_RO feature if offered, and MUST NOT write any data.
"""

I was under the impression, that we sometimes express what is naively
a driver-requirement (e.g. thou shall not write to a read only
device) as a device-requirement. This has benefits in my opinion:
the driver implementer is educated about a certain behavior being a no-no
and hopefully leading to sane error handling (with a compliant device
sitting on the other side) --- instead of  offending drivers landing beyond
the spec (in undefined behavior land) by violating a driver-normative.

> Reading a field being SHOULD seems reasonable: e.g.
> driver might read it once and cache it in memory.

I don't quite understand. Let me quote the normative section

+\drivernormative{\subsubsection}{Device configuration layout}{Device Types / 
Crypto Device / Device configuration layout}
+
+\begin{itemize*}
+\item The driver MUST read the \field{status} from the bottom bit of status to 
check whether the
+VIRTIO_CRYPTO_S_HW_READY is set, and the driver MUST reread it after 
device reset.
+\item The driver MUST NOT transmit any requests to the device if the 
VIRTIO_CRYPTO_S_HW_READY is not set.
+\item The driver MUST read \field{max_dataqueues} field to discover the number 
of data queues the device supports.

[..]

+\item The driver SHOULD read \field{max_cipher_key_len} to discover the 
maximum length of cipher key
+the device supports.

Does it mean it's OK for the driver (e.g. after a configuration change
notification to use a stale) \field{max_cipher_key_len} ) as it is SHOULD read
bit it's not OK to use a stale \field{max_dataqueues}?

AFAIU all configuration space stuff eligible for caching, but
under certain circumstances the cache invalidates and a re-read
is necessary.

> 
> Halil, could you try to split your comments between requirements
> for more conformance clauses/clarifications as opposed to
> defects where it's wrong and does not match actual or
> expected behaviour?

Yes. I'm already trying to tag my comments. 'This question is only
 about niceness. We are already good enough' was supposed to indicate
that this one is not requirement.

Do you mean putting these in separate emails?

> 
> I think spec is better off with some documentation for this
> device than none at all like today.
> 


If the rest community says it's good enough, I won't fight against
inclusion neither in the repo nor in the next Committee Specification.

I would %100 agree with you if this were normal documentation.
The problem with standards is that both correctness and completeness
are crucial. What is not part of the standard, is not part of the
standard and period.

Virtio is especially tricky as there is no versions of the standard.
What once was a compliant device/driver must be kept compliant when
we change the text. That is why this better something than nothing
does not entirely work for me.

Regards,
Halil




Re: [Qemu-devel] qemu master build failure

2018-03-16 Thread Christian Borntraeger
Does it make sense to have something like

diff --git a/configure b/configure
index 831ebf2..67d7ae3 100755
--- a/configure
+++ b/configure
@@ -552,6 +552,10 @@ else
 pwd_is_source_path="n"
 fi
 
+if test -f $source_path\/qemu-version.h -a $pwd_is_source_path = "n" ; then
+error_exit "source path contains a stale configuration, cannot build outside" 
+fi
+
 check_define() {
 cat > $TMPC < On 16/03/2018 18:01, Andrew Jones wrote:
>> Hi Thomas,
>>
>> QEMU master is failing to build on an AArch64 machine with GCC 4.8. I get
>>
>>   ...
>>   CC  qemu-nbd.o
>> /home/drjones/code/qemu/qemu-nbd.c: In function ‘version’:
>> /home/drjones/code/qemu/qemu-nbd.c:133:7: error: expected ‘)’ before 
>> ‘QEMU_FULL_VERSION’
>>  "%s " QEMU_FULL_VERSION "\n"
>>^
>> /home/drjones/code/qemu/qemu-nbd.c:139:5: error: format ‘%s’ expects a 
>> matching ‘char *’ argument [-Werror=format=]
>>  , name);
>>  ^
>> cc1: all warnings being treated as errors
>> make: *** [qemu-nbd.o] Error 1
>>
>>
>> Reverting 7e563bfb8 fixes the build. I figured I'd report it now,
>> but I won't have time to look closer until Monday.
> 
> You probably have a stray qemu-version.h file somewhere.  No worries, I
> was puzzled by the same thing after I applied Thomas's patch. :)
> 
> Paolo
> 




Re: [Qemu-devel] [PULL v2 0/3] tcg queued patches

2018-03-16 Thread Peter Maydell
On 15 March 2018 at 17:38, Richard Henderson
<richard.hender...@linaro.org> wrote:
> Ho hum, I rushed v1 before leaving on holidays and failed to format
> the cover letter properly, so Peter's scripts did not pick it up.
>
> Patches 2 & 3 are real bug fixes and so still appropriate for the
> softfreeze.  Patch 1 is trivial enough I didn't feel it needed to
> be held back for 2.13 development.  Let me know if you disagree.
>
>
> r~
>
>
> The following changes since commit 56e8698ffa8aba9f762f980bc21b5340b006f24b:
>
>   Merge remote-tracking branch 
> 'remotes/stsquad/tags/pull-travis-speedup-130318-1' into staging (2018-03-15 
> 14:48:09 +)
>
> are available in the Git repository at:
>
>   git://github.com/rth7680/qemu.git tags/pull-tcg-20180316
>
> for you to fetch changes up to adb196cbd5cff26547bc32a208074f03f4c4a627:
>
>   tcg: Add choose_vector_size (2018-03-16 00:55:04 +0800)
>
> 
> Queued TCG patches
>
> 
> Richard Henderson (3):
>   tcg: Improve tcg_gen_muli_i32/i64
>   tcg/i386: Support INDEX_op_dup2_vec for -m32
>   tcg: Add choose_vector_size

Applied, thanks.

-- PMM



Re: [Qemu-devel] [RFC v11 00/15] mutifd

2018-03-16 Thread Daniel P . Berrangé
On Fri, Mar 16, 2018 at 12:53:48PM +0100, Juan Quintela wrote:
> Multifd
> 
> 
> Hi
> 
> [v11]
> 
> Changes on top of previous sumbimission:
> - Now on top of migration-tests/v6 that I sent on Wednesday
> - Rebased to latest upstream
> - Everything that is sent through the network should be converted correctly
>   (famous last words)
> - Still on RFC (sometimes it ends some packets at the end), just to
>   show how things are going on.  Problems are only on the last patch.
> 
> - Redo some locking (again) Now the problem is being able te send the
>   synchronization through the multifd channels.  I end the migration
>   _before_ all the channels have recevied all the packets.
> 
> - Trying to get a flags argument into each packet, to be able to synchronze
>   through the network, not from the "main" incoming corroutine.
> 
> - Related to the network-safe fields, now everything is in its own
>   routine, it should be easier to understand/review.  Once there, I
>   check that all values are inside range.
> 
> So, please comment.

Just a few very minor things I've noticed. No more comments from me,
i'll defer to someone else for understanding of the actual RAM page
handling patches


Regards,
Daniel
-- 
|: https://berrange.com  -o-https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o-https://fstop138.berrange.com :|
|: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|



Re: [Qemu-devel] [PATCH v11 12/15] migration: Transmit initial package through the multifd channels

2018-03-16 Thread Daniel P . Berrangé
On Fri, Mar 16, 2018 at 12:54:00PM +0100, Juan Quintela wrote:
> Signed-off-by: Juan Quintela 
> 
> --
> 
> Be network agnostic.
> Add error checking for all values.
> ---
>  migration/ram.c | 97 
> ++---
>  1 file changed, 92 insertions(+), 5 deletions(-)
> 


> +static int multifd_recv_initial_packet(QIOChannel *c, Error **errp)
> +{
> +MultiFDInit_t msg;
> +int ret;
> +
> +ret = qio_channel_read_all(c, (char *), sizeof(msg), errp);
> +if (ret != 0) {
> +return -1;
> +}
> +
> +be32_to_cpus();
> +be32_to_cpus();
> +
> +if (msg.magic != MULTIFD_MAGIC) {
> +error_setg(errp, "multifd: recevied packet magic %d "

s/recevied/received/

and in few places below too

> +   "expected %d", msg.magic, MULTIFD_MAGIC);
> +return -1;
> +}
> +
> +if (msg.version != MULTIFD_VERSION) {
> +error_setg(errp, "multifd: recevied packet version %d "
> +   "expected %d", msg.version, MULTIFD_VERSION);
> +return -1;
> +}
> +
> +if (memcmp(msg.uuid, _uuid, sizeof(qemu_uuid))) {
> +char *uuid = qemu_uuid_unparse_strdup(_uuid);
> +error_setg(errp, "multifd: received uuid '%s' and expected "
> +   "uuid '%s' for channel %hhd", msg.uuid, uuid, msg.id);
> +g_free(uuid);
> +return -1;
> +}
> +
> +if (msg.id > migrate_multifd_channels()) {
> +error_setg(errp, "multifd: recevied channel version %d "
> +   "expected %d", msg.version, MULTIFD_VERSION);
> +return -1;
> +}
> +
> +return msg.id;
> +}

Reviewed-by: Daniel P. Berrangé 


Regards,
Daniel
-- 
|: https://berrange.com  -o-https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o-https://fstop138.berrange.com :|
|: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|



Re: [Qemu-devel] [PATCH v11 11/15] migration: Delay start of migration main routines

2018-03-16 Thread Daniel P . Berrangé
On Fri, Mar 16, 2018 at 12:53:59PM +0100, Juan Quintela wrote:
> We need to make sure that we have started all the multifd threads.
> 
> Signed-off-by: Juan Quintela 
> ---
>  migration/migration.c | 4 ++--
>  migration/migration.h | 1 +
>  migration/ram.c   | 3 +++
>  migration/socket.c| 3 +++
>  4 files changed, 9 insertions(+), 2 deletions(-)

Reviewed-by: Daniel P. Berrangé 


Regards,
Daniel
-- 
|: https://berrange.com  -o-https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o-https://fstop138.berrange.com :|
|: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|



Re: [Qemu-devel] [PATCH v4 2/5] target/i386: Populate AMD Processor Cache Information

2018-03-16 Thread Eduardo Habkost
On Mon, Mar 12, 2018 at 05:00:46PM -0400, Babu Moger wrote:
> From: Stanislav Lanci 
> 
> Add information for cpuid 0x801D leaf. Populate cache topology information
> for different cache types(Data Cache, Instruction Cache, L2 and L3) supported
> by 0x801D leaf. Please refer Processor Programming Reference (PPR) for AMD
> Family 17h Model for more details.
> 
> Signed-off-by: Stanislav Lanci 
> Signed-off-by: Babu Moger 

The new CPUID leaves don't seem to match the existing AMD cache information
leaves.  Is this intentional?  Why?

Details below:

> ---
>  target/i386/cpu.c | 65 
> +++
>  target/i386/kvm.c | 29 ++---
>  2 files changed, 91 insertions(+), 3 deletions(-)
> 
> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> index 42dd381..5fdbedd 100644
> --- a/target/i386/cpu.c
> +++ b/target/i386/cpu.c
[...]
> @@ -3590,6 +3594,67 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, 
> uint32_t count,
>  *edx = 0;
>  }
>  break;
> +case 0x801D: /* AMD TOPOEXT cache info */
> +switch (count) {

Copying macro definitions here, for reference:

> /* L1 data cache: */
> #define L1D_LINE_SIZE 64
> #define L1D_ASSOCIATIVITY  8
> #define L1D_SETS  64
> #define L1D_PARTITIONS 1
> /* Size = LINE_SIZE*ASSOCIATIVITY*SETS*PARTITIONS = 32KiB */
> #define L1D_DESCRIPTOR CPUID_2_L1D_32KB_8WAY_64B
> /*FIXME: CPUID leaf 0x8005 is inconsistent with leaves 2 & 4 */
> #define L1D_LINES_PER_TAG  1
> #define L1D_SIZE_KB_AMD   64
> #define L1D_ASSOCIATIVITY_AMD  2

So, we already have:

CPUID[2]: 32KB 8-way cache, 64-byte lines
CPUID[4]: 8-way cache, 64-byte lines, 64 sets, 1 partition (32 KB)
CPUID[0x8005]: 64 KB 2-way cache, 1 line per tag


> +case 0: /* L1 dcache info */
> +*eax |= TYPE_DCACHE | \
> +CACHE_LEVEL(1) | \
> +CACHE_SELF_INIT_LEVEL | \
> +((cs->nr_threads - 1) << 14);
> +*ebx = (L1D_LINE_SIZE - 1) | \
> +   ((L1D_PARTITIONS - 1) << 12) | \
> +   ((L1D_ASSOCIATIVITY - 1) << 22);
> +*ecx = L1D_SETS - 1;
> +*edx = 0;
> +break;

This adds:
CPUID[0x801D]: 8-way cache, 64-byte lines, 64 sets, 1 partition (32 KiB)

This agrees with CPUID[2] and CPUID[4] (Intel leaves, reserved on AMD), but not
with CPUID[0x8005].

>  
>  /* L1 instruction cache: */
>  #define L1I_LINE_SIZE 64
>  #define L1I_ASSOCIATIVITY  8
>  #define L1I_SETS  64
> +#define L1I_SETS_AMD 256
>  #define L1I_PARTITIONS 1
>  /* Size = LINE_SIZE*ASSOCIATIVITY*SETS*PARTITIONS = 32KiB */
>  #define L1I_DESCRIPTOR CPUID_2_L1I_32KB_8WAY_64B
>  /*FIXME: CPUID leaf 0x8005 is inconsistent with leaves 2 & 4 */
>  #define L1I_LINES_PER_TAG  1
>  #define L1I_SIZE_KB_AMD   64
>  #define L1I_ASSOCIATIVITY_AMD  2

Currently we have:

CPUID[2]: 32KiB 8-way cache, 64-byte lines
CPUID[4]: 8-way cache, 64-byte lines, 64 sets, 1 partition (32 KiB)
CPUID[0x8005]: 64 KiB 2-way cache, 1 line per tag


>  
> +case 1: /* L1 icache info */
> +*eax |= TYPE_ICACHE | \
> +CACHE_LEVEL(1) | \
> +CACHE_SELF_INIT_LEVEL | \
> +((cs->nr_threads - 1) << 14);
> +*ebx = (L1I_LINE_SIZE - 1) | \
> +   ((L1I_PARTITIONS - 1) << 12) | \
> +   ((L1I_ASSOCIATIVITY_AMD - 1) << 22);
> +*ecx = L1I_SETS_AMD - 1;
> +*edx = 0;
> +break;

This adds:
CPUID[0x801D]: 2-way cache, 64-byte lines, 256 sets, 1 partition (32 KiB)

This doesn't match any of the existing leaves.


>  /* Level 2 unified cache: */
>  #define L2_LINE_SIZE  64
>  #define L2_ASSOCIATIVITY  16
> +#define L2_ASSOCIATIVITY_AMD   8
>  #define L2_SETS 4096
> +#define L2_SETS_AMD 1024
>  #define L2_PARTITIONS  1
>  /* Size = LINE_SIZE*ASSOCIATIVITY*SETS*PARTITIONS = 4MiB */
>  /*FIXME: CPUID leaf 2 descriptor is inconsistent with CPUID leaf 4 */
>  #define L2_DESCRIPTOR CPUID_2_L2_2MB_8WAY_64B
>  /*FIXME: CPUID leaf 0x8006 is inconsistent with leaves 2 & 4 */
>  #define L2_LINES_PER_TAG   1
>  #define L2_SIZE_KB_AMD   512

Currently we have:
CPUID[2]: 4MiB 8-way cache, 64-byte lines
CPUID[4]: 64-byte lines, 16-way, 1 partition, 4096 sets (4 MiB)
CPUID[0x8006]: 512 KiB, 16-way cache, 1 line per tag

>  
> +case 2: /* L2 cache info */
> +*eax |= TYPE_UNIFIED | \
> +CACHE_LEVEL(2) | \
> +CACHE_SELF_INIT_LEVEL | \
> +((cs->nr_threads - 1) << 14);
> +*ebx = (L2_LINE_SIZE - 1) | \
> +   ((L2_PARTITIONS - 1) << 12) | \
> +   ((L2_ASSOCIATIVITY_AMD - 1) << 22);

Re: [Qemu-devel] [PATCH v11 10/15] migration: Create multifd channels

2018-03-16 Thread Daniel P . Berrangé
On Fri, Mar 16, 2018 at 12:53:58PM +0100, Juan Quintela wrote:
> In both sides.  We still don't transmit anything through them.
> 
> Signed-off-by: Juan Quintela 
> ---
>  migration/ram.c | 50 --
>  1 file changed, 40 insertions(+), 10 deletions(-)

Reviewed-by: Daniel P. Berrangé 


Regards,
Daniel
-- 
|: https://berrange.com  -o-https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o-https://fstop138.berrange.com :|
|: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|



Re: [Qemu-devel] [PATCH v11 01/15] migration: Set error state in case of error

2018-03-16 Thread Daniel P . Berrangé
On Fri, Mar 16, 2018 at 05:49:07PM +, Daniel P. Berrangé wrote:
> On Fri, Mar 16, 2018 at 12:53:49PM +0100, Juan Quintela wrote:
> > Signed-off-by: Juan Quintela 
> > ---
> >  migration/ram.c | 20 
> >  1 file changed, 20 insertions(+)
> > 
> > diff --git a/migration/ram.c b/migration/ram.c
> > index 7266351fd0..1b8095a358 100644
> > --- a/migration/ram.c
> > +++ b/migration/ram.c
> > @@ -414,6 +414,16 @@ static void terminate_multifd_send_threads(Error *errp)
> >  {
> >  int i;
> >  
> > +if (errp) {
> > +MigrationState *s = migrate_get_current();
> > +migrate_set_error(s, errp);
> 
> This doesn't look quiet right. You're checking if 'errp' is a non-NULL,
> which just tells you if the caller wants to collect the error, not
> whether an error has happened. For the latter you need
> 
>   if (errp && *errp)
> 
> seems a little strange though for the caller to pass an error into this
> method for reporting.

Oh wait, I'm being mislead by the unusual parameter name.

An "errp" name should only ever be used for a "Error **", but we
only have an "Error *" here.

So just fix the parameter name to be "err" instead of "errp".


> > +if (s->state == MIGRATION_STATUS_SETUP ||
> > +s->state == MIGRATION_STATUS_ACTIVE) {
> > +migrate_set_state(>state, s->state,
> > +  MIGRATION_STATUS_FAILED);
> > +}
> > +}
> > +
> >  for (i = 0; i < multifd_send_state->count; i++) {
> >  MultiFDSendParams *p = _send_state->params[i];
> >  
> > @@ -514,6 +524,16 @@ static void terminate_multifd_recv_threads(Error *errp)

This parameter name needs fixing too.

These are actually a pre-existing problem in current GIT, so worth fixing
in a separate patch.

> >  {
> >  int i;
> >  
> > +if (errp) {
> > +MigrationState *s = migrate_get_current();
> > +migrate_set_error(s, errp);
> > +if (s->state == MIGRATION_STATUS_SETUP ||
> > +s->state == MIGRATION_STATUS_ACTIVE) {
> > +migrate_set_state(>state, s->state,
> > +  MIGRATION_STATUS_FAILED);
> > +}
> > +}
> > +
> >  for (i = 0; i < multifd_recv_state->count; i++) {
> >  MultiFDRecvParams *p = _recv_state->params[i];
> >  
> > -- 
> > 2.14.3
> > 
> > 
> 
> Regards,
> Daniel
> -- 
> |: https://berrange.com  -o-https://www.flickr.com/photos/dberrange :|
> |: https://libvirt.org -o-https://fstop138.berrange.com :|
> |: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|
> 

Regards,
Daniel
-- 
|: https://berrange.com  -o-https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o-https://fstop138.berrange.com :|
|: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|



Re: [Qemu-devel] [PATCH v11 05/15] migration: Be sure all recv channels are created

2018-03-16 Thread Daniel P . Berrangé
On Fri, Mar 16, 2018 at 12:53:53PM +0100, Juan Quintela wrote:
> We need them before we start migration.
> 
> Signed-off-by: Juan Quintela 
> ---
>  migration/migration.c |  6 +-
>  migration/ram.c   | 11 +++
>  migration/ram.h   |  1 +
>  3 files changed, 17 insertions(+), 1 deletion(-)

Reviewed-by: Daniel P. Berrangé 


Regards,
Daniel
-- 
|: https://berrange.com  -o-https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o-https://fstop138.berrange.com :|
|: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|



  1   2   3   >