From 04ad1bf68e22dd5de8249ffd4c4e5886d50f3f95 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 3 Dec 2018 16:32:19 +0100 Subject: [PATCH 01/76] vhost-user-test: use g_cond_broadcast MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit g_cond_signal is rarely the right thing to do, it works now because vhost-user-test only has two threads but it is not correct in general. Fix it before adding more calls. Reviewed-by: Marc-André Lureau Signed-off-by: Paolo Bonzini Message-Id: <1543851204-41186-7-git-send-email-pbonzini@redhat.com> --- tests/vhost-user-test.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/vhost-user-test.c b/tests/vhost-user-test.c index 84e50d84e71..9baaff4f24b 100644 --- a/tests/vhost-user-test.c +++ b/tests/vhost-user-test.c @@ -393,7 +393,7 @@ static void chr_read(void *opaque, const uint8_t *buf, int size) G_N_ELEMENTS(s->fds)); /* signal the test that it can continue */ - g_cond_signal(&s->data_cond); + g_cond_broadcast(&s->data_cond); break; case VHOST_USER_SET_VRING_KICK: @@ -419,7 +419,7 @@ static void chr_read(void *opaque, const uint8_t *buf, int size) p = (uint8_t *) &msg; qemu_chr_fe_write_all(chr, p, VHOST_USER_HDR_SIZE); - g_cond_signal(&s->data_cond); + g_cond_broadcast(&s->data_cond); break; case VHOST_USER_SET_VRING_BASE: From acca950ccded44277037ac765cf6d5003a3d43eb Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 3 Dec 2018 16:32:20 +0100 Subject: [PATCH 02/76] vhost-user-test: signal data_cond when s->rings changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This speeds up wait_for_rings_started, which currently is just waiting for the timeout before checking s->rings. Reviewed-by: Marc-André Lureau Signed-off-by: Paolo Bonzini Message-Id: <1543851204-41186-8-git-send-email-pbonzini@redhat.com> --- tests/vhost-user-test.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/vhost-user-test.c b/tests/vhost-user-test.c index 9baaff4f24b..8eb79437746 100644 --- a/tests/vhost-user-test.c +++ b/tests/vhost-user-test.c @@ -384,6 +384,7 @@ static void chr_read(void *opaque, const uint8_t *buf, int size) assert(msg.payload.state.index < s->queues * 2); s->rings &= ~(0x1ULL << msg.payload.state.index); + g_cond_broadcast(&s->data_cond); break; case VHOST_USER_SET_MEM_TABLE: @@ -425,6 +426,7 @@ static void chr_read(void *opaque, const uint8_t *buf, int size) case VHOST_USER_SET_VRING_BASE: assert(msg.payload.state.index < s->queues * 2); s->rings |= 0x1ULL << msg.payload.state.index; + g_cond_broadcast(&s->data_cond); break; case VHOST_USER_GET_QUEUE_NUM: From 5a583cc55531b1bac7f652b848a0884c808d953d Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 3 Dec 2018 16:32:22 +0100 Subject: [PATCH 03/76] vhost-user-test: support VHOST_USER_PROTOCOL_F_CROSS_ENDIAN MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This will be useful to run the qtest for ppc64 targets on (for example) x86_64 hosts. Reviewed-by: Marc-André Lureau Signed-off-by: Paolo Bonzini Reviewed-by: Thomas Huth Message-Id: <1543851204-41186-10-git-send-email-pbonzini@redhat.com> --- tests/vhost-user-test.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/vhost-user-test.c b/tests/vhost-user-test.c index 8eb79437746..a4f51b5e118 100644 --- a/tests/vhost-user-test.c +++ b/tests/vhost-user-test.c @@ -51,6 +51,7 @@ #define VHOST_USER_F_PROTOCOL_FEATURES 30 #define VHOST_USER_PROTOCOL_F_MQ 0 #define VHOST_USER_PROTOCOL_F_LOG_SHMFD 1 +#define VHOST_USER_PROTOCOL_F_CROSS_ENDIAN 6 #define VHOST_LOG_PAGE 0x1000 @@ -251,7 +252,7 @@ static void wait_for_fds(TestServer *s) static void read_guest_mem_server(TestServer *s) { - uint32_t *guest_mem; + uint8_t *guest_mem; int i, j; size_t size; @@ -278,8 +279,8 @@ static void read_guest_mem_server(TestServer *s) g_assert(guest_mem != MAP_FAILED); guest_mem += (s->memory.regions[i].mmap_offset / sizeof(*guest_mem)); - for (j = 0; j < 256; j++) { - uint32_t a = readl(s->memory.regions[i].guest_phys_addr + j*4); + for (j = 0; j < 1024; j++) { + uint32_t a = readb(s->memory.regions[i].guest_phys_addr + j); uint32_t b = guest_mem[j]; g_assert_cmpint(a, ==, b); @@ -367,6 +368,7 @@ static void chr_read(void *opaque, const uint8_t *buf, int size) msg.flags |= VHOST_USER_REPLY_MASK; msg.size = sizeof(m.payload.u64); msg.payload.u64 = 1 << VHOST_USER_PROTOCOL_F_LOG_SHMFD; + msg.payload.u64 |= 1 << VHOST_USER_PROTOCOL_F_CROSS_ENDIAN; if (s->queues > 1) { msg.payload.u64 |= 1 << VHOST_USER_PROTOCOL_F_MQ; } From 3b72ca381f22393a564b6a8f3b831a3dd0a88d65 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 3 Dec 2018 16:32:23 +0100 Subject: [PATCH 04/76] vhost-user-test: skip if there is no memory at address 0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The virt machine cannot run the vhost-user qtests because they hardcode the presence of memory at address 0. Report the tests as a skip so that they can be converted to use qgraph. Reviewed-by: Marc-André Lureau Signed-off-by: Paolo Bonzini Message-Id: <1543851204-41186-11-git-send-email-pbonzini@redhat.com> --- tests/vhost-user-test.c | 58 ++++++++++++++++++++++++++++++++--------- 1 file changed, 45 insertions(+), 13 deletions(-) diff --git a/tests/vhost-user-test.c b/tests/vhost-user-test.c index a4f51b5e118..a0da5c320a8 100644 --- a/tests/vhost-user-test.c +++ b/tests/vhost-user-test.c @@ -228,9 +228,11 @@ static void uninit_virtio_dev(TestServer *s) qvirtio_pci_device_free(s->dev); } -static void wait_for_fds(TestServer *s) +static bool wait_for_fds(TestServer *s) { gint64 end_time; + bool got_region; + int i; g_mutex_lock(&s->data_mutex); @@ -248,6 +250,19 @@ static void wait_for_fds(TestServer *s) g_assert_cmpint(s->fds_num, ==, s->memory.nregions); g_mutex_unlock(&s->data_mutex); + + got_region = false; + for (i = 0; i < s->memory.nregions; ++i) { + VhostUserMemoryRegion *reg = &s->memory.regions[i]; + if (reg->guest_phys_addr == 0) { + got_region = true; + break; + } + } + if (!got_region) { + g_test_skip("No memory at address 0x0"); + } + return got_region; } static void read_guest_mem_server(TestServer *s) @@ -256,8 +271,6 @@ static void read_guest_mem_server(TestServer *s) int i, j; size_t size; - wait_for_fds(s); - g_mutex_lock(&s->data_mutex); /* iterate all regions */ @@ -577,8 +590,6 @@ static void write_guest_mem(TestServer *s, uint32_t seed) int i, j; size_t size; - wait_for_fds(s); - /* iterate all regions */ for (i = 0; i < s->fds_num; i++) { @@ -661,8 +672,13 @@ static void test_read_guest_mem(const void *arg) init_virtio_dev(server, 1u << VIRTIO_NET_F_MAC); + if (!wait_for_fds(server)) { + goto exit; + } + read_guest_mem_server(server); +exit: uninit_virtio_dev(server); qtest_quit(s); @@ -689,8 +705,10 @@ static void test_migrate(void) g_free(cmd); init_virtio_dev(s, 1u << VIRTIO_NET_F_MAC); - init_virtio_dev(dest, 1u << VIRTIO_NET_F_MAC); - wait_for_fds(s); + if (!wait_for_fds(s)) { + goto exit; + } + size = get_log_size(s); g_assert_cmpint(size, ==, (2 * 1024 * 1024) / (VHOST_LOG_PAGE * 8)); @@ -699,6 +717,7 @@ static void test_migrate(void) g_free(tmp); to = qtest_init(cmd); g_free(cmd); + init_virtio_dev(dest, 1u << VIRTIO_NET_F_MAC); source = g_source_new(&test_migrate_source_funcs, sizeof(TestMigrateSource)); @@ -738,15 +757,18 @@ static void test_migrate(void) global_qtest = to; qmp_eventwait("RESUME"); + g_assert(wait_for_fds(s)); read_guest_mem_server(dest); - uninit_virtio_dev(s); uninit_virtio_dev(dest); + qtest_quit(to); g_source_destroy(source); g_source_unref(source); - qtest_quit(to); +exit: + uninit_virtio_dev(s); + test_server_free(dest); qtest_quit(from); test_server_free(s); @@ -810,16 +832,20 @@ static void test_reconnect_subprocess(void) g_free(cmd); init_virtio_dev(s, 1u << VIRTIO_NET_F_MAC); - wait_for_fds(s); + if (!wait_for_fds(s)) { + goto exit; + } + wait_for_rings_started(s, 2); /* reconnect */ s->fds_num = 0; s->rings = 0; g_idle_add(reconnect_cb, s); - wait_for_fds(s); + g_assert(wait_for_fds(s)); wait_for_rings_started(s, 2); +exit: uninit_virtio_dev(s); qtest_end(); @@ -848,9 +874,12 @@ static void test_connect_fail_subprocess(void) g_free(cmd); init_virtio_dev(s, 1u << VIRTIO_NET_F_MAC); - wait_for_fds(s); + if (!wait_for_fds(s)) { + goto exit; + } wait_for_rings_started(s, 2); +exit: uninit_virtio_dev(s); qtest_end(); @@ -878,9 +907,12 @@ static void test_flags_mismatch_subprocess(void) g_free(cmd); init_virtio_dev(s, 1u << VIRTIO_NET_F_MAC); - wait_for_fds(s); + if (!wait_for_fds(s)) { + goto exit; + } wait_for_rings_started(s, 2); +exit: uninit_virtio_dev(s); qtest_end(); From bae6b59d46f9cb5e8a4f4cc07c5b2528b198b06b Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 3 Dec 2018 16:32:24 +0100 Subject: [PATCH 05/76] vhost-user-test: reduce usage of global_qtest MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Whenever the code can run on multiple QTestStates, use them explicitly instead of global_qtest. Reviewed-by: Marc-André Lureau Signed-off-by: Paolo Bonzini Reviewed-by: Thomas Huth Message-Id: <1543851204-41186-12-git-send-email-pbonzini@redhat.com> --- tests/vhost-user-test.c | 38 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/tests/vhost-user-test.c b/tests/vhost-user-test.c index a0da5c320a8..7d5f2346468 100644 --- a/tests/vhost-user-test.c +++ b/tests/vhost-user-test.c @@ -187,12 +187,12 @@ static char *get_qemu_cmd(TestServer *s, } } -static void init_virtio_dev(TestServer *s, uint32_t features_mask) +static void init_virtio_dev(QTestState *qts, TestServer *s, uint32_t features_mask) { uint32_t features; int i; - s->bus = qpci_init_pc(global_qtest, NULL); + s->bus = qpci_init_pc(qts, NULL); g_assert_nonnull(s->bus); s->dev = qvirtio_pci_device_find(s->bus, VIRTIO_ID_NET); @@ -203,7 +203,7 @@ static void init_virtio_dev(TestServer *s, uint32_t features_mask) qvirtio_set_acknowledge(&s->dev->vdev); qvirtio_set_driver(&s->dev->vdev); - s->alloc = pc_alloc_init(global_qtest); + s->alloc = pc_alloc_init(qts); for (i = 0; i < s->queues * 2; i++) { s->vq[i] = qvirtqueue_setup(&s->dev->vdev, s->alloc, i); @@ -265,7 +265,7 @@ static bool wait_for_fds(TestServer *s) return got_region; } -static void read_guest_mem_server(TestServer *s) +static void read_guest_mem_server(QTestState *qts, TestServer *s) { uint8_t *guest_mem; int i, j; @@ -293,7 +293,7 @@ static void read_guest_mem_server(TestServer *s) guest_mem += (s->memory.regions[i].mmap_offset / sizeof(*guest_mem)); for (j = 0; j < 1024; j++) { - uint32_t a = readb(s->memory.regions[i].guest_phys_addr + j); + uint32_t a = qtest_readb(qts, s->memory.regions[i].guest_phys_addr + j); uint32_t b = guest_mem[j]; g_assert_cmpint(a, ==, b); @@ -670,13 +670,13 @@ static void test_read_guest_mem(const void *arg) s = qtest_start(qemu_cmd); g_free(qemu_cmd); - init_virtio_dev(server, 1u << VIRTIO_NET_F_MAC); + init_virtio_dev(global_qtest, server, 1u << VIRTIO_NET_F_MAC); if (!wait_for_fds(server)) { goto exit; } - read_guest_mem_server(server); + read_guest_mem_server(global_qtest, server); exit: uninit_virtio_dev(server); @@ -690,7 +690,7 @@ static void test_migrate(void) TestServer *s = test_server_new("src"); TestServer *dest = test_server_new("dest"); char *uri = g_strdup_printf("%s%s", "unix:", dest->mig_path); - QTestState *global = global_qtest, *from, *to; + QTestState *from, *to; GSource *source; gchar *cmd, *tmp; QDict *rsp; @@ -704,7 +704,7 @@ static void test_migrate(void) from = qtest_start(cmd); g_free(cmd); - init_virtio_dev(s, 1u << VIRTIO_NET_F_MAC); + init_virtio_dev(from, s, 1u << VIRTIO_NET_F_MAC); if (!wait_for_fds(s)) { goto exit; } @@ -717,7 +717,7 @@ static void test_migrate(void) g_free(tmp); to = qtest_init(cmd); g_free(cmd); - init_virtio_dev(dest, 1u << VIRTIO_NET_F_MAC); + init_virtio_dev(to, dest, 1u << VIRTIO_NET_F_MAC); source = g_source_new(&test_migrate_source_funcs, sizeof(TestMigrateSource)); @@ -753,12 +753,10 @@ static void test_migrate(void) qobject_unref(rsp); qmp_eventwait("STOP"); + qtest_qmp_eventwait(to, "RESUME"); - global_qtest = to; - qmp_eventwait("RESUME"); - - g_assert(wait_for_fds(s)); - read_guest_mem_server(dest); + g_assert(wait_for_fds(dest)); + read_guest_mem_server(to, dest); uninit_virtio_dev(dest); qtest_quit(to); @@ -773,8 +771,6 @@ static void test_migrate(void) qtest_quit(from); test_server_free(s); g_free(uri); - - global_qtest = global; } static void wait_for_rings_started(TestServer *s, size_t count) @@ -831,7 +827,7 @@ static void test_reconnect_subprocess(void) qtest_start(cmd); g_free(cmd); - init_virtio_dev(s, 1u << VIRTIO_NET_F_MAC); + init_virtio_dev(global_qtest, s, 1u << VIRTIO_NET_F_MAC); if (!wait_for_fds(s)) { goto exit; } @@ -873,7 +869,7 @@ static void test_connect_fail_subprocess(void) qtest_start(cmd); g_free(cmd); - init_virtio_dev(s, 1u << VIRTIO_NET_F_MAC); + init_virtio_dev(global_qtest, s, 1u << VIRTIO_NET_F_MAC); if (!wait_for_fds(s)) { goto exit; } @@ -906,7 +902,7 @@ static void test_flags_mismatch_subprocess(void) qtest_start(cmd); g_free(cmd); - init_virtio_dev(s, 1u << VIRTIO_NET_F_MAC); + init_virtio_dev(global_qtest, s, 1u << VIRTIO_NET_F_MAC); if (!wait_for_fds(s)) { goto exit; } @@ -957,7 +953,7 @@ static void test_multiqueue(void) qtest_start(cmd); g_free(cmd); - init_virtio_dev(s, features_mask); + init_virtio_dev(global_qtest, s, features_mask); wait_for_rings_started(s, s->queues * 2); From 2a11ee1019530a917fff43182a1ef19a0d701018 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 15 Jan 2019 18:55:36 +0100 Subject: [PATCH 06/76] tap: flush STDOUT on newline This makes it easier to follow what is going on. Signed-off-by: Paolo Bonzini --- scripts/tap-driver.pl | 1 + scripts/tap-merge.pl | 1 + 2 files changed, 2 insertions(+) diff --git a/scripts/tap-driver.pl b/scripts/tap-driver.pl index 5e59b5db49c..6621a5cd671 100755 --- a/scripts/tap-driver.pl +++ b/scripts/tap-driver.pl @@ -313,6 +313,7 @@ () my $iterator = TAP::Parser::Iterator::Stream->new(\*STDIN); my $parser = TAP::Parser->new ({iterator => $iterator }); + STDOUT->autoflush(1); while (defined (my $cur = $parser->next)) { # Parsing of TAP input should stop after a "Bail out!" directive. diff --git a/scripts/tap-merge.pl b/scripts/tap-merge.pl index 59e3fa5007c..10ccf57bb2e 100755 --- a/scripts/tap-merge.pl +++ b/scripts/tap-merge.pl @@ -53,6 +53,7 @@ () my $testno = 0; # Number of test results seen so far. my $bailed_out = 0; # Whether a "Bail out!" directive has been seen. + STDOUT->autoflush(1); while (defined (my $cur = $parser->next)) { if ($cur->is_bailout) From 8fd3a9b81d29abf16f9cadfdcb55dd3a229ab12a Mon Sep 17 00:00:00 2001 From: "Emilio G. Cota" Date: Tue, 15 Jan 2019 14:47:53 -0500 Subject: [PATCH 07/76] cpu-exec: add assert_no_pages_locked() after longjmp We forgot to add this check in faa9372c07 ("translate-all: introduce assert_no_pages_locked", 2018-06-15); we only added it after returning from a longjmp in cpu_exec_step_atomic. Fix it. Signed-off-by: Emilio G. Cota Reviewed-by: Richard Henderson Signed-off-by: Paolo Bonzini --- accel/tcg/cpu-exec.c | 1 + 1 file changed, 1 insertion(+) diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c index 7cf1292546f..49b3259f362 100644 --- a/accel/tcg/cpu-exec.c +++ b/accel/tcg/cpu-exec.c @@ -702,6 +702,7 @@ int cpu_exec(CPUState *cpu) if (qemu_mutex_iothread_locked()) { qemu_mutex_unlock_iothread(); } + assert_no_pages_locked(); } /* if an exception is pending, we execute it here */ From 6aaa24f9d494a46c0a5aa5c7202cf50b3a7075ef Mon Sep 17 00:00:00 2001 From: "Emilio G. Cota" Date: Tue, 15 Jan 2019 14:47:54 -0500 Subject: [PATCH 08/76] cpu-exec: reset BQL after longjmp in cpu_exec_step_atomic Just like we do in cpu_exec(). Reported-by: Max Filippov Tested-by: Max Filippov Signed-off-by: Emilio G. Cota Reviewed-by: Richard Henderson Signed-off-by: Paolo Bonzini --- accel/tcg/cpu-exec.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c index 49b3259f362..fab30af86f9 100644 --- a/accel/tcg/cpu-exec.c +++ b/accel/tcg/cpu-exec.c @@ -266,6 +266,9 @@ void cpu_exec_step_atomic(CPUState *cpu) #ifndef CONFIG_SOFTMMU tcg_debug_assert(!have_mmap_lock()); #endif + if (qemu_mutex_iothread_locked()) { + qemu_mutex_unlock_iothread(); + } assert_no_pages_locked(); } From d99e97e6912d90a55e9a92e004dd54513da2848a Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Thu, 17 Jan 2019 18:14:08 +0100 Subject: [PATCH 09/76] configure: Add a proper check for openpty() in libutil MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On Linux (and maybe some BSDs), we require libutil for the openpty() function. However, this library is not available on some other systems, so we currently use a fragile if-statement in the configure script to check whether we need the library or not. Unfortunately, we also hard-coded a "-lutil" in the tests/Makefile.include file, so this breaks the build on Solaris, for example (see buglink below). To fix the issue, add the "-lutil" to "libs_tools" in the configure script instead, then this gets properly propagated to the tests, too. And while we're at it, also replace the fragile if-statement in the confi- gure script with a proper link-check for the availability of this function. Buglink: https://bugs.launchpad.net/qemu/+bug/1777252 Signed-off-by: Thomas Huth Reviewed-by: Philippe Mathieu-Daudé Tested-by: Philippe Mathieu-Daudé Signed-off-by: Paolo Bonzini --- configure | 12 ++++++++++-- tests/Makefile.include | 4 ---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/configure b/configure index 3d89870d996..f6a51e07651 100755 --- a/configure +++ b/configure @@ -4612,9 +4612,17 @@ elif compile_prog "" "$pthread_lib -lrt" ; then libs_qga="$libs_qga -lrt" fi -if test "$darwin" != "yes" -a "$mingw32" != "yes" -a "$solaris" != yes -a \ - "$haiku" != "yes" ; then +# Check whether we need to link libutil for openpty() +cat > $TMPC << EOF +extern int openpty(int *am, int *as, char *name, void *termp, void *winp); +int main(void) { return openpty(0, 0, 0, 0, 0); } +EOF + +if ! compile_prog "" "" ; then + if compile_prog "" "-lutil" ; then libs_softmmu="-lutil $libs_softmmu" + libs_tools="-lutil $libs_tools" + fi fi ########################################## diff --git a/tests/Makefile.include b/tests/Makefile.include index 75ad9c0dd37..b39e989f72d 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -798,10 +798,6 @@ tests/migration/initrd-stress.img: tests/migration/stress$(EXESUF) rm $(INITRD_WORK_DIR)/init rmdir $(INITRD_WORK_DIR) -ifeq ($(CONFIG_POSIX),y) -LIBS += -lutil -endif - # QTest rules TARGETS=$(patsubst %-softmmu,%, $(filter %-softmmu,$(TARGET_DIRS))) From d455ebc4f827c14a29240db17931e170b6937c6c Mon Sep 17 00:00:00 2001 From: Laurent Vivier Date: Wed, 2 Jan 2019 15:16:03 +0100 Subject: [PATCH 10/76] cpus: ignore ESRCH in qemu_cpu_kick_thread() We can have a race condition between qemu_cpu_kick_thread() and qemu_kvm_cpu_thread_fn() when we hotunplug a CPU. In this case, qemu_cpu_kick_thread() can try to kick a thread that is exiting. pthread_kill() returns an error and qemu is stopped by an exit(1). qemu:qemu_cpu_kick_thread: No such process We can ignore safely this error. Signed-off-by: Laurent Vivier Signed-off-by: Paolo Bonzini --- cpus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpus.c b/cpus.c index b09b7027126..154daf57dcb 100644 --- a/cpus.c +++ b/cpus.c @@ -1778,7 +1778,7 @@ static void qemu_cpu_kick_thread(CPUState *cpu) } cpu->thread_kicked = true; err = pthread_kill(cpu->thread->thread, SIG_IPI); - if (err) { + if (err && err != ESRCH) { fprintf(stderr, "qemu:%s: %s", __func__, strerror(err)); exit(1); } From 4366e1db16a3ec7bf24171e5c7619c8ea038e43b Mon Sep 17 00:00:00 2001 From: Liam Merwick Date: Tue, 15 Jan 2019 12:18:03 +0000 Subject: [PATCH 11/76] elf: Add optional function ptr to load_elf() to parse ELF notes This patch adds an optional function pointer, 'elf_note_fn', to load_elf() which causes load_elf() to additionally parse any ELF program headers of type PT_NOTE and check to see if the ELF Note is of the type specified by the 'translate_opaque' arg. If a matching ELF Note is found then the specfied function pointer is called to process the ELF note. Passing a NULL function pointer results in ELF Notes being skipped. The first consumer of this functionality is the PVHboot support which needs to read the XEN_ELFNOTE_PHYS32_ENTRY ELF Note while loading the uncompressed kernel binary in order to discover the boot entry address for the x86/HVM direct boot ABI. Signed-off-by: Liam Merwick Signed-off-by: Paolo Bonzini --- hw/alpha/dp264.c | 4 ++-- hw/arm/armv7m.c | 3 ++- hw/arm/boot.c | 2 +- hw/core/generic-loader.c | 2 +- hw/core/loader.c | 24 ++++++++++++++++-------- hw/cris/boot.c | 3 ++- hw/hppa/machine.c | 6 +++--- hw/i386/multiboot.c | 2 +- hw/lm32/lm32_boards.c | 6 ++++-- hw/lm32/milkymist.c | 3 ++- hw/m68k/an5206.c | 2 +- hw/m68k/mcf5208.c | 2 +- hw/microblaze/boot.c | 7 ++++--- hw/mips/mips_fulong2e.c | 5 +++-- hw/mips/mips_malta.c | 5 +++-- hw/mips/mips_mipssim.c | 5 +++-- hw/mips/mips_r4k.c | 5 +++-- hw/moxie/moxiesim.c | 2 +- hw/nios2/boot.c | 7 ++++--- hw/openrisc/openrisc_sim.c | 2 +- hw/pci-host/prep.c | 2 +- hw/ppc/e500.c | 3 ++- hw/ppc/mac_newworld.c | 5 +++-- hw/ppc/mac_oldworld.c | 5 +++-- hw/ppc/ppc440_bamboo.c | 2 +- hw/ppc/sam460ex.c | 3 ++- hw/ppc/spapr.c | 7 ++++--- hw/ppc/virtex_ml507.c | 2 +- hw/riscv/sifive_e.c | 2 +- hw/riscv/sifive_u.c | 2 +- hw/riscv/spike.c | 2 +- hw/riscv/virt.c | 2 +- hw/s390x/ipl.c | 9 ++++++--- hw/sparc/leon3.c | 3 ++- hw/sparc/sun4m.c | 6 ++++-- hw/sparc64/sun4u.c | 4 ++-- hw/tricore/tricore_testboard.c | 2 +- hw/xtensa/sim.c | 12 ++++++++---- hw/xtensa/xtfpga.c | 2 +- include/hw/elf_ops.h | 2 ++ include/hw/loader.h | 9 ++++++++- 41 files changed, 113 insertions(+), 70 deletions(-) diff --git a/hw/alpha/dp264.c b/hw/alpha/dp264.c index dd62f2a4050..0347eb897c8 100644 --- a/hw/alpha/dp264.c +++ b/hw/alpha/dp264.c @@ -114,7 +114,7 @@ static void clipper_init(MachineState *machine) error_report("no palcode provided"); exit(1); } - size = load_elf(palcode_filename, cpu_alpha_superpage_to_phys, + size = load_elf(palcode_filename, NULL, cpu_alpha_superpage_to_phys, NULL, &palcode_entry, &palcode_low, &palcode_high, 0, EM_ALPHA, 0, 0); if (size < 0) { @@ -133,7 +133,7 @@ static void clipper_init(MachineState *machine) if (kernel_filename) { uint64_t param_offset; - size = load_elf(kernel_filename, cpu_alpha_superpage_to_phys, + size = load_elf(kernel_filename, NULL, cpu_alpha_superpage_to_phys, NULL, &kernel_entry, &kernel_low, &kernel_high, 0, EM_ALPHA, 0, 0); if (size < 0) { diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c index adae11e76ed..c4b2a9a1f5c 100644 --- a/hw/arm/armv7m.c +++ b/hw/arm/armv7m.c @@ -310,7 +310,8 @@ void armv7m_load_kernel(ARMCPU *cpu, const char *kernel_filename, int mem_size) as = cpu_get_address_space(cs, asidx); if (kernel_filename) { - image_size = load_elf_as(kernel_filename, NULL, NULL, &entry, &lowaddr, + image_size = load_elf_as(kernel_filename, NULL, NULL, NULL, + &entry, &lowaddr, NULL, big_endian, EM_ARM, 1, 0, as); if (image_size < 0) { image_size = load_image_targphys_as(kernel_filename, 0, diff --git a/hw/arm/boot.c b/hw/arm/boot.c index 05762d0fc1b..be25902c128 100644 --- a/hw/arm/boot.c +++ b/hw/arm/boot.c @@ -881,7 +881,7 @@ static int64_t arm_load_elf(struct arm_boot_info *info, uint64_t *pentry, } } - ret = load_elf_as(info->kernel_filename, NULL, NULL, + ret = load_elf_as(info->kernel_filename, NULL, NULL, NULL, pentry, lowaddr, highaddr, big_endian, elf_machine, 1, data_swab, as); if (ret <= 0) { diff --git a/hw/core/generic-loader.c b/hw/core/generic-loader.c index fbae05fb3b6..3695dd439cd 100644 --- a/hw/core/generic-loader.c +++ b/hw/core/generic-loader.c @@ -136,7 +136,7 @@ static void generic_loader_realize(DeviceState *dev, Error **errp) AddressSpace *as = s->cpu ? s->cpu->as : NULL; if (!s->force_raw) { - size = load_elf_as(s->file, NULL, NULL, &entry, NULL, NULL, + size = load_elf_as(s->file, NULL, NULL, NULL, &entry, NULL, NULL, big_endian, 0, 0, 0, as); if (size < 0) { diff --git a/hw/core/loader.c b/hw/core/loader.c index c4f62fe4277..3a000d576b3 100644 --- a/hw/core/loader.c +++ b/hw/core/loader.c @@ -396,37 +396,42 @@ void load_elf_hdr(const char *filename, void *hdr, bool *is64, Error **errp) } /* return < 0 if error, otherwise the number of bytes loaded in memory */ -int load_elf(const char *filename, uint64_t (*translate_fn)(void *, uint64_t), +int load_elf(const char *filename, + uint64_t (*elf_note_fn)(void *, void *, bool), + uint64_t (*translate_fn)(void *, uint64_t), void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr, uint64_t *highaddr, int big_endian, int elf_machine, int clear_lsb, int data_swab) { - return load_elf_as(filename, translate_fn, translate_opaque, pentry, - lowaddr, highaddr, big_endian, elf_machine, clear_lsb, - data_swab, NULL); + return load_elf_as(filename, elf_note_fn, translate_fn, translate_opaque, + pentry, lowaddr, highaddr, big_endian, elf_machine, + clear_lsb, data_swab, NULL); } /* return < 0 if error, otherwise the number of bytes loaded in memory */ int load_elf_as(const char *filename, + uint64_t (*elf_note_fn)(void *, void *, bool), uint64_t (*translate_fn)(void *, uint64_t), void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr, uint64_t *highaddr, int big_endian, int elf_machine, int clear_lsb, int data_swab, AddressSpace *as) { - return load_elf_ram(filename, translate_fn, translate_opaque, + return load_elf_ram(filename, elf_note_fn, translate_fn, translate_opaque, pentry, lowaddr, highaddr, big_endian, elf_machine, clear_lsb, data_swab, as, true); } /* return < 0 if error, otherwise the number of bytes loaded in memory */ int load_elf_ram(const char *filename, + uint64_t (*elf_note_fn)(void *, void *, bool), uint64_t (*translate_fn)(void *, uint64_t), void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr, uint64_t *highaddr, int big_endian, int elf_machine, int clear_lsb, int data_swab, AddressSpace *as, bool load_rom) { - return load_elf_ram_sym(filename, translate_fn, translate_opaque, + return load_elf_ram_sym(filename, elf_note_fn, + translate_fn, translate_opaque, pentry, lowaddr, highaddr, big_endian, elf_machine, clear_lsb, data_swab, as, load_rom, NULL); @@ -434,6 +439,7 @@ int load_elf_ram(const char *filename, /* return < 0 if error, otherwise the number of bytes loaded in memory */ int load_elf_ram_sym(const char *filename, + uint64_t (*elf_note_fn)(void *, void *, bool), uint64_t (*translate_fn)(void *, uint64_t), void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr, uint64_t *highaddr, int big_endian, @@ -476,11 +482,13 @@ int load_elf_ram_sym(const char *filename, lseek(fd, 0, SEEK_SET); if (e_ident[EI_CLASS] == ELFCLASS64) { - ret = load_elf64(filename, fd, translate_fn, translate_opaque, must_swab, + ret = load_elf64(filename, fd, elf_note_fn, + translate_fn, translate_opaque, must_swab, pentry, lowaddr, highaddr, elf_machine, clear_lsb, data_swab, as, load_rom, sym_cb); } else { - ret = load_elf32(filename, fd, translate_fn, translate_opaque, must_swab, + ret = load_elf32(filename, fd, elf_note_fn, + translate_fn, translate_opaque, must_swab, pentry, lowaddr, highaddr, elf_machine, clear_lsb, data_swab, as, load_rom, sym_cb); } diff --git a/hw/cris/boot.c b/hw/cris/boot.c index f896ed7f863..95cba2151b7 100644 --- a/hw/cris/boot.c +++ b/hw/cris/boot.c @@ -75,7 +75,8 @@ void cris_load_image(CRISCPU *cpu, struct cris_load_info *li) env->load_info = li; /* Boots a kernel elf binary, os/linux-2.6/vmlinux from the axis devboard SDK. */ - image_size = load_elf(li->image_filename, translate_kernel_address, NULL, + image_size = load_elf(li->image_filename, NULL, + translate_kernel_address, NULL, &entry, NULL, &high, 0, EM_CRIS, 0, 0); li->entry = entry; if (image_size < 0) { diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c index ac6dd7f6abd..d1b1d3caa40 100644 --- a/hw/hppa/machine.c +++ b/hw/hppa/machine.c @@ -135,8 +135,8 @@ static void machine_hppa_init(MachineState *machine) exit(1); } - size = load_elf(firmware_filename, NULL, - NULL, &firmware_entry, &firmware_low, &firmware_high, + size = load_elf(firmware_filename, NULL, NULL, NULL, + &firmware_entry, &firmware_low, &firmware_high, true, EM_PARISC, 0, 0); /* Unfortunately, load_elf sign-extends reading elf32. */ @@ -165,7 +165,7 @@ static void machine_hppa_init(MachineState *machine) /* Load kernel */ if (kernel_filename) { - size = load_elf(kernel_filename, &cpu_hppa_to_phys, + size = load_elf(kernel_filename, NULL, &cpu_hppa_to_phys, NULL, &kernel_entry, &kernel_low, &kernel_high, true, EM_PARISC, 0, 0); diff --git a/hw/i386/multiboot.c b/hw/i386/multiboot.c index 62340687e8e..a3e33fbe5e1 100644 --- a/hw/i386/multiboot.c +++ b/hw/i386/multiboot.c @@ -199,7 +199,7 @@ int load_multiboot(FWCfgState *fw_cfg, exit(1); } - kernel_size = load_elf(kernel_filename, NULL, NULL, &elf_entry, + kernel_size = load_elf(kernel_filename, NULL, NULL, NULL, &elf_entry, &elf_low, &elf_high, 0, I386_ELF_MACHINE, 0, 0); if (kernel_size < 0) { diff --git a/hw/lm32/lm32_boards.c b/hw/lm32/lm32_boards.c index fd8eccca14d..05157f8eab7 100644 --- a/hw/lm32/lm32_boards.c +++ b/hw/lm32/lm32_boards.c @@ -138,7 +138,8 @@ static void lm32_evr_init(MachineState *machine) uint64_t entry; int kernel_size; - kernel_size = load_elf(kernel_filename, NULL, NULL, &entry, NULL, NULL, + kernel_size = load_elf(kernel_filename, NULL, NULL, NULL, + &entry, NULL, NULL, 1, EM_LATTICEMICO32, 0, 0); reset_info->bootstrap_pc = entry; @@ -231,7 +232,8 @@ static void lm32_uclinux_init(MachineState *machine) uint64_t entry; int kernel_size; - kernel_size = load_elf(kernel_filename, NULL, NULL, &entry, NULL, NULL, + kernel_size = load_elf(kernel_filename, NULL, NULL, NULL, + &entry, NULL, NULL, 1, EM_LATTICEMICO32, 0, 0); reset_info->bootstrap_pc = entry; diff --git a/hw/lm32/milkymist.c b/hw/lm32/milkymist.c index 26a2398354f..b080cf1ca92 100644 --- a/hw/lm32/milkymist.c +++ b/hw/lm32/milkymist.c @@ -176,7 +176,8 @@ milkymist_init(MachineState *machine) uint64_t entry; /* Boots a kernel elf binary. */ - kernel_size = load_elf(kernel_filename, NULL, NULL, &entry, NULL, NULL, + kernel_size = load_elf(kernel_filename, NULL, NULL, NULL, + &entry, NULL, NULL, 1, EM_LATTICEMICO32, 0, 0); reset_info->bootstrap_pc = entry; diff --git a/hw/m68k/an5206.c b/hw/m68k/an5206.c index 5e067ea1c35..06e38032588 100644 --- a/hw/m68k/an5206.c +++ b/hw/m68k/an5206.c @@ -66,7 +66,7 @@ static void an5206_init(MachineState *machine) exit(1); } - kernel_size = load_elf(kernel_filename, NULL, NULL, &elf_entry, + kernel_size = load_elf(kernel_filename, NULL, NULL, NULL, &elf_entry, NULL, NULL, 1, EM_68K, 0, 0); entry = elf_entry; if (kernel_size < 0) { diff --git a/hw/m68k/mcf5208.c b/hw/m68k/mcf5208.c index 0f2245dd817..8531e07e5b5 100644 --- a/hw/m68k/mcf5208.c +++ b/hw/m68k/mcf5208.c @@ -294,7 +294,7 @@ static void mcf5208evb_init(MachineState *machine) exit(1); } - kernel_size = load_elf(kernel_filename, NULL, NULL, &elf_entry, + kernel_size = load_elf(kernel_filename, NULL, NULL, NULL, &elf_entry, NULL, NULL, 1, EM_68K, 0, 0); entry = elf_entry; if (kernel_size < 0) { diff --git a/hw/microblaze/boot.c b/hw/microblaze/boot.c index 489ab839b7c..a7af4c07048 100644 --- a/hw/microblaze/boot.c +++ b/hw/microblaze/boot.c @@ -142,13 +142,14 @@ void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr ddr_base, #endif /* Boots a kernel elf binary. */ - kernel_size = load_elf(kernel_filename, NULL, NULL, + kernel_size = load_elf(kernel_filename, NULL, NULL, NULL, &entry, &low, &high, big_endian, EM_MICROBLAZE, 0, 0); base32 = entry; if (base32 == 0xc0000000) { - kernel_size = load_elf(kernel_filename, translate_kernel_address, - NULL, &entry, NULL, NULL, + kernel_size = load_elf(kernel_filename, NULL, + translate_kernel_address, NULL, + &entry, NULL, NULL, big_endian, EM_MICROBLAZE, 0, 0); } /* Always boot into physical ram. */ diff --git a/hw/mips/mips_fulong2e.c b/hw/mips/mips_fulong2e.c index 42d09f6892b..02549d5c7ef 100644 --- a/hw/mips/mips_fulong2e.c +++ b/hw/mips/mips_fulong2e.c @@ -111,8 +111,9 @@ static int64_t load_kernel (CPUMIPSState *env) uint32_t *prom_buf; long prom_size; - kernel_size = load_elf(loaderparams.kernel_filename, cpu_mips_kseg0_to_phys, - NULL, (uint64_t *)&kernel_entry, + kernel_size = load_elf(loaderparams.kernel_filename, NULL, + cpu_mips_kseg0_to_phys, NULL, + (uint64_t *)&kernel_entry, (uint64_t *)&kernel_low, (uint64_t *)&kernel_high, 0, EM_MIPS, 1, 0); if (kernel_size < 0) { diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c index c1cf0fe12e9..74667766c27 100644 --- a/hw/mips/mips_malta.c +++ b/hw/mips/mips_malta.c @@ -1010,8 +1010,9 @@ static int64_t load_kernel (void) big_endian = 0; #endif - kernel_size = load_elf(loaderparams.kernel_filename, cpu_mips_kseg0_to_phys, - NULL, (uint64_t *)&kernel_entry, NULL, + kernel_size = load_elf(loaderparams.kernel_filename, NULL, + cpu_mips_kseg0_to_phys, NULL, + (uint64_t *)&kernel_entry, NULL, (uint64_t *)&kernel_high, big_endian, EM_MIPS, 1, 0); if (kernel_size < 0) { error_report("could not load kernel '%s': %s", diff --git a/hw/mips/mips_mipssim.c b/hw/mips/mips_mipssim.c index f665752a2fc..824abda6574 100644 --- a/hw/mips/mips_mipssim.c +++ b/hw/mips/mips_mipssim.c @@ -69,8 +69,9 @@ static int64_t load_kernel(void) big_endian = 0; #endif - kernel_size = load_elf(loaderparams.kernel_filename, cpu_mips_kseg0_to_phys, - NULL, (uint64_t *)&entry, NULL, + kernel_size = load_elf(loaderparams.kernel_filename, NULL, + cpu_mips_kseg0_to_phys, NULL, + (uint64_t *)&entry, NULL, (uint64_t *)&kernel_high, big_endian, EM_MIPS, 1, 0); if (kernel_size >= 0) { diff --git a/hw/mips/mips_r4k.c b/hw/mips/mips_r4k.c index 19224073947..a015a6d14ee 100644 --- a/hw/mips/mips_r4k.c +++ b/hw/mips/mips_r4k.c @@ -92,8 +92,9 @@ static int64_t load_kernel(void) #else big_endian = 0; #endif - kernel_size = load_elf(loaderparams.kernel_filename, cpu_mips_kseg0_to_phys, - NULL, (uint64_t *)&entry, NULL, + kernel_size = load_elf(loaderparams.kernel_filename, NULL, + cpu_mips_kseg0_to_phys, NULL, + (uint64_t *)&entry, NULL, (uint64_t *)&kernel_high, big_endian, EM_MIPS, 1, 0); if (kernel_size >= 0) { diff --git a/hw/moxie/moxiesim.c b/hw/moxie/moxiesim.c index c6b6f7262dc..eddeed915d3 100644 --- a/hw/moxie/moxiesim.c +++ b/hw/moxie/moxiesim.c @@ -57,7 +57,7 @@ static void load_kernel(MoxieCPU *cpu, LoaderParams *loader_params) long kernel_size; ram_addr_t initrd_offset; - kernel_size = load_elf(loader_params->kernel_filename, NULL, NULL, + kernel_size = load_elf(loader_params->kernel_filename, NULL, NULL, NULL, &entry, &kernel_low, &kernel_high, 1, EM_MOXIE, 0, 0); diff --git a/hw/nios2/boot.c b/hw/nios2/boot.c index ed5cb28e942..5f0ab2fbb9c 100644 --- a/hw/nios2/boot.c +++ b/hw/nios2/boot.c @@ -146,13 +146,14 @@ void nios2_load_kernel(Nios2CPU *cpu, hwaddr ddr_base, #endif /* Boots a kernel elf binary. */ - kernel_size = load_elf(kernel_filename, NULL, NULL, + kernel_size = load_elf(kernel_filename, NULL, NULL, NULL, &entry, &low, &high, big_endian, EM_ALTERA_NIOS2, 0, 0); base32 = entry; if (base32 == 0xc0000000) { - kernel_size = load_elf(kernel_filename, translate_kernel_address, - NULL, &entry, NULL, NULL, + kernel_size = load_elf(kernel_filename, NULL, + translate_kernel_address, NULL, + &entry, NULL, NULL, big_endian, EM_ALTERA_NIOS2, 0, 0); } diff --git a/hw/openrisc/openrisc_sim.c b/hw/openrisc/openrisc_sim.c index a495a84a41d..7d3b734d24f 100644 --- a/hw/openrisc/openrisc_sim.c +++ b/hw/openrisc/openrisc_sim.c @@ -96,7 +96,7 @@ static void openrisc_load_kernel(ram_addr_t ram_size, hwaddr entry; if (kernel_filename && !qtest_enabled()) { - kernel_size = load_elf(kernel_filename, NULL, NULL, + kernel_size = load_elf(kernel_filename, NULL, NULL, NULL, &elf_entry, NULL, NULL, 1, EM_OPENRISC, 1, 0); entry = elf_entry; diff --git a/hw/pci-host/prep.c b/hw/pci-host/prep.c index b1b6b16badb..8b9e1fd0d34 100644 --- a/hw/pci-host/prep.c +++ b/hw/pci-host/prep.c @@ -331,7 +331,7 @@ static void raven_realize(PCIDevice *d, Error **errp) filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, s->bios_name); if (filename) { if (s->elf_machine != EM_NONE) { - bios_size = load_elf(filename, NULL, NULL, NULL, + bios_size = load_elf(filename, NULL, NULL, NULL, NULL, NULL, NULL, 1, s->elf_machine, 0, 0); } if (bios_size < 0) { diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c index 0581e9e3d4c..7553f674c99 100644 --- a/hw/ppc/e500.c +++ b/hw/ppc/e500.c @@ -988,7 +988,8 @@ void ppce500_init(MachineState *machine) filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, payload_name); - payload_size = load_elf(filename, NULL, NULL, &bios_entry, &loadaddr, NULL, + payload_size = load_elf(filename, NULL, NULL, NULL, + &bios_entry, &loadaddr, NULL, 1, PPC_ELF_MACHINE, 0, 0); if (payload_size < 0) { /* diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c index f1c8400efd4..10be728c37d 100644 --- a/hw/ppc/mac_newworld.c +++ b/hw/ppc/mac_newworld.c @@ -164,7 +164,7 @@ static void ppc_core99_init(MachineState *machine) /* Load OpenBIOS (ELF) */ if (filename) { - bios_size = load_elf(filename, NULL, NULL, NULL, + bios_size = load_elf(filename, NULL, NULL, NULL, NULL, NULL, NULL, 1, PPC_ELF_MACHINE, 0, 0); g_free(filename); @@ -187,7 +187,8 @@ static void ppc_core99_init(MachineState *machine) #endif kernel_base = KERNEL_LOAD_ADDR; - kernel_size = load_elf(kernel_filename, translate_kernel_address, NULL, + kernel_size = load_elf(kernel_filename, NULL, + translate_kernel_address, NULL, NULL, &lowaddr, NULL, 1, PPC_ELF_MACHINE, 0, 0); if (kernel_size < 0) diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c index 98d531d1141..284431ddd68 100644 --- a/hw/ppc/mac_oldworld.c +++ b/hw/ppc/mac_oldworld.c @@ -139,7 +139,7 @@ static void ppc_heathrow_init(MachineState *machine) /* Load OpenBIOS (ELF) */ if (filename) { - bios_size = load_elf(filename, 0, NULL, NULL, NULL, NULL, + bios_size = load_elf(filename, NULL, 0, NULL, NULL, NULL, NULL, 1, PPC_ELF_MACHINE, 0, 0); g_free(filename); } else { @@ -160,7 +160,8 @@ static void ppc_heathrow_init(MachineState *machine) bswap_needed = 0; #endif kernel_base = KERNEL_LOAD_ADDR; - kernel_size = load_elf(kernel_filename, translate_kernel_address, NULL, + kernel_size = load_elf(kernel_filename, NULL, + translate_kernel_address, NULL, NULL, &lowaddr, NULL, 1, PPC_ELF_MACHINE, 0, 0); if (kernel_size < 0) diff --git a/hw/ppc/ppc440_bamboo.c b/hw/ppc/ppc440_bamboo.c index 4b547eaf77a..b4da099e3ea 100644 --- a/hw/ppc/ppc440_bamboo.c +++ b/hw/ppc/ppc440_bamboo.c @@ -256,7 +256,7 @@ static void bamboo_init(MachineState *machine) success = load_uimage(kernel_filename, &entry, &loadaddr, NULL, NULL, NULL); if (success < 0) { - success = load_elf(kernel_filename, NULL, NULL, &elf_entry, + success = load_elf(kernel_filename, NULL, NULL, NULL, &elf_entry, &elf_lowaddr, NULL, 1, PPC_ELF_MACHINE, 0, 0); entry = elf_entry; diff --git a/hw/ppc/sam460ex.c b/hw/ppc/sam460ex.c index 202ed14bcf7..75250d49e43 100644 --- a/hw/ppc/sam460ex.c +++ b/hw/ppc/sam460ex.c @@ -426,7 +426,8 @@ static void sam460ex_init(MachineState *machine) if (success < 0) { uint64_t elf_entry, elf_lowaddr; - success = load_elf(machine->kernel_filename, NULL, NULL, &elf_entry, + success = load_elf(machine->kernel_filename, NULL, + NULL, NULL, &elf_entry, &elf_lowaddr, NULL, 1, PPC_ELF_MACHINE, 0, 0); entry = elf_entry; loadaddr = elf_lowaddr; diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 0fcdd35cbe1..332cba89d42 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -2851,11 +2851,12 @@ static void spapr_machine_init(MachineState *machine) if (kernel_filename) { uint64_t lowaddr = 0; - spapr->kernel_size = load_elf(kernel_filename, translate_kernel_address, - NULL, NULL, &lowaddr, NULL, 1, + spapr->kernel_size = load_elf(kernel_filename, NULL, + translate_kernel_address, NULL, + NULL, &lowaddr, NULL, 1, PPC_ELF_MACHINE, 0, 0); if (spapr->kernel_size == ELF_LOAD_WRONG_ENDIAN) { - spapr->kernel_size = load_elf(kernel_filename, + spapr->kernel_size = load_elf(kernel_filename, NULL, translate_kernel_address, NULL, NULL, &lowaddr, NULL, 0, PPC_ELF_MACHINE, 0, 0); diff --git a/hw/ppc/virtex_ml507.c b/hw/ppc/virtex_ml507.c index 51771205743..5a711cb3d94 100644 --- a/hw/ppc/virtex_ml507.c +++ b/hw/ppc/virtex_ml507.c @@ -258,7 +258,7 @@ static void virtex_init(MachineState *machine) hwaddr boot_offset; /* Boots a kernel elf binary. */ - kernel_size = load_elf(kernel_filename, NULL, NULL, + kernel_size = load_elf(kernel_filename, NULL, NULL, NULL, &entry, &low, &high, 1, PPC_ELF_MACHINE, 0, 0); boot_info.bootstrap_pc = entry & 0x00ffffff; diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c index 5d9d65ff29a..bfc086609cb 100644 --- a/hw/riscv/sifive_e.c +++ b/hw/riscv/sifive_e.c @@ -78,7 +78,7 @@ static uint64_t load_kernel(const char *kernel_filename) { uint64_t kernel_entry, kernel_high; - if (load_elf(kernel_filename, NULL, NULL, + if (load_elf(kernel_filename, NULL, NULL, NULL, &kernel_entry, NULL, &kernel_high, 0, EM_RISCV, 1, 0) < 0) { error_report("could not load kernel '%s'", kernel_filename); diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c index 3bd3b67507f..2730b25b603 100644 --- a/hw/riscv/sifive_u.c +++ b/hw/riscv/sifive_u.c @@ -69,7 +69,7 @@ static uint64_t load_kernel(const char *kernel_filename) { uint64_t kernel_entry, kernel_high; - if (load_elf(kernel_filename, NULL, NULL, + if (load_elf(kernel_filename, NULL, NULL, NULL, &kernel_entry, NULL, &kernel_high, 0, EM_RISCV, 1, 0) < 0) { error_report("could not load kernel '%s'", kernel_filename); diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c index 268df04c3c7..c66ffc50cc7 100644 --- a/hw/riscv/spike.c +++ b/hw/riscv/spike.c @@ -57,7 +57,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, + if (load_elf_ram_sym(kernel_filename, NULL, NULL, NULL, &kernel_entry, NULL, &kernel_high, 0, EM_RISCV, 1, 0, NULL, true, htif_symbol_callback) < 0) { error_report("could not load kernel '%s'", kernel_filename); diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index e7f0716fb66..3e8b19c6689 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -66,7 +66,7 @@ static uint64_t load_kernel(const char *kernel_filename) { uint64_t kernel_entry, kernel_high; - if (load_elf(kernel_filename, NULL, NULL, + if (load_elf(kernel_filename, NULL, NULL, NULL, &kernel_entry, NULL, &kernel_high, 0, EM_RISCV, 1, 0) < 0) { error_report("could not load kernel '%s'", kernel_filename); diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c index 21f64ad26aa..896888bf8f0 100644 --- a/hw/s390x/ipl.c +++ b/hw/s390x/ipl.c @@ -131,7 +131,8 @@ static void s390_ipl_realize(DeviceState *dev, Error **errp) goto error; } - bios_size = load_elf(bios_filename, bios_translate_addr, &fwbase, + bios_size = load_elf(bios_filename, NULL, + bios_translate_addr, &fwbase, &ipl->bios_start_addr, NULL, NULL, 1, EM_S390, 0, 0); if (bios_size > 0) { @@ -155,7 +156,8 @@ static void s390_ipl_realize(DeviceState *dev, Error **errp) } if (ipl->kernel) { - kernel_size = load_elf(ipl->kernel, NULL, NULL, &pentry, NULL, + kernel_size = load_elf(ipl->kernel, NULL, NULL, NULL, + &pentry, NULL, NULL, 1, EM_S390, 0, 0); if (kernel_size < 0) { kernel_size = load_image_targphys(ipl->kernel, 0, ram_size); @@ -436,7 +438,8 @@ static int load_netboot_image(Error **errp) goto unref_mr; } - img_size = load_elf_ram(netboot_filename, NULL, NULL, &ipl->start_addr, + img_size = load_elf_ram(netboot_filename, NULL, NULL, NULL, + &ipl->start_addr, NULL, NULL, 1, EM_S390, 0, 0, NULL, false); if (img_size < 0) { diff --git a/hw/sparc/leon3.c b/hw/sparc/leon3.c index fa98ab81776..774639af339 100644 --- a/hw/sparc/leon3.c +++ b/hw/sparc/leon3.c @@ -190,7 +190,8 @@ static void leon3_generic_hw_init(MachineState *machine) long kernel_size; uint64_t entry; - kernel_size = load_elf(kernel_filename, NULL, NULL, &entry, NULL, NULL, + kernel_size = load_elf(kernel_filename, NULL, NULL, NULL, + &entry, NULL, NULL, 1 /* big endian */, EM_SPARC, 0, 0); if (kernel_size < 0) { error_report("could not load kernel '%s'", kernel_filename); diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c index 709ee37e08a..779f3f97d5d 100644 --- a/hw/sparc/sun4m.c +++ b/hw/sparc/sun4m.c @@ -242,7 +242,8 @@ static unsigned long sun4m_load_kernel(const char *kernel_filename, #else bswap_needed = 0; #endif - kernel_size = load_elf(kernel_filename, translate_kernel_address, NULL, + kernel_size = load_elf(kernel_filename, NULL, + translate_kernel_address, NULL, NULL, NULL, NULL, 1, EM_SPARC, 0, 0); if (kernel_size < 0) kernel_size = load_aout(kernel_filename, KERNEL_LOAD_ADDR, @@ -692,7 +693,8 @@ static void prom_init(hwaddr addr, const char *bios_name) } filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); if (filename) { - ret = load_elf(filename, translate_prom_address, &addr, NULL, + ret = load_elf(filename, NULL, + translate_prom_address, &addr, NULL, NULL, NULL, 1, EM_SPARC, 0, 0); if (ret < 0 || ret > PROM_SIZE_MAX) { ret = load_image_targphys(filename, addr, PROM_SIZE_MAX); diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c index f76b19e4e93..b9bd4be5d51 100644 --- a/hw/sparc64/sun4u.c +++ b/hw/sparc64/sun4u.c @@ -153,7 +153,7 @@ static uint64_t sun4u_load_kernel(const char *kernel_filename, #else bswap_needed = 0; #endif - kernel_size = load_elf(kernel_filename, NULL, NULL, kernel_entry, + kernel_size = load_elf(kernel_filename, NULL, NULL, NULL, kernel_entry, kernel_addr, &kernel_top, 1, EM_SPARCV9, 0, 0); if (kernel_size < 0) { *kernel_addr = KERNEL_LOAD_ADDR; @@ -411,7 +411,7 @@ static void prom_init(hwaddr addr, const char *bios_name) } filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); if (filename) { - ret = load_elf(filename, translate_prom_address, &addr, + ret = load_elf(filename, NULL, translate_prom_address, &addr, NULL, NULL, NULL, 1, EM_SPARCV9, 0, 0); if (ret < 0 || ret > PROM_SIZE_MAX) { ret = load_image_targphys(filename, addr, PROM_SIZE_MAX); diff --git a/hw/tricore/tricore_testboard.c b/hw/tricore/tricore_testboard.c index a58096f05e7..003592af27a 100644 --- a/hw/tricore/tricore_testboard.c +++ b/hw/tricore/tricore_testboard.c @@ -45,7 +45,7 @@ static void tricore_load_kernel(CPUTriCoreState *env) long kernel_size; kernel_size = load_elf(tricoretb_binfo.kernel_filename, NULL, - NULL, &entry, NULL, + NULL, NULL, &entry, NULL, NULL, 0, EM_TRICORE, 1, 0); if (kernel_size <= 0) { diff --git a/hw/xtensa/sim.c b/hw/xtensa/sim.c index b6ccb3cd4ae..12c7437398e 100644 --- a/hw/xtensa/sim.c +++ b/hw/xtensa/sim.c @@ -97,11 +97,15 @@ static void xtensa_sim_init(MachineState *machine) uint64_t elf_entry; uint64_t elf_lowaddr; #ifdef TARGET_WORDS_BIGENDIAN - int success = load_elf(kernel_filename, translate_phys_addr, cpu, - &elf_entry, &elf_lowaddr, NULL, 1, EM_XTENSA, 0, 0); + int success = load_elf(kernel_filename, NULL, + translate_phys_addr, cpu, + &elf_entry, &elf_lowaddr, + NULL, 1, EM_XTENSA, 0, 0); #else - int success = load_elf(kernel_filename, translate_phys_addr, cpu, - &elf_entry, &elf_lowaddr, NULL, 0, EM_XTENSA, 0, 0); + int success = load_elf(kernel_filename, NULL, + translate_phys_addr, cpu, + &elf_entry, &elf_lowaddr, + NULL, 0, EM_XTENSA, 0, 0); #endif if (success > 0) { env->pc = elf_entry; diff --git a/hw/xtensa/xtfpga.c b/hw/xtensa/xtfpga.c index 1d21162a277..ab3e52b4159 100644 --- a/hw/xtensa/xtfpga.c +++ b/hw/xtensa/xtfpga.c @@ -409,7 +409,7 @@ static void xtfpga_init(const XtfpgaBoardDesc *board, MachineState *machine) uint64_t elf_entry; uint64_t elf_lowaddr; - int success = load_elf(kernel_filename, translate_phys_addr, cpu, + int success = load_elf(kernel_filename, NULL, translate_phys_addr, cpu, &elf_entry, &elf_lowaddr, NULL, be, EM_XTENSA, 0, 0); if (success > 0) { entry_point = elf_entry; diff --git a/include/hw/elf_ops.h b/include/hw/elf_ops.h index e2cb6751955..3438d6f69e8 100644 --- a/include/hw/elf_ops.h +++ b/include/hw/elf_ops.h @@ -266,6 +266,7 @@ static int glue(elf_reloc, SZ)(struct elfhdr *ehdr, int fd, int must_swab, } static int glue(load_elf, SZ)(const char *name, int fd, + uint64_t (*elf_note_fn)(void *, void *, bool), uint64_t (*translate_fn)(void *, uint64_t), void *translate_opaque, int must_swab, uint64_t *pentry, @@ -498,6 +499,7 @@ static int glue(load_elf, SZ)(const char *name, int fd, data = NULL; } } + g_free(phdr); if (lowaddr) *lowaddr = (uint64_t)(elf_sword)low; diff --git a/include/hw/loader.h b/include/hw/loader.h index de8a29603b0..3e1b3a4566c 100644 --- a/include/hw/loader.h +++ b/include/hw/loader.h @@ -93,6 +93,8 @@ const char *load_elf_strerror(int error); /** load_elf_ram_sym: * @filename: Path of ELF file + * @elf_note_fn: optional function to parse ELF Note type + * passed via @translate_opaque * @translate_fn: optional function to translate load addresses * @translate_opaque: opaque data passed to @translate_fn * @pentry: Populated with program entry point. Ignored if NULL. @@ -125,6 +127,7 @@ typedef void (*symbol_fn_t)(const char *st_name, int st_info, uint64_t st_value, uint64_t st_size); int load_elf_ram_sym(const char *filename, + uint64_t (*elf_note_fn)(void *, void *, bool), uint64_t (*translate_fn)(void *, uint64_t), void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr, uint64_t *highaddr, int big_endian, @@ -136,6 +139,7 @@ int load_elf_ram_sym(const char *filename, * symbol callback function */ int load_elf_ram(const char *filename, + uint64_t (*elf_note_fn)(void *, void *, bool), uint64_t (*translate_fn)(void *, uint64_t), void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr, uint64_t *highaddr, int big_endian, int elf_machine, @@ -146,6 +150,7 @@ int load_elf_ram(const char *filename, * Same as load_elf_ram(), but always loads the elf as ROM */ int load_elf_as(const char *filename, + uint64_t (*elf_note_fn)(void *, void *, bool), uint64_t (*translate_fn)(void *, uint64_t), void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr, uint64_t *highaddr, int big_endian, int elf_machine, @@ -155,7 +160,9 @@ int load_elf_as(const char *filename, * Same as load_elf_as(), but doesn't allow the caller to specify an * AddressSpace. */ -int load_elf(const char *filename, uint64_t (*translate_fn)(void *, uint64_t), +int load_elf(const char *filename, + uint64_t (*elf_note_fn)(void *, void *, bool), + uint64_t (*translate_fn)(void *, uint64_t), void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr, uint64_t *highaddr, int big_endian, int elf_machine, int clear_lsb, int data_swab); From 696aa04c84c6065aa6c4b085d223a3129718d700 Mon Sep 17 00:00:00 2001 From: Liam Merwick Date: Tue, 15 Jan 2019 12:18:04 +0000 Subject: [PATCH 12/76] elf-ops.h: Add get_elf_note_type() Introduce a routine which, given a pointer to a range of ELF Notes, searches through them looking for a note matching the type specified and returns a pointer to the matching ELF note. get_elf_note_type() is used by elf_load[32|64]() to find the specified note type required by the 'elf_note_fn' parameter added in the previous commit. Signed-off-by: Liam Merwick Signed-off-by: Paolo Bonzini Signed-off-by: Liam Merwick --- include/hw/elf_ops.h | 75 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/include/hw/elf_ops.h b/include/hw/elf_ops.h index 3438d6f69e8..690f9238c8c 100644 --- a/include/hw/elf_ops.h +++ b/include/hw/elf_ops.h @@ -265,6 +265,51 @@ static int glue(elf_reloc, SZ)(struct elfhdr *ehdr, int fd, int must_swab, return ret; } +/* + * Given 'nhdr', a pointer to a range of ELF Notes, search through them + * for a note matching type 'elf_note_type' and return a pointer to + * the matching ELF note. + */ +static struct elf_note *glue(get_elf_note_type, SZ)(struct elf_note *nhdr, + elf_word note_size, + elf_word phdr_align, + elf_word elf_note_type) +{ + elf_word nhdr_size = sizeof(struct elf_note); + elf_word elf_note_entry_offset = 0; + elf_word note_type; + elf_word nhdr_namesz; + elf_word nhdr_descsz; + + if (nhdr == NULL) { + return NULL; + } + + note_type = nhdr->n_type; + while (note_type != elf_note_type) { + nhdr_namesz = nhdr->n_namesz; + nhdr_descsz = nhdr->n_descsz; + + elf_note_entry_offset = nhdr_size + + QEMU_ALIGN_UP(nhdr_namesz, phdr_align) + + QEMU_ALIGN_UP(nhdr_descsz, phdr_align); + + /* + * If the offset calculated in this iteration exceeds the + * supplied size, we are done and no matching note was found. + */ + if (elf_note_entry_offset > note_size) { + return NULL; + } + + /* skip to the next ELF Note entry */ + nhdr = (void *)nhdr + elf_note_entry_offset; + note_type = nhdr->n_type; + } + + return nhdr; +} + static int glue(load_elf, SZ)(const char *name, int fd, uint64_t (*elf_note_fn)(void *, void *, bool), uint64_t (*translate_fn)(void *, uint64_t), @@ -497,6 +542,36 @@ static int glue(load_elf, SZ)(const char *name, int fd, high = addr + mem_size; data = NULL; + + } else if (ph->p_type == PT_NOTE && elf_note_fn) { + struct elf_note *nhdr = NULL; + + file_size = ph->p_filesz; /* Size of the range of ELF notes */ + data = g_malloc0(file_size); + if (ph->p_filesz > 0) { + if (lseek(fd, ph->p_offset, SEEK_SET) < 0) { + goto fail; + } + if (read(fd, data, file_size) != file_size) { + goto fail; + } + } + + /* + * Search the ELF notes to find one with a type matching the + * value passed in via 'translate_opaque' + */ + nhdr = (struct elf_note *)data; + assert(translate_opaque != NULL); + nhdr = glue(get_elf_note_type, SZ)(nhdr, file_size, ph->p_align, + *(uint64_t *)translate_opaque); + if (nhdr != NULL) { + bool is64 = + sizeof(struct elf_note) == sizeof(struct elf64_note); + elf_note_fn((void *)nhdr, (void *)&ph->p_align, is64); + } + g_free(data); + data = NULL; } } From 20a965067fbece568d2dcb3ccaa603723731a9f9 Mon Sep 17 00:00:00 2001 From: Liam Merwick Date: Tue, 15 Jan 2019 12:18:05 +0000 Subject: [PATCH 13/76] pvh: Add x86/HVM direct boot ABI header file The x86/HVM direct boot ABI permits Qemu to be able to boot directly into the uncompressed Linux kernel binary with minimal firmware involvement. https://xenbits.xen.org/docs/unstable/misc/pvh.html This commit adds the header file that defines the start_info struct that needs to be populated in order to use this ABI. The canonical version of start_info.h is in the Xen codebase. (like QEMU, the Linux kernel uses a copy as well). Signed-off-by: Liam Merwick Reviewed-by: Konrad Rzeszutek Wilk Signed-off-by: Paolo Bonzini --- include/hw/xen/start_info.h | 146 ++++++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 include/hw/xen/start_info.h diff --git a/include/hw/xen/start_info.h b/include/hw/xen/start_info.h new file mode 100644 index 00000000000..348779eb10c --- /dev/null +++ b/include/hw/xen/start_info.h @@ -0,0 +1,146 @@ +/* + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright (c) 2016, Citrix Systems, Inc. + */ + +#ifndef __XEN_PUBLIC_ARCH_X86_HVM_START_INFO_H__ +#define __XEN_PUBLIC_ARCH_X86_HVM_START_INFO_H__ + +/* + * Start of day structure passed to PVH guests and to HVM guests in %ebx. + * + * NOTE: nothing will be loaded at physical address 0, so a 0 value in any + * of the address fields should be treated as not present. + * + * 0 +----------------+ + * | magic | Contains the magic value XEN_HVM_START_MAGIC_VALUE + * | | ("xEn3" with the 0x80 bit of the "E" set). + * 4 +----------------+ + * | version | Version of this structure. Current version is 1. New + * | | versions are guaranteed to be backwards-compatible. + * 8 +----------------+ + * | flags | SIF_xxx flags. + * 12 +----------------+ + * | nr_modules | Number of modules passed to the kernel. + * 16 +----------------+ + * | modlist_paddr | Physical address of an array of modules + * | | (layout of the structure below). + * 24 +----------------+ + * | cmdline_paddr | Physical address of the command line, + * | | a zero-terminated ASCII string. + * 32 +----------------+ + * | rsdp_paddr | Physical address of the RSDP ACPI data structure. + * 40 +----------------+ + * | memmap_paddr | Physical address of the (optional) memory map. Only + * | | present in version 1 and newer of the structure. + * 48 +----------------+ + * | memmap_entries | Number of entries in the memory map table. Only + * | | present in version 1 and newer of the structure. + * | | Zero if there is no memory map being provided. + * 52 +----------------+ + * | reserved | Version 1 and newer only. + * 56 +----------------+ + * + * The layout of each entry in the module structure is the following: + * + * 0 +----------------+ + * | paddr | Physical address of the module. + * 8 +----------------+ + * | size | Size of the module in bytes. + * 16 +----------------+ + * | cmdline_paddr | Physical address of the command line, + * | | a zero-terminated ASCII string. + * 24 +----------------+ + * | reserved | + * 32 +----------------+ + * + * The layout of each entry in the memory map table is as follows: + * + * 0 +----------------+ + * | addr | Base address + * 8 +----------------+ + * | size | Size of mapping in bytes + * 16 +----------------+ + * | type | Type of mapping as defined between the hypervisor + * | | and guest it's starting. E820_TYPE_xxx, for example. + * 20 +----------------| + * | reserved | + * 24 +----------------+ + * + * The address and sizes are always a 64bit little endian unsigned integer. + * + * NB: Xen on x86 will always try to place all the data below the 4GiB + * boundary. + * + * Version numbers of the hvm_start_info structure have evolved like this: + * + * Version 0: + * + * Version 1: Added the memmap_paddr/memmap_entries fields (plus 4 bytes of + * padding) to the end of the hvm_start_info struct. These new + * fields can be used to pass a memory map to the guest. The + * memory map is optional and so guests that understand version 1 + * of the structure must check that memmap_entries is non-zero + * before trying to read the memory map. + */ +#define XEN_HVM_START_MAGIC_VALUE 0x336ec578 + +/* + * C representation of the x86/HVM start info layout. + * + * The canonical definition of this layout is above, this is just a way to + * represent the layout described there using C types. + */ +struct hvm_start_info { + uint32_t magic; /* Contains the magic value 0x336ec578 */ + /* ("xEn3" with the 0x80 bit of the "E" set).*/ + uint32_t version; /* Version of this structure. */ + uint32_t flags; /* SIF_xxx flags. */ + uint32_t nr_modules; /* Number of modules passed to the kernel. */ + uint64_t modlist_paddr; /* Physical address of an array of */ + /* hvm_modlist_entry. */ + uint64_t cmdline_paddr; /* Physical address of the command line. */ + uint64_t rsdp_paddr; /* Physical address of the RSDP ACPI data */ + /* structure. */ + uint64_t memmap_paddr; /* Physical address of an array of */ + /* hvm_memmap_table_entry. Only present in */ + /* version 1 and newer of the structure */ + uint32_t memmap_entries; /* Number of entries in the memmap table. */ + /* Only present in version 1 and newer of */ + /* the structure. Value will be zero if */ + /* there is no memory map being provided. */ + uint32_t reserved; +}; + +struct hvm_modlist_entry { + uint64_t paddr; /* Physical address of the module. */ + uint64_t size; /* Size of the module in bytes. */ + uint64_t cmdline_paddr; /* Physical address of the command line. */ + uint64_t reserved; +}; + +struct hvm_memmap_table_entry { + uint64_t addr; /* Base address of the memory region */ + uint64_t size; /* Size of the memory region in bytes */ + uint32_t type; /* Mapping type */ + uint32_t reserved; +}; + +#endif /* __XEN_PUBLIC_ARCH_X86_HVM_START_INFO_H__ */ From ab969087da65e2f67a546cfc664901eda7029e36 Mon Sep 17 00:00:00 2001 From: Liam Merwick Date: Tue, 15 Jan 2019 12:18:06 +0000 Subject: [PATCH 14/76] pvh: Boot uncompressed kernel using direct boot ABI These changes (along with corresponding Linux kernel and qboot changes) enable a guest to be booted using the x86/HVM direct boot ABI. This commit adds a load_elfboot() routine to pass the size and location of the kernel entry point to qboot (which will fill in the start_info struct information needed to to boot the guest). Having loaded the ELF binary, load_linux() will run qboot which continues the boot. The address for the kernel entry point is read from an ELF Note in the uncompressed kernel binary by a helper routine passed to load_elf(). Co-developed-by: George Kennedy Signed-off-by: George Kennedy Signed-off-by: Liam Merwick Signed-off-by: Paolo Bonzini --- hw/i386/pc.c | 135 ++++++++++++++++++++++++++++++++++++++++++++++++++ include/elf.h | 10 ++++ 2 files changed, 145 insertions(+) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 1690b1935f7..e39ef5caa1c 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -54,6 +54,7 @@ #include "sysemu/qtest.h" #include "kvm_i386.h" #include "hw/xen/xen.h" +#include "hw/xen/start_info.h" #include "ui/qemu-spice.h" #include "exec/memory.h" #include "exec/address-spaces.h" @@ -110,6 +111,9 @@ static struct e820_entry *e820_table; static unsigned e820_entries; struct hpet_fw_config hpet_cfg = {.count = UINT8_MAX}; +/* Physical Address of PVH entry point read from kernel ELF NOTE */ +static size_t pvh_start_addr; + GlobalProperty pc_compat_3_1[] = { { "intel-iommu", "dma-drain", "off" }, { "Opteron_G3" "-" TYPE_X86_CPU, "rdtscp", "off" }, @@ -1069,6 +1073,109 @@ struct setup_data { uint8_t data[0]; } __attribute__((packed)); + +/* + * The entry point into the kernel for PVH boot is different from + * the native entry point. The PVH entry is defined by the x86/HVM + * direct boot ABI and is available in an ELFNOTE in the kernel binary. + * + * This function is passed to load_elf() when it is called from + * load_elfboot() which then additionally checks for an ELF Note of + * type XEN_ELFNOTE_PHYS32_ENTRY and passes it to this function to + * parse the PVH entry address from the ELF Note. + * + * Due to trickery in elf_opts.h, load_elf() is actually available as + * load_elf32() or load_elf64() and this routine needs to be able + * to deal with being called as 32 or 64 bit. + * + * The address of the PVH entry point is saved to the 'pvh_start_addr' + * global variable. (although the entry point is 32-bit, the kernel + * binary can be either 32-bit or 64-bit). + */ +static uint64_t read_pvh_start_addr(void *arg1, void *arg2, bool is64) +{ + size_t *elf_note_data_addr; + + /* Check if ELF Note header passed in is valid */ + if (arg1 == NULL) { + return 0; + } + + if (is64) { + struct elf64_note *nhdr64 = (struct elf64_note *)arg1; + uint64_t nhdr_size64 = sizeof(struct elf64_note); + uint64_t phdr_align = *(uint64_t *)arg2; + uint64_t nhdr_namesz = nhdr64->n_namesz; + + elf_note_data_addr = + ((void *)nhdr64) + nhdr_size64 + + QEMU_ALIGN_UP(nhdr_namesz, phdr_align); + } else { + struct elf32_note *nhdr32 = (struct elf32_note *)arg1; + uint32_t nhdr_size32 = sizeof(struct elf32_note); + uint32_t phdr_align = *(uint32_t *)arg2; + uint32_t nhdr_namesz = nhdr32->n_namesz; + + elf_note_data_addr = + ((void *)nhdr32) + nhdr_size32 + + QEMU_ALIGN_UP(nhdr_namesz, phdr_align); + } + + pvh_start_addr = *elf_note_data_addr; + + return pvh_start_addr; +} + +static bool load_elfboot(const char *kernel_filename, + int kernel_file_size, + uint8_t *header, + size_t pvh_xen_start_addr, + FWCfgState *fw_cfg) +{ + uint32_t flags = 0; + uint32_t mh_load_addr = 0; + uint32_t elf_kernel_size = 0; + uint64_t elf_entry; + uint64_t elf_low, elf_high; + int kernel_size; + + if (ldl_p(header) != 0x464c457f) { + return false; /* no elfboot */ + } + + bool elf_is64 = header[EI_CLASS] == ELFCLASS64; + flags = elf_is64 ? + ((Elf64_Ehdr *)header)->e_flags : ((Elf32_Ehdr *)header)->e_flags; + + if (flags & 0x00010004) { /* LOAD_ELF_HEADER_HAS_ADDR */ + error_report("elfboot unsupported flags = %x", flags); + exit(1); + } + + uint64_t elf_note_type = XEN_ELFNOTE_PHYS32_ENTRY; + kernel_size = load_elf(kernel_filename, read_pvh_start_addr, + NULL, &elf_note_type, &elf_entry, + &elf_low, &elf_high, 0, I386_ELF_MACHINE, + 0, 0); + + if (kernel_size < 0) { + error_report("Error while loading elf kernel"); + exit(1); + } + mh_load_addr = elf_low; + elf_kernel_size = elf_high - elf_low; + + if (pvh_start_addr == 0) { + error_report("Error loading uncompressed kernel without PVH ELF Note"); + exit(1); + } + fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ENTRY, pvh_start_addr); + fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, mh_load_addr); + fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, elf_kernel_size); + + return true; +} + static void load_linux(PCMachineState *pcms, FWCfgState *fw_cfg) { @@ -1108,6 +1215,34 @@ static void load_linux(PCMachineState *pcms, if (ldl_p(header+0x202) == 0x53726448) { protocol = lduw_p(header+0x206); } else { + /* + * Check if the file is an uncompressed kernel file (ELF) and load it, + * saving the PVH entry point used by the x86/HVM direct boot ABI. + * If load_elfboot() is successful, populate the fw_cfg info. + */ + if (load_elfboot(kernel_filename, kernel_size, + header, pvh_start_addr, fw_cfg)) { + struct hvm_modlist_entry ramdisk_mod = { 0 }; + + fclose(f); + + fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, + strlen(kernel_cmdline) + 1); + fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, kernel_cmdline); + + assert(machine->device_memory != NULL); + ramdisk_mod.paddr = machine->device_memory->base; + ramdisk_mod.size = + memory_region_size(&machine->device_memory->mr); + + fw_cfg_add_bytes(fw_cfg, FW_CFG_KERNEL_DATA, &ramdisk_mod, + sizeof(ramdisk_mod)); + fw_cfg_add_i32(fw_cfg, FW_CFG_SETUP_SIZE, sizeof(header)); + fw_cfg_add_bytes(fw_cfg, FW_CFG_SETUP_DATA, + header, sizeof(header)); + + return; + } /* This looks like a multiboot kernel. If it is, let's stop treating it like a Linux kernel. */ if (load_multiboot(fw_cfg, f, kernel_filename, initrd_filename, diff --git a/include/elf.h b/include/elf.h index e816fb4d764..b35347eee76 100644 --- a/include/elf.h +++ b/include/elf.h @@ -1640,6 +1640,16 @@ typedef struct elf64_shdr { #define NT_ARM_HW_WATCH 0x403 /* ARM hardware watchpoint registers */ #define NT_ARM_SYSTEM_CALL 0x404 /* ARM system call number */ +/* + * Physical entry point into the kernel. + * + * 32bit entry point into the kernel. When requested to launch the + * guest kernel, use this entry point to launch the guest in 32-bit + * protected mode with paging disabled. + * + * [ Corresponding definition in Linux kernel: include/xen/interface/elfnote.h ] + */ +#define XEN_ELFNOTE_PHYS32_ENTRY 18 /* 0x12 */ /* Note header in a PT_NOTE section */ typedef struct elf32_note { From c5bf7847b7b281bc13795b12d09ca1f35fc62673 Mon Sep 17 00:00:00 2001 From: Stefano Garzarella Date: Tue, 15 Jan 2019 12:18:07 +0000 Subject: [PATCH 15/76] pvh: load initrd and expose it through fw_cfg When initrd is specified, load and expose it to the guest firmware through fw_cfg. The firmware will fill the hvm_start_info for the kernel. Signed-off-by: Stefano Garzarella Based-on: <1545422632-24444-5-git-send-email-liam.merwick@oracle.com> Signed-off-by: Liam Merwick Signed-off-by: Paolo Bonzini --- hw/i386/pc.c | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index e39ef5caa1c..5d61557a243 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1222,25 +1222,45 @@ static void load_linux(PCMachineState *pcms, */ if (load_elfboot(kernel_filename, kernel_size, header, pvh_start_addr, fw_cfg)) { - struct hvm_modlist_entry ramdisk_mod = { 0 }; - fclose(f); fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, strlen(kernel_cmdline) + 1); fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA, kernel_cmdline); - assert(machine->device_memory != NULL); - ramdisk_mod.paddr = machine->device_memory->base; - ramdisk_mod.size = - memory_region_size(&machine->device_memory->mr); - - fw_cfg_add_bytes(fw_cfg, FW_CFG_KERNEL_DATA, &ramdisk_mod, - sizeof(ramdisk_mod)); fw_cfg_add_i32(fw_cfg, FW_CFG_SETUP_SIZE, sizeof(header)); fw_cfg_add_bytes(fw_cfg, FW_CFG_SETUP_DATA, header, sizeof(header)); + /* load initrd */ + if (initrd_filename) { + gsize initrd_size; + gchar *initrd_data; + GError *gerr = NULL; + + if (!g_file_get_contents(initrd_filename, &initrd_data, + &initrd_size, &gerr)) { + fprintf(stderr, "qemu: error reading initrd %s: %s\n", + initrd_filename, gerr->message); + exit(1); + } + + initrd_max = pcms->below_4g_mem_size - pcmc->acpi_data_size - 1; + if (initrd_size >= initrd_max) { + fprintf(stderr, "qemu: initrd is too large, cannot support." + "(max: %"PRIu32", need %"PRId64")\n", + initrd_max, (uint64_t)initrd_size); + exit(1); + } + + initrd_addr = (initrd_max - initrd_size) & ~4095; + + fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, initrd_addr); + fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size); + fw_cfg_add_bytes(fw_cfg, FW_CFG_INITRD_DATA, initrd_data, + initrd_size); + } + return; } /* This looks like a multiboot kernel. If it is, let's stop From 526d798435045d74e819700d8c5c64900776b980 Mon Sep 17 00:00:00 2001 From: Stefano Garzarella Date: Fri, 18 Jan 2019 13:01:39 +0100 Subject: [PATCH 16/76] linuxboot_dma: remove duplicate definitions of FW_CFG FW_CFG_DMA_CTL_* bits and struct fw_cfg_dma_access are defined in the qemu_fw_cfg.h header file already included in linuxboot_dma.c, so we can remove the definition of BIOS_CFG_DMA_CTL_* and struct FWCfgDmaAccess. Signed-off-by: Stefano Garzarella Reviewed-by: Stefan Hajnoczi Reviewed-by: Liam Merwick Based-on: <1547554687-12687-1-git-send-email-liam.merwick@oracle.com> Signed-off-by: Paolo Bonzini --- pc-bios/optionrom/linuxboot_dma.c | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/pc-bios/optionrom/linuxboot_dma.c b/pc-bios/optionrom/linuxboot_dma.c index d856d41b55c..f728dc839fb 100644 --- a/pc-bios/optionrom/linuxboot_dma.c +++ b/pc-bios/optionrom/linuxboot_dma.c @@ -58,12 +58,6 @@ asm( " jmp load_kernel\n" ); -/* QEMU_CFG_DMA_CONTROL bits */ -#define BIOS_CFG_DMA_CTL_ERROR 0x01 -#define BIOS_CFG_DMA_CTL_READ 0x02 -#define BIOS_CFG_DMA_CTL_SKIP 0x04 -#define BIOS_CFG_DMA_CTL_SELECT 0x08 - #define BIOS_CFG_DMA_ADDR_HIGH 0x514 #define BIOS_CFG_DMA_ADDR_LOW 0x518 @@ -75,12 +69,6 @@ asm( #define barrier() asm("" : : : "memory") -typedef struct FWCfgDmaAccess { - uint32_t control; - uint32_t length; - uint64_t address; -} __attribute__((packed)) FWCfgDmaAccess; - static inline void outl(uint32_t value, uint16_t port) { asm("outl %0, %w1" : : "a"(value), "Nd"(port)); @@ -153,9 +141,9 @@ static inline uint32_t be32_to_cpu(uint32_t x) static __attribute__((__noinline__)) void bios_cfg_read_entry(void *buf, uint16_t entry, uint32_t len) { - FWCfgDmaAccess access; - uint32_t control = (entry << 16) | BIOS_CFG_DMA_CTL_SELECT - | BIOS_CFG_DMA_CTL_READ; + struct fw_cfg_dma_access access; + uint32_t control = (entry << 16) | FW_CFG_DMA_CTL_SELECT + | FW_CFG_DMA_CTL_READ; access.address = cpu_to_be64((uint64_t)(uint32_t)buf); access.length = cpu_to_be32(len); @@ -165,7 +153,7 @@ void bios_cfg_read_entry(void *buf, uint16_t entry, uint32_t len) outl(cpu_to_be32((uint32_t)&access), BIOS_CFG_DMA_ADDR_LOW); - while (be32_to_cpu(access.control) & ~BIOS_CFG_DMA_CTL_ERROR) { + while (be32_to_cpu(access.control) & ~FW_CFG_DMA_CTL_ERROR) { barrier(); } } From 6dfa01437bea02b2e5ae14f9e163e55610ead6fe Mon Sep 17 00:00:00 2001 From: Stefano Garzarella Date: Fri, 18 Jan 2019 13:01:40 +0100 Subject: [PATCH 17/76] linuxboot_dma: move common functions in a new header In order to allow other option roms to use these common useful functions and definitions, this patch put them in two new C header files called optrom.h and optrom_fw_cfg.h. We also add useful out*() in*() functions for different size, and new fw_cfg functions to use when DMA feature is not available. Signed-off-by: Stefano Garzarella Reviewed-by: Stefan Hajnoczi Reviewed-by: Liam Merwick --- pc-bios/optionrom/linuxboot_dma.c | 102 ++++++--------------------- pc-bios/optionrom/optrom.h | 110 ++++++++++++++++++++++++++++++ pc-bios/optionrom/optrom_fw_cfg.h | 92 +++++++++++++++++++++++++ 3 files changed, 221 insertions(+), 83 deletions(-) create mode 100644 pc-bios/optionrom/optrom.h create mode 100644 pc-bios/optionrom/optrom_fw_cfg.h diff --git a/pc-bios/optionrom/linuxboot_dma.c b/pc-bios/optionrom/linuxboot_dma.c index f728dc839fb..cbcf6679d9b 100644 --- a/pc-bios/optionrom/linuxboot_dma.c +++ b/pc-bios/optionrom/linuxboot_dma.c @@ -58,21 +58,13 @@ asm( " jmp load_kernel\n" ); -#define BIOS_CFG_DMA_ADDR_HIGH 0x514 -#define BIOS_CFG_DMA_ADDR_LOW 0x518 - -#define uint64_t unsigned long long -#define uint32_t unsigned int -#define uint16_t unsigned short - -#include "../../include/standard-headers/linux/qemu_fw_cfg.h" - -#define barrier() asm("" : : : "memory") - -static inline void outl(uint32_t value, uint16_t port) -{ - asm("outl %0, %w1" : : "a"(value), "Nd"(port)); -} +/* + * The includes of C headers must be after the asm block to avoid compiler + * errors. + */ +#include +#include "optrom.h" +#include "optrom_fw_cfg.h" static inline void set_es(void *addr) { @@ -80,12 +72,6 @@ static inline void set_es(void *addr) asm("movl %0, %%es" : : "r"(seg)); } -#ifdef __clang__ -#define ADDR32 -#else -#define ADDR32 "addr32 " -#endif - static inline uint16_t readw_es(uint16_t offset) { uint16_t val; @@ -108,56 +94,6 @@ static inline void writel_es(uint16_t offset, uint32_t val) asm(ADDR32 "movl %0, %%es:(%1)" : : "r"(val), "r"((uint32_t)offset)); } -static inline uint32_t bswap32(uint32_t x) -{ - asm("bswapl %0" : "=r" (x) : "0" (x)); - return x; -} - -static inline uint64_t bswap64(uint64_t x) -{ - asm("bswapl %%eax; bswapl %%edx; xchg %%eax, %%edx" : "=A" (x) : "0" (x)); - return x; -} - -static inline uint64_t cpu_to_be64(uint64_t x) -{ - return bswap64(x); -} - -static inline uint32_t cpu_to_be32(uint32_t x) -{ - return bswap32(x); -} - -static inline uint32_t be32_to_cpu(uint32_t x) -{ - return bswap32(x); -} - -/* clang is happy to inline this function, and bloats the - * ROM. - */ -static __attribute__((__noinline__)) -void bios_cfg_read_entry(void *buf, uint16_t entry, uint32_t len) -{ - struct fw_cfg_dma_access access; - uint32_t control = (entry << 16) | FW_CFG_DMA_CTL_SELECT - | FW_CFG_DMA_CTL_READ; - - access.address = cpu_to_be64((uint64_t)(uint32_t)buf); - access.length = cpu_to_be32(len); - access.control = cpu_to_be32(control); - - barrier(); - - outl(cpu_to_be32((uint32_t)&access), BIOS_CFG_DMA_ADDR_LOW); - - while (be32_to_cpu(access.control) & ~FW_CFG_DMA_CTL_ERROR) { - barrier(); - } -} - /* Return top of memory using BIOS function E801. */ static uint32_t get_e801_addr(void) { @@ -211,9 +147,9 @@ void load_kernel(void) uint32_t initrd_end_page, max_allowed_page; uint32_t segment_addr, stack_addr; - bios_cfg_read_entry(&setup_addr, FW_CFG_SETUP_ADDR, 4); - bios_cfg_read_entry(&setup_size, FW_CFG_SETUP_SIZE, 4); - bios_cfg_read_entry(setup_addr, FW_CFG_SETUP_DATA, setup_size); + bios_cfg_read_entry_dma(&setup_addr, FW_CFG_SETUP_ADDR, 4); + bios_cfg_read_entry_dma(&setup_size, FW_CFG_SETUP_SIZE, 4); + bios_cfg_read_entry_dma(setup_addr, FW_CFG_SETUP_DATA, setup_size); set_es(setup_addr); @@ -223,8 +159,8 @@ void load_kernel(void) writel_es(0x22c, 0x37ffffff); } - bios_cfg_read_entry(&initrd_addr, FW_CFG_INITRD_ADDR, 4); - bios_cfg_read_entry(&initrd_size, FW_CFG_INITRD_SIZE, 4); + bios_cfg_read_entry_dma(&initrd_addr, FW_CFG_INITRD_ADDR, 4); + bios_cfg_read_entry_dma(&initrd_size, FW_CFG_INITRD_SIZE, 4); initrd_end_page = ((uint32_t)(initrd_addr + initrd_size) & -4096); max_allowed_page = (readl_es(0x22c) & -4096); @@ -239,15 +175,15 @@ void load_kernel(void) } - bios_cfg_read_entry(initrd_addr, FW_CFG_INITRD_DATA, initrd_size); + bios_cfg_read_entry_dma(initrd_addr, FW_CFG_INITRD_DATA, initrd_size); - bios_cfg_read_entry(&kernel_addr, FW_CFG_KERNEL_ADDR, 4); - bios_cfg_read_entry(&kernel_size, FW_CFG_KERNEL_SIZE, 4); - bios_cfg_read_entry(kernel_addr, FW_CFG_KERNEL_DATA, kernel_size); + bios_cfg_read_entry_dma(&kernel_addr, FW_CFG_KERNEL_ADDR, 4); + bios_cfg_read_entry_dma(&kernel_size, FW_CFG_KERNEL_SIZE, 4); + bios_cfg_read_entry_dma(kernel_addr, FW_CFG_KERNEL_DATA, kernel_size); - bios_cfg_read_entry(&cmdline_addr, FW_CFG_CMDLINE_ADDR, 4); - bios_cfg_read_entry(&cmdline_size, FW_CFG_CMDLINE_SIZE, 4); - bios_cfg_read_entry(cmdline_addr, FW_CFG_CMDLINE_DATA, cmdline_size); + bios_cfg_read_entry_dma(&cmdline_addr, FW_CFG_CMDLINE_ADDR, 4); + bios_cfg_read_entry_dma(&cmdline_size, FW_CFG_CMDLINE_SIZE, 4); + bios_cfg_read_entry_dma(cmdline_addr, FW_CFG_CMDLINE_DATA, cmdline_size); /* Boot linux */ segment_addr = ((uint32_t)setup_addr >> 4); diff --git a/pc-bios/optionrom/optrom.h b/pc-bios/optionrom/optrom.h new file mode 100644 index 00000000000..357819259aa --- /dev/null +++ b/pc-bios/optionrom/optrom.h @@ -0,0 +1,110 @@ +/* + * Common Option ROM Functions for C code + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * Copyright (c) 2015-2019 Red Hat Inc. + * Authors: + * Marc Marí + * Richard W.M. Jones + * Stefano Garzarella + */ + +#ifndef OPTROM_H +#define OPTROM_H + +#include +#include "../../include/standard-headers/linux/qemu_fw_cfg.h" + +#define barrier() asm("" : : : "memory") + +#ifdef __clang__ +#define ADDR32 +#else +#define ADDR32 "addr32 " +#endif + +static inline void outb(uint8_t value, uint16_t port) +{ + asm volatile("outb %0, %w1" : : "a"(value), "Nd"(port)); +} + +static inline void outw(uint16_t value, uint16_t port) +{ + asm volatile("outw %0, %w1" : : "a"(value), "Nd"(port)); +} + +static inline void outl(uint32_t value, uint16_t port) +{ + asm volatile("outl %0, %w1" : : "a"(value), "Nd"(port)); +} + +static inline uint8_t inb(uint16_t port) +{ + uint8_t value; + + asm volatile("inb %w1, %0" : "=a"(value) : "Nd"(port)); + return value; +} + +static inline uint16_t inw(uint16_t port) +{ + uint16_t value; + + asm volatile("inw %w1, %0" : "=a"(value) : "Nd"(port)); + return value; +} + +static inline uint32_t inl(uint16_t port) +{ + uint32_t value; + + asm volatile("inl %w1, %0" : "=a"(value) : "Nd"(port)); + return value; +} + +static inline void insb(uint16_t port, uint8_t *buf, uint32_t len) +{ + asm volatile("rep insb %%dx, %%es:(%%edi)" + : "+c"(len), "+D"(buf) : "d"(port) : "memory"); +} + +static inline uint32_t bswap32(uint32_t x) +{ + asm("bswapl %0" : "=r" (x) : "0" (x)); + return x; +} + +static inline uint64_t bswap64(uint64_t x) +{ + asm("bswapl %%eax; bswapl %%edx; xchg %%eax, %%edx" : "=A" (x) : "0" (x)); + return x; +} + +static inline uint64_t cpu_to_be64(uint64_t x) +{ + return bswap64(x); +} + +static inline uint32_t cpu_to_be32(uint32_t x) +{ + return bswap32(x); +} + +static inline uint32_t be32_to_cpu(uint32_t x) +{ + return bswap32(x); +} + +#endif /* OPTROM_H */ diff --git a/pc-bios/optionrom/optrom_fw_cfg.h b/pc-bios/optionrom/optrom_fw_cfg.h new file mode 100644 index 00000000000..a3660a52006 --- /dev/null +++ b/pc-bios/optionrom/optrom_fw_cfg.h @@ -0,0 +1,92 @@ +/* + * Common Option ROM Functions for fw_cfg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * Copyright (c) 2015-2019 Red Hat Inc. + * Authors: + * Marc Marí + * Richard W.M. Jones + * Stefano Garzarella + */ + +#ifndef OPTROM_FW_CFG_H +#define OPTROM_FW_CFG_H + +#include "../../include/standard-headers/linux/qemu_fw_cfg.h" + +#define BIOS_CFG_IOPORT_CFG 0x510 +#define BIOS_CFG_IOPORT_DATA 0x511 +#define BIOS_CFG_DMA_ADDR_HIGH 0x514 +#define BIOS_CFG_DMA_ADDR_LOW 0x518 + +static __attribute__((unused)) +void bios_cfg_select(uint16_t key) +{ + outw(key, BIOS_CFG_IOPORT_CFG); +} + +static __attribute__((unused)) +void bios_cfg_read_entry_io(void *buf, uint16_t entry, uint32_t len) +{ + bios_cfg_select(entry); + insb(BIOS_CFG_IOPORT_DATA, buf, len); +} + +/* + * clang is happy to inline this function, and bloats the + * ROM. + */ +static __attribute__((__noinline__)) __attribute__((unused)) +void bios_cfg_read_entry_dma(void *buf, uint16_t entry, uint32_t len) +{ + struct fw_cfg_dma_access access; + uint32_t control = (entry << 16) | FW_CFG_DMA_CTL_SELECT + | FW_CFG_DMA_CTL_READ; + + access.address = cpu_to_be64((uint64_t)(uint32_t)buf); + access.length = cpu_to_be32(len); + access.control = cpu_to_be32(control); + + barrier(); + + outl(cpu_to_be32((uint32_t)&access), BIOS_CFG_DMA_ADDR_LOW); + + while (be32_to_cpu(access.control) & ~FW_CFG_DMA_CTL_ERROR) { + barrier(); + } +} + +static __attribute__((unused)) +void bios_cfg_read_entry(void *buf, uint16_t entry, uint32_t len, + uint32_t version) +{ + if (version & FW_CFG_VERSION_DMA) { + bios_cfg_read_entry_dma(buf, entry, len); + } else { + bios_cfg_read_entry_io(buf, entry, len); + } +} + +static __attribute__((unused)) +uint32_t bios_cfg_version(void) +{ + uint32_t version; + + bios_cfg_read_entry_io(&version, FW_CFG_ID, sizeof(version)); + + return version; +} + +#endif /* OPTROM_FW_CFG_H */ From 2785dc7b1786a833ca5ad6d8d39d64eb82e2cddc Mon Sep 17 00:00:00 2001 From: Stefano Garzarella Date: Fri, 18 Jan 2019 13:01:41 +0100 Subject: [PATCH 18/76] optionrom: add new PVH option rom The new pvh.bin option rom can be used with SeaBIOS to boot uncompressed kernel using the x86/HVM direct boot ABI. pvh.S contains the entry point of the option rom. It runs in real mode, loads the e820 table querying the BIOS, and then it switches to 32bit protected mode and jumps to the pvh_load_kernel() written in pvh_main.c. pvh_load_kernel() loads the cmdline and kernel entry_point using fw_cfg, then it looks for RSDP, fills the hvm_start_info required by x86/HVM ABI, and finally jumps to the kernel entry_point. Signed-off-by: Stefano Garzarella Reviewed-by: Stefan Hajnoczi Reviewed-by: Liam Merwick --- .gitignore | 4 + Makefile | 2 +- pc-bios/optionrom/Makefile | 5 +- pc-bios/optionrom/pvh.S | 200 +++++++++++++++++++++++++++++++++++ pc-bios/optionrom/pvh_main.c | 116 ++++++++++++++++++++ pc-bios/pvh.bin | Bin 0 -> 1536 bytes 6 files changed, 325 insertions(+), 2 deletions(-) create mode 100644 pc-bios/optionrom/pvh.S create mode 100644 pc-bios/optionrom/pvh_main.c create mode 100644 pc-bios/pvh.bin diff --git a/.gitignore b/.gitignore index 0430257313b..321095bf1a0 100644 --- a/.gitignore +++ b/.gitignore @@ -103,6 +103,10 @@ /pc-bios/optionrom/linuxboot_dma.bin /pc-bios/optionrom/linuxboot_dma.raw /pc-bios/optionrom/linuxboot_dma.img +/pc-bios/optionrom/pvh.asm +/pc-bios/optionrom/pvh.bin +/pc-bios/optionrom/pvh.raw +/pc-bios/optionrom/pvh.img /pc-bios/optionrom/multiboot.asm /pc-bios/optionrom/multiboot.bin /pc-bios/optionrom/multiboot.raw diff --git a/Makefile b/Makefile index 1278a3eb529..76f6ab4b7e8 100644 --- a/Makefile +++ b/Makefile @@ -673,7 +673,7 @@ efi-e1000.rom efi-eepro100.rom efi-ne2k_pci.rom \ efi-pcnet.rom efi-rtl8139.rom efi-virtio.rom \ efi-e1000e.rom efi-vmxnet3.rom \ bamboo.dtb canyonlands.dtb petalogix-s3adsp1800.dtb petalogix-ml605.dtb \ -multiboot.bin linuxboot.bin linuxboot_dma.bin kvmvapic.bin \ +multiboot.bin linuxboot.bin linuxboot_dma.bin kvmvapic.bin pvh.bin \ s390-ccw.img s390-netboot.img \ spapr-rtas.bin slof.bin skiboot.lid \ palcode-clipper \ diff --git a/pc-bios/optionrom/Makefile b/pc-bios/optionrom/Makefile index a9a9e5e7ebc..e33a24da0d0 100644 --- a/pc-bios/optionrom/Makefile +++ b/pc-bios/optionrom/Makefile @@ -37,7 +37,7 @@ Wa = -Wa, ASFLAGS += -32 QEMU_CFLAGS += $(call cc-c-option, $(QEMU_CFLAGS), $(Wa)-32) -build-all: multiboot.bin linuxboot.bin linuxboot_dma.bin kvmvapic.bin +build-all: multiboot.bin linuxboot.bin linuxboot_dma.bin kvmvapic.bin pvh.bin # suppress auto-removal of intermediate files .SECONDARY: @@ -46,6 +46,9 @@ build-all: multiboot.bin linuxboot.bin linuxboot_dma.bin kvmvapic.bin %.o: %.S $(call quiet-command,$(CPP) $(QEMU_INCLUDES) $(QEMU_DGFLAGS) -c -o - $< | $(AS) $(ASFLAGS) -o $@,"AS","$(TARGET_DIR)$@") +pvh.img: pvh.o pvh_main.o + $(call quiet-command,$(LD) $(LDFLAGS_NOPIE) -m $(LD_I386_EMULATION) -T $(SRC_PATH)/pc-bios/optionrom/flat.lds -s -o $@ $^,"BUILD","$(TARGET_DIR)$@") + %.img: %.o $(call quiet-command,$(LD) $(LDFLAGS_NOPIE) -m $(LD_I386_EMULATION) -T $(SRC_PATH)/pc-bios/optionrom/flat.lds -s -o $@ $<,"BUILD","$(TARGET_DIR)$@") diff --git a/pc-bios/optionrom/pvh.S b/pc-bios/optionrom/pvh.S new file mode 100644 index 00000000000..e1d7f4a7a78 --- /dev/null +++ b/pc-bios/optionrom/pvh.S @@ -0,0 +1,200 @@ +/* + * PVH Option ROM + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * Copyright Novell Inc, 2009 + * Authors: Alexander Graf + * + * Copyright (c) 2019 Red Hat Inc. + * Authors: Stefano Garzarella + */ + +#include "optionrom.h" + +#define BOOT_ROM_PRODUCT "PVH loader" + +#define GS_PROT_JUMP 0 +#define GS_GDT_DESC 6 + +#ifdef OPTION_ROM_START +#undef OPTION_ROM_START +#endif +#ifdef OPTION_ROM_END +#undef OPTION_ROM_END +#endif + +/* + * Redefine OPTION_ROM_START and OPTION_ROM_END, because this rom is produced + * linking multiple objects. + * signrom.py will add padding. + */ +#define OPTION_ROM_START \ + .code16; \ + .text; \ + .global _start; \ + _start:; \ + .short 0xaa55; \ + .byte 3; /* desired size in 512 units */ + +#define OPTION_ROM_END \ + _end: + +BOOT_ROM_START + +run_pvhboot: + + cli + cld + + mov %cs, %eax + shl $0x4, %eax + + /* set up a long jump descriptor that is PC relative */ + + /* move stack memory to %gs */ + mov %ss, %ecx + shl $0x4, %ecx + mov %esp, %ebx + add %ebx, %ecx + sub $0x20, %ecx + sub $0x30, %esp + shr $0x4, %ecx + mov %cx, %gs + + /* now push the indirect jump descriptor there */ + mov (prot_jump), %ebx + add %eax, %ebx + movl %ebx, %gs:GS_PROT_JUMP + mov $8, %bx + movw %bx, %gs:GS_PROT_JUMP + 4 + + /* fix the gdt descriptor to be PC relative */ + movw (gdt_desc), %bx + movw %bx, %gs:GS_GDT_DESC + movl (gdt_desc+2), %ebx + add %eax, %ebx + movl %ebx, %gs:GS_GDT_DESC + 2 + + /* initialize HVM memmap table using int 0x15(e820) */ + + /* ES = pvh_e820 struct */ + mov $pvh_e820, %eax + shr $4, %eax + mov %ax, %es + + /* start storing memmap table at %es:8 (pvh_e820.table) */ + mov $8,%edi + xor %ebx, %ebx + jmp memmap_loop + +memmap_loop_check: + /* pvh_e820 can contains up to 128 entries */ + cmp $128, %ebx + je memmap_done + +memmap_loop: + /* entry size (hvm_memmap_table_entry) & max buffer size (int15) */ + movl $24, %ecx + /* e820 */ + movl $0x0000e820, %eax + /* 'SMAP' magic */ + movl $0x534d4150, %edx + /* store counter value at %es:0 (pvh_e820.entries) */ + movl %ebx, %es:0 + + int $0x15 + /* error or last entry already done? */ + jb memmap_err + + /* %edi += entry size (hvm_memmap_table_entry) */ + add $24, %edi + + /* continuation value 0 means last entry */ + test %ebx, %ebx + jnz memmap_loop_check + + /* increase pvh_e820.entries to save the last entry */ + movl %es:0, %ebx + inc %ebx + +memmap_done: + movl %ebx, %es:0 + +memmap_err: + + /* load the GDT before going into protected mode */ +lgdt: + data32 lgdt %gs:GS_GDT_DESC + + /* get us to protected mode now */ + movl $1, %eax + movl %eax, %cr0 + + /* the LJMP sets CS for us and gets us to 32-bit */ +ljmp: + data32 ljmp *%gs:GS_PROT_JUMP + +prot_mode: +.code32 + + /* initialize all other segments */ + movl $0x10, %eax + movl %eax, %ss + movl %eax, %ds + movl %eax, %es + movl %eax, %fs + movl %eax, %gs + + jmp pvh_load_kernel + +/* Variables */ +.align 4, 0 +prot_jump: .long prot_mode + .short 8 + +.align 4, 0 +gdt: + /* 0x00 */ +.byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + + /* + * 0x08: code segment + * (base=0, limit=0xfffff, type=32bit code exec/read, DPL=0, 4k) + */ +.byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x9a, 0xcf, 0x00 + + /* + * 0x10: data segment + * (base=0, limit=0xfffff, type=32bit data read/write, DPL=0, 4k) + */ +.byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x92, 0xcf, 0x00 + + /* + * 0x18: code segment + * (base=0, limit=0x0ffff, type=16bit code exec/read/conf, DPL=0, 1b) + */ +.byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00 + + /* + * 0x20: data segment + * (base=0, limit=0x0ffff, type=16bit data read/write, DPL=0, 1b) + */ +.byte 0xff, 0xff, 0x00, 0x00, 0x00, 0x92, 0x00, 0x00 + +gdt_desc: +.short (5 * 8) - 1 +.long gdt + +BOOT_ROM_END diff --git a/pc-bios/optionrom/pvh_main.c b/pc-bios/optionrom/pvh_main.c new file mode 100644 index 00000000000..1dcc5c92565 --- /dev/null +++ b/pc-bios/optionrom/pvh_main.c @@ -0,0 +1,116 @@ +/* + * PVH Option ROM for fw_cfg DMA + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * Copyright (c) 2019 Red Hat Inc. + * Authors: + * Stefano Garzarella + */ + +asm (".code32"); /* this code will be executed in protected mode */ + +#include +#include +#include "optrom.h" +#include "optrom_fw_cfg.h" +#include "../../include/hw/xen/start_info.h" + +#define RSDP_SIGNATURE 0x2052545020445352LL /* "RSD PTR " */ +#define RSDP_AREA_ADDR 0x000E0000 +#define RSDP_AREA_SIZE 2048 +#define EBDA_BASE_ADDR 0x0000040E +#define EBDA_SIZE 1024 + +#define E820_MAXENTRIES 128 +#define CMDLINE_BUFSIZE 4096 + +/* e820 table filled in pvh.S using int 0x15 */ +struct pvh_e820_table { + uint32_t entries; + uint32_t reserved; + struct hvm_memmap_table_entry table[E820_MAXENTRIES]; +}; + +struct pvh_e820_table pvh_e820 asm("pvh_e820") __attribute__ ((aligned)); + +static struct hvm_start_info start_info; +static uint8_t cmdline_buffer[CMDLINE_BUFSIZE]; + + +/* Search RSDP signature. */ +static uintptr_t search_rsdp(uint32_t start_addr, uint32_t end_addr) +{ + uint64_t *rsdp_p; + + /* RSDP signature is always on a 16 byte boundary */ + for (rsdp_p = (uint64_t *)start_addr; rsdp_p < (uint64_t *)end_addr; + rsdp_p += 2) { + if (*rsdp_p == RSDP_SIGNATURE) { + return (uintptr_t)rsdp_p; + } + } + + return 0; +} + +/* Force the asm name without leading underscore, even on Win32. */ +extern void pvh_load_kernel(void) asm("pvh_load_kernel"); + +void pvh_load_kernel(void) +{ + void *cmdline_addr = &cmdline_buffer; + void *kernel_entry; + uint32_t cmdline_size, fw_cfg_version = bios_cfg_version(); + + start_info.magic = XEN_HVM_START_MAGIC_VALUE; + start_info.version = 1; + + /* + * pvh_e820 is filled in the pvh.S before to switch in protected mode, + * because we can use int 0x15 only in real mode. + */ + start_info.memmap_entries = pvh_e820.entries; + start_info.memmap_paddr = (uintptr_t)pvh_e820.table; + + /* + * Search RSDP in the main BIOS area below 1 MB. + * SeaBIOS store the RSDP in this area, so we try it first. + */ + start_info.rsdp_paddr = search_rsdp(RSDP_AREA_ADDR, + RSDP_AREA_ADDR + RSDP_AREA_SIZE); + + /* Search RSDP in the EBDA if it is not found */ + if (!start_info.rsdp_paddr) { + /* + * Th EBDA address is stored at EBDA_BASE_ADDR. It contains 2 bytes + * segment pointer to EBDA, so we must convert it to a linear address. + */ + uint32_t ebda_paddr = ((uint32_t)*((uint16_t *)EBDA_BASE_ADDR)) << 4; + if (ebda_paddr > 0x400) { + uint32_t *ebda = (uint32_t *)ebda_paddr; + + start_info.rsdp_paddr = search_rsdp(*ebda, *ebda + EBDA_SIZE); + } + } + + bios_cfg_read_entry(&cmdline_size, FW_CFG_CMDLINE_SIZE, 4, fw_cfg_version); + bios_cfg_read_entry(cmdline_addr, FW_CFG_CMDLINE_DATA, cmdline_size, + fw_cfg_version); + start_info.cmdline_paddr = (uintptr_t)cmdline_addr; + + bios_cfg_read_entry(&kernel_entry, FW_CFG_KERNEL_ENTRY, 4, fw_cfg_version); + + asm volatile("jmp *%1" : : "b"(&start_info), "c"(kernel_entry)); +} diff --git a/pc-bios/pvh.bin b/pc-bios/pvh.bin new file mode 100644 index 0000000000000000000000000000000000000000..38a41761014957d50eb55d790b6957888cbeee0a GIT binary patch literal 1536 zcmeHFO=uHA6n6(H}8AjdpoTU zx4nc-R}e_ND=t*H!BfH+!No@%FjUZISAWu>0?idgIy6ml^CD#nRCq@fD@>KeLo{cJ zx<%EHEKnhzpezJ1;e`YXiJ*q+1O(dw!^hpQ7pT$a2cWrlj?Wv^Sfe_CWwc zMo)jE&+1vdsF$n<=mMch!vS2`2j zK!@F5v$80&x6v7?AWe<181b?evP*iw8i<%%klA}>YNs^C{Dc*yLMGq=SW-nI6_nz7 z%BQ6w;Ckur%B0+$A8tL@hLl04m5hw{>C(7}61AJepV^K6N>WV`zv-#NDc*SAb=dU8 z5b@4O`C!McqcH|Kx{Aj1B+>F^0QgY1D)%opHOIngz1aUP-qIAVoR)6wz;q=m*Mipv z=?|voayiHJbe2&xOGkaE10O;y;NEju1??_JHTm9Z>j)BPk9irSsmV*X_u;`NrP9Ud z%ot~9Rh(Jtfr&cgU_oNW2m;LiR3Q!ALGXk(Z}9T$GhKShTmL->w!D%ws>&g?f%w@+ zeuT4BTZlMz-YL+5)_DUw-%XYIy$L=$Oq1<-Wir@)@zRC7_9%jMI3GvdpT4aQ+qTO= z{<(%7q70X%#fZPOwr1O0K*musTl&iVe`IVV@%M;Ha;boqtX@vs1JUeX6R{T8otMbP NY^|*c{O<$?e*uLwDi8nw literal 0 HcmV?d00001 From 1fb0d709906379ce7d520a0e9bf62c6275c1983f Mon Sep 17 00:00:00 2001 From: Stefano Garzarella Date: Fri, 18 Jan 2019 13:01:42 +0100 Subject: [PATCH 19/76] hw/i386/pc: use PVH option rom Use pvh.bin option rom when we are booting an uncompressed kernel using the x86/HVM direct boot ABI. Signed-off-by: Stefano Garzarella Reviewed-by: Stefan Hajnoczi Reviewed-by: Liam Merwick Based-on: <1547554687-12687-1-git-send-email-liam.merwick@oracle.com> Signed-off-by: Paolo Bonzini --- hw/i386/pc.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 5d61557a243..9efbd16fa7b 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1261,6 +1261,10 @@ static void load_linux(PCMachineState *pcms, initrd_size); } + option_rom[nb_option_roms].bootindex = 0; + option_rom[nb_option_roms].name = "pvh.bin"; + nb_option_roms++; + return; } /* This looks like a multiboot kernel. If it is, let's stop @@ -1712,6 +1716,7 @@ void xen_load_linux(PCMachineState *pcms) for (i = 0; i < nb_option_roms; i++) { assert(!strcmp(option_rom[i].name, "linuxboot.bin") || !strcmp(option_rom[i].name, "linuxboot_dma.bin") || + !strcmp(option_rom[i].name, "pvh.bin") || !strcmp(option_rom[i].name, "multiboot.bin")); rom_add_option(option_rom[i].name, option_rom[i].bootindex); } From b1b876ca70f1b240852ad24e7d3ff788f2c47153 Mon Sep 17 00:00:00 2001 From: Stefano Garzarella Date: Fri, 18 Jan 2019 13:01:43 +0100 Subject: [PATCH 20/76] optionrom/pvh: load initrd from fw_cfg If we found initrd through fw_cfg, we can load it and use the first module of hvm_start_info to pass initrd address and size to the kernel. Signed-off-by: Stefano Garzarella Reviewed-by: Stefan Hajnoczi Reviewed-by: Liam Merwick Based-on: <1547554687-12687-1-git-send-email-liam.merwick@oracle.com> Signed-off-by: Paolo Bonzini --- pc-bios/optionrom/pvh_main.c | 21 +++++++++++++++++++-- pc-bios/pvh.bin | Bin 1536 -> 1536 bytes 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/pc-bios/optionrom/pvh_main.c b/pc-bios/optionrom/pvh_main.c index 1dcc5c92565..a015e1bf223 100644 --- a/pc-bios/optionrom/pvh_main.c +++ b/pc-bios/optionrom/pvh_main.c @@ -46,6 +46,7 @@ struct pvh_e820_table { struct pvh_e820_table pvh_e820 asm("pvh_e820") __attribute__ ((aligned)); static struct hvm_start_info start_info; +static struct hvm_modlist_entry ramdisk_mod; static uint8_t cmdline_buffer[CMDLINE_BUFSIZE]; @@ -71,8 +72,8 @@ extern void pvh_load_kernel(void) asm("pvh_load_kernel"); void pvh_load_kernel(void) { void *cmdline_addr = &cmdline_buffer; - void *kernel_entry; - uint32_t cmdline_size, fw_cfg_version = bios_cfg_version(); + void *kernel_entry, *initrd_addr; + uint32_t cmdline_size, initrd_size, fw_cfg_version = bios_cfg_version(); start_info.magic = XEN_HVM_START_MAGIC_VALUE; start_info.version = 1; @@ -110,6 +111,22 @@ void pvh_load_kernel(void) fw_cfg_version); start_info.cmdline_paddr = (uintptr_t)cmdline_addr; + /* Check if we have the initrd to load */ + bios_cfg_read_entry(&initrd_size, FW_CFG_INITRD_SIZE, 4, fw_cfg_version); + if (initrd_size) { + bios_cfg_read_entry(&initrd_addr, FW_CFG_INITRD_ADDR, 4, + fw_cfg_version); + bios_cfg_read_entry(initrd_addr, FW_CFG_INITRD_DATA, initrd_size, + fw_cfg_version); + + ramdisk_mod.paddr = (uintptr_t)initrd_addr; + ramdisk_mod.size = initrd_size; + + /* The first module is always ramdisk. */ + start_info.modlist_paddr = (uintptr_t)&ramdisk_mod; + start_info.nr_modules = 1; + } + bios_cfg_read_entry(&kernel_entry, FW_CFG_KERNEL_ENTRY, 4, fw_cfg_version); asm volatile("jmp *%1" : : "b"(&start_info), "c"(kernel_entry)); diff --git a/pc-bios/pvh.bin b/pc-bios/pvh.bin index 38a41761014957d50eb55d790b6957888cbeee0a..8033080ada2db4c4613fdc3bb5a69d79c7b0c0ca 100644 GIT binary patch delta 735 zcmZqRY2cYKndyM&#;Nv<`Y|dZ$5|Uh85k;#<{2MnZ2__v85kHA9sn{HZvYZIPJmb| zfW&duHKLQ5nUrMIfhw902-q@k@G+F$J|Cout)f{N^UIC!Q4iTVG=c}~$y9I%~ogfvxH7Wv~w?60W5Uq#G zb^8ECzJtWNSyZ}1R9F_z0NXGJNbcZV*bKQ3xZ=Q(yf415}LN%^5^G8scV%O`y;R+Qji<3DDe^<^K@j Z2no&!h6hlR%ga4L7i~VsEX~MR4FFIY;aUIy delta 434 zcmZqRY2cYKnW;f!<5YV_{Sp>3=9kl8-R?(1wdj)2Z)sc zB#yJ@h)iZ?Qj%c@s%SnSV9UV4$549rIBNn>5(JL3rie^-WRk9*!N9`6V0pM)?4=n{ zY40|WBv6CpVg5E%pg^}k~;W} z(J7;H+(iY*0P26n#NRp{$k;2u3Un37%Fb75@AnA;c{@QWdTUffIzN5R*&&(+mFxBa zirfc@b+f2+hp4bDjsV*b10;6{Ko!CC3V_t@289Gro525v%|~RS Date: Tue, 22 Jan 2019 13:10:48 +0100 Subject: [PATCH 21/76] hw/i386/pc: enable PVH only for machine type >= 4.0 In order to avoid migration issues, we enable PVH only for machine type >= 4.0 Suggested-by: Michael S. Tsirkin Signed-off-by: Stefano Garzarella Signed-off-by: Paolo Bonzini --- hw/i386/pc.c | 4 +++- hw/i386/pc_piix.c | 3 +++ hw/i386/pc_q35.c | 3 +++ include/hw/i386/pc.h | 3 +++ 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 9efbd16fa7b..00166d19d82 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1220,7 +1220,8 @@ static void load_linux(PCMachineState *pcms, * saving the PVH entry point used by the x86/HVM direct boot ABI. * If load_elfboot() is successful, populate the fw_cfg info. */ - if (load_elfboot(kernel_filename, kernel_size, + if (pcmc->pvh_enabled && + load_elfboot(kernel_filename, kernel_size, header, pvh_start_addr, fw_cfg)) { fclose(f); @@ -2783,6 +2784,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data) pcmc->acpi_data_size = 0x20000 + 0x8000; pcmc->save_tsc_khz = true; pcmc->linuxboot_dma_enabled = true; + pcmc->pvh_enabled = true; assert(!mc->get_hotplug_handler); mc->get_hotplug_handler = pc_get_hotplug_handler; mc->cpu_index_to_instance_props = pc_cpu_index_to_props; diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 63c84e38275..fd0f2c268ff 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -440,9 +440,12 @@ DEFINE_I440FX_MACHINE(v4_0, "pc-i440fx-4.0", NULL, static void pc_i440fx_3_1_machine_options(MachineClass *m) { + PCMachineClass *pcmc = PC_MACHINE_CLASS(m); + pc_i440fx_4_0_machine_options(m); m->is_default = 0; m->alias = NULL; + pcmc->pvh_enabled = false; compat_props_add(m->compat_props, hw_compat_3_1, hw_compat_3_1_len); compat_props_add(m->compat_props, pc_compat_3_1, pc_compat_3_1_len); } diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index b7b7959934f..4a175ea50e1 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -376,9 +376,12 @@ DEFINE_Q35_MACHINE(v4_0, "pc-q35-4.0", NULL, static void pc_q35_3_1_machine_options(MachineClass *m) { + PCMachineClass *pcmc = PC_MACHINE_CLASS(m); + pc_q35_4_0_machine_options(m); m->default_kernel_irqchip_split = false; m->alias = NULL; + pcmc->pvh_enabled = false; compat_props_add(m->compat_props, hw_compat_3_1, hw_compat_3_1_len); compat_props_add(m->compat_props, pc_compat_3_1, pc_compat_3_1_len); } diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 882fd8dfd2b..3ff127ebd03 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -133,6 +133,9 @@ typedef struct PCMachineClass { /* use DMA capable linuxboot option rom */ bool linuxboot_dma_enabled; + + /* use PVH to load kernels that support this feature */ + bool pvh_enabled; } PCMachineClass; #define TYPE_PC_MACHINE "generic-pc-machine" From 76e5a4d58357b9d077afccf7f7c82e17f733b722 Mon Sep 17 00:00:00 2001 From: Robert Hoo Date: Wed, 19 Dec 2018 21:44:40 +0800 Subject: [PATCH 22/76] i386: remove the new CPUID 'PCONFIG' from Icelake-Server CPU model PCONFIG is not available to guests; it must be specifically enabled using the PCONFIG_ENABLE execution control. Disable it, because no one can ever use it. Signed-off-by: Robert Hoo Message-Id: <1545227081-213696-2-git-send-email-robert.hu@linux.intel.com> Cc: qemu-stable@nongnu.org Signed-off-by: Paolo Bonzini --- target/i386/cpu.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 7483daef580..4d21ae43600 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -2650,8 +2650,7 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_7_0_ECX_AVX512VNNI | CPUID_7_0_ECX_AVX512BITALG | CPUID_7_0_ECX_AVX512_VPOPCNTDQ | CPUID_7_0_ECX_LA57, .features[FEAT_7_0_EDX] = - CPUID_7_0_EDX_PCONFIG | CPUID_7_0_EDX_SPEC_CTRL | - CPUID_7_0_EDX_SPEC_CTRL_SSBD, + CPUID_7_0_EDX_SPEC_CTRL | CPUID_7_0_EDX_SPEC_CTRL_SSBD, /* Missing: XSAVES (not supported by some Linux versions, * including v4.1 to v4.12). * KVM doesn't yet expose any XSAVES state save component, From 4c257911dcc7c4189768e9651755c849ce9db4e8 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 21 Dec 2018 12:35:56 +0100 Subject: [PATCH 23/76] i386: remove the 'INTEL_PT' CPUID bit from named CPU models Processor tracing is not yet implemented for KVM and it will be an opt in feature requiring a special module parameter. Disable it, because it is wrong to enable it by default and it is impossible that no one has ever used it. Cc: qemu-stable@nongnu.org Signed-off-by: Paolo Bonzini --- target/i386/cpu.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 4d21ae43600..7301e7d49e7 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -2530,8 +2530,7 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_CLWB | CPUID_7_0_EBX_AVX512F | CPUID_7_0_EBX_AVX512DQ | CPUID_7_0_EBX_AVX512BW | CPUID_7_0_EBX_AVX512CD | - CPUID_7_0_EBX_AVX512VL | CPUID_7_0_EBX_CLFLUSHOPT | - CPUID_7_0_EBX_INTEL_PT, + CPUID_7_0_EBX_AVX512VL | CPUID_7_0_EBX_CLFLUSHOPT, .features[FEAT_7_0_ECX] = CPUID_7_0_ECX_PKU | CPUID_7_0_ECX_OSPKE | CPUID_7_0_ECX_AVX512VNNI, @@ -2583,7 +2582,7 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID | CPUID_7_0_EBX_RTM | CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX | - CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_INTEL_PT, + CPUID_7_0_EBX_SMAP, .features[FEAT_7_0_ECX] = CPUID_7_0_ECX_VBMI | CPUID_7_0_ECX_UMIP | CPUID_7_0_ECX_PKU | CPUID_7_0_ECX_OSPKE | CPUID_7_0_ECX_VBMI2 | CPUID_7_0_ECX_GFNI | @@ -2641,8 +2640,7 @@ static X86CPUDefinition builtin_x86_defs[] = { CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_CLWB | CPUID_7_0_EBX_AVX512F | CPUID_7_0_EBX_AVX512DQ | CPUID_7_0_EBX_AVX512BW | CPUID_7_0_EBX_AVX512CD | - CPUID_7_0_EBX_AVX512VL | CPUID_7_0_EBX_CLFLUSHOPT | - CPUID_7_0_EBX_INTEL_PT, + CPUID_7_0_EBX_AVX512VL | CPUID_7_0_EBX_CLFLUSHOPT, .features[FEAT_7_0_ECX] = CPUID_7_0_ECX_VBMI | CPUID_7_0_ECX_UMIP | CPUID_7_0_ECX_PKU | CPUID_7_0_ECX_OSPKE | CPUID_7_0_ECX_VBMI2 | CPUID_7_0_ECX_GFNI | From 712f807e1965c8f1f1da5bbec2b92a8c540e6631 Mon Sep 17 00:00:00 2001 From: Robert Hoo Date: Wed, 19 Dec 2018 21:44:41 +0800 Subject: [PATCH 24/76] Revert "i386: Add CPUID bit for PCONFIG" This reverts commit 5131dc433df54b37e8e918d8fba7fe10344e7a7b. For new instruction 'PCONFIG' will not be exposed to guest. Signed-off-by: Robert Hoo Message-Id: <1545227081-213696-3-git-send-email-robert.hu@linux.intel.com> Signed-off-by: Paolo Bonzini --- target/i386/cpu.c | 2 +- target/i386/cpu.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 7301e7d49e7..6f3b841723b 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -1077,7 +1077,7 @@ static FeatureWordInfo feature_word_info[FEATURE_WORDS] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, "pconfig", NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "spec-ctrl", "stibp", NULL, "arch-capabilities", NULL, "ssbd", diff --git a/target/i386/cpu.h b/target/i386/cpu.h index 59656a70e6f..95112b91188 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -694,7 +694,6 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS]; #define CPUID_7_0_EDX_AVX512_4VNNIW (1U << 2) /* AVX512 Neural Network Instructions */ #define CPUID_7_0_EDX_AVX512_4FMAPS (1U << 3) /* AVX512 Multiply Accumulation Single Precision */ -#define CPUID_7_0_EDX_PCONFIG (1U << 18) /* Platform Configuration */ #define CPUID_7_0_EDX_SPEC_CTRL (1U << 26) /* Speculation Control */ #define CPUID_7_0_EDX_ARCH_CAPABILITIES (1U << 29) /*Arch Capabilities*/ #define CPUID_7_0_EDX_SPEC_CTRL_SSBD (1U << 31) /* Speculative Store Bypass Disable */ From c29b48db1db562caf5076a429747247dcecc3b08 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 20 Dec 2018 13:10:40 +0100 Subject: [PATCH 25/76] target-i386: hvf: remove MPX support MPX support is being phased out by Intel and actually I am not sure that OS X has ever enabled it in XCR0. Drop it from the Hypervisor.framework acceleration. Signed-off-by: Paolo Bonzini --- target/i386/hvf/x86_cpuid.c | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/target/i386/hvf/x86_cpuid.c b/target/i386/hvf/x86_cpuid.c index 9874a46e924..4d957fe8969 100644 --- a/target/i386/hvf/x86_cpuid.c +++ b/target/i386/hvf/x86_cpuid.c @@ -38,16 +38,6 @@ static uint64_t xgetbv(uint32_t xcr) return (((uint64_t)edx) << 32) | eax; } -static bool vmx_mpx_supported() -{ - uint64_t cap_exit, cap_entry; - - hv_vmx_read_capability(HV_VMX_CAP_ENTRY, &cap_entry); - hv_vmx_read_capability(HV_VMX_CAP_EXIT, &cap_exit); - - return ((cap_exit & (1 << 23)) && (cap_entry & (1 << 16))); -} - uint32_t hvf_get_supported_cpuid(uint32_t func, uint32_t idx, int reg) { @@ -92,11 +82,8 @@ uint32_t hvf_get_supported_cpuid(uint32_t func, uint32_t idx, CPUID_7_0_EBX_CLFLUSHOPT | CPUID_7_0_EBX_CLWB | CPUID_7_0_EBX_AVX512DQ | CPUID_7_0_EBX_SHA_NI | CPUID_7_0_EBX_AVX512BW | CPUID_7_0_EBX_AVX512VL | - CPUID_7_0_EBX_INVPCID | CPUID_7_0_EBX_MPX; + CPUID_7_0_EBX_INVPCID; - if (!vmx_mpx_supported()) { - ebx &= ~CPUID_7_0_EBX_MPX; - } hv_vmx_read_capability(HV_VMX_CAP_PROCBASED2, &cap); if (!(cap & CPU_BASED2_INVPCID)) { ebx &= ~CPUID_7_0_EBX_INVPCID; @@ -119,9 +106,6 @@ uint32_t hvf_get_supported_cpuid(uint32_t func, uint32_t idx, XSTATE_BNDCSR_MASK | XSTATE_OPMASK_MASK | XSTATE_ZMM_Hi256_MASK | XSTATE_Hi16_ZMM_MASK); eax &= supp_xcr0; - if (!vmx_mpx_supported()) { - eax &= ~(XSTATE_BNDREGS_MASK | XSTATE_BNDCSR_MASK); - } } else if (idx == 1) { hv_vmx_read_capability(HV_VMX_CAP_PROCBASED2, &cap); eax &= CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XGETBV1; From e53f3466e3233a66e3d77f1ee53c330c29179fcc Mon Sep 17 00:00:00 2001 From: Viktor Prutyanov Date: Thu, 20 Dec 2018 04:24:36 +0300 Subject: [PATCH 26/76] contrib/elf2dmp: fix elf.h including Before this patch QEMU elf.h was not actually included. Signed-off-by: Viktor Prutyanov Message-Id: <20181220012441.13694-2-viktor.prutyanov@phystech.edu> Signed-off-by: Paolo Bonzini --- contrib/elf2dmp/qemu_elf.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/contrib/elf2dmp/qemu_elf.h b/contrib/elf2dmp/qemu_elf.h index 86e6e688fb6..da70affaa4d 100644 --- a/contrib/elf2dmp/qemu_elf.h +++ b/contrib/elf2dmp/qemu_elf.h @@ -5,10 +5,10 @@ * */ -#ifndef QEMU_ELF_H -#define QEMU_ELF_H +#ifndef ELF2DMP_ELF_H +#define ELF2DMP_ELF_H -#include +#include "elf.h" typedef struct QEMUCPUSegment { uint32_t selector; @@ -47,4 +47,4 @@ void QEMU_Elf_exit(QEMU_Elf *qe); Elf64_Phdr *elf64_getphdr(void *map); Elf64_Half elf_getphdrnum(void *map); -#endif /* QEMU_ELF_H */ +#endif /* ELF2DMP_ELF_H */ From bd4d0da7db2bbbfd8715f5040edda9f146628d98 Mon Sep 17 00:00:00 2001 From: Viktor Prutyanov Date: Thu, 20 Dec 2018 04:24:37 +0300 Subject: [PATCH 27/76] contrib/elf2dmp: use GLib in ELF processing Replace POSIX mmap with GLib g_mapped_file_new in ELF processing module to make elf2dmp cross-platform. Signed-off-by: Viktor Prutyanov Message-Id: <20181220012441.13694-3-viktor.prutyanov@phystech.edu> Signed-off-by: Paolo Bonzini --- contrib/elf2dmp/qemu_elf.c | 27 ++++++++------------------- contrib/elf2dmp/qemu_elf.h | 2 +- 2 files changed, 9 insertions(+), 20 deletions(-) diff --git a/contrib/elf2dmp/qemu_elf.c b/contrib/elf2dmp/qemu_elf.c index e9c0d2534a2..0db78165862 100644 --- a/contrib/elf2dmp/qemu_elf.c +++ b/contrib/elf2dmp/qemu_elf.c @@ -120,25 +120,17 @@ static void exit_states(QEMU_Elf *qe) int QEMU_Elf_init(QEMU_Elf *qe, const char *filename) { + GError *gerr = NULL; int err = 0; - struct stat st; - qe->fd = open(filename, O_RDONLY, 0); - if (qe->fd == -1) { - eprintf("Failed to open ELF dump file \'%s\'\n", filename); + qe->gmf = g_mapped_file_new(filename, TRUE, &gerr); + if (gerr) { + eprintf("Failed to map ELF dump file \'%s\'\n", filename); return 1; } - fstat(qe->fd, &st); - qe->size = st.st_size; - - qe->map = mmap(NULL, qe->size, PROT_READ | PROT_WRITE, - MAP_PRIVATE, qe->fd, 0); - if (qe->map == MAP_FAILED) { - eprintf("Failed to map ELF file\n"); - err = 1; - goto out_fd; - } + qe->map = g_mapped_file_get_contents(qe->gmf); + qe->size = g_mapped_file_get_length(qe->gmf); if (init_states(qe)) { eprintf("Failed to extract QEMU CPU states\n"); @@ -149,9 +141,7 @@ int QEMU_Elf_init(QEMU_Elf *qe, const char *filename) return 0; out_unmap: - munmap(qe->map, qe->size); -out_fd: - close(qe->fd); + g_mapped_file_unref(qe->gmf); return err; } @@ -159,6 +149,5 @@ int QEMU_Elf_init(QEMU_Elf *qe, const char *filename) void QEMU_Elf_exit(QEMU_Elf *qe) { exit_states(qe); - munmap(qe->map, qe->size); - close(qe->fd); + g_mapped_file_unref(qe->gmf); } diff --git a/contrib/elf2dmp/qemu_elf.h b/contrib/elf2dmp/qemu_elf.h index da70affaa4d..2a7963821a4 100644 --- a/contrib/elf2dmp/qemu_elf.h +++ b/contrib/elf2dmp/qemu_elf.h @@ -33,7 +33,7 @@ typedef struct QEMUCPUState { int is_system(QEMUCPUState *s); typedef struct QEMU_Elf { - int fd; + GMappedFile *gmf; size_t size; void *map; QEMUCPUState **state; From 4ea1a21d8413b84d36d57a708c40a5a19b266584 Mon Sep 17 00:00:00 2001 From: Viktor Prutyanov Date: Thu, 20 Dec 2018 04:24:38 +0300 Subject: [PATCH 28/76] contrib/elf2dmp: use GLib in PDB processing Replace POSIX mmap with GLib g_mapped_file_new in PDB processing stage to make elf2dmp cross-platform. There are no direct POSIX in elf2dmp after this patch. Signed-off-by: Viktor Prutyanov Message-Id: <20181220012441.13694-4-viktor.prutyanov@phystech.edu> Signed-off-by: Paolo Bonzini --- contrib/elf2dmp/pdb.c | 29 ++++++++--------------------- contrib/elf2dmp/pdb.h | 2 +- 2 files changed, 9 insertions(+), 22 deletions(-) diff --git a/contrib/elf2dmp/pdb.c b/contrib/elf2dmp/pdb.c index bcb01b414fb..52e352df79d 100644 --- a/contrib/elf2dmp/pdb.c +++ b/contrib/elf2dmp/pdb.c @@ -277,28 +277,18 @@ static void pdb_reader_exit(struct pdb_reader *r) int pdb_init_from_file(const char *name, struct pdb_reader *reader) { + GError *gerr = NULL; int err = 0; - int fd; void *map; - struct stat st; - fd = open(name, O_RDONLY, 0); - if (fd == -1) { - eprintf("Failed to open PDB file \'%s\'\n", name); + reader->gmf = g_mapped_file_new(name, TRUE, &gerr); + if (gerr) { + eprintf("Failed to map PDB file \'%s\'\n", name); return 1; } - reader->fd = fd; - - fstat(fd, &st); - reader->file_size = st.st_size; - - map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); - if (map == MAP_FAILED) { - eprintf("Failed to map PDB file\n"); - err = 1; - goto out_fd; - } + reader->file_size = g_mapped_file_get_length(reader->gmf); + map = g_mapped_file_get_contents(reader->gmf); if (pdb_reader_init(reader, map)) { err = 1; goto out_unmap; @@ -307,16 +297,13 @@ int pdb_init_from_file(const char *name, struct pdb_reader *reader) return 0; out_unmap: - munmap(map, st.st_size); -out_fd: - close(fd); + g_mapped_file_unref(reader->gmf); return err; } void pdb_exit(struct pdb_reader *reader) { - munmap(reader->ds.header, reader->file_size); - close(reader->fd); + g_mapped_file_unref(reader->gmf); pdb_reader_exit(reader); } diff --git a/contrib/elf2dmp/pdb.h b/contrib/elf2dmp/pdb.h index a3a3cac2c1b..1640d544eb0 100644 --- a/contrib/elf2dmp/pdb.h +++ b/contrib/elf2dmp/pdb.h @@ -216,7 +216,7 @@ typedef struct pdb_seg { #define IMAGE_FILE_MACHINE_AMD64 0x8664 struct pdb_reader { - int fd; + GMappedFile *gmf; size_t file_size; struct { PDB_DS_HEADER *header; From 4591f4ceefb80ebdded948080a839a21a331ecbb Mon Sep 17 00:00:00 2001 From: Viktor Prutyanov Date: Thu, 20 Dec 2018 04:24:39 +0300 Subject: [PATCH 29/76] contrib/elf2dmp: fix structures definitions Remove duplicate structures definitions in case of build for Windows hosts. Signed-off-by: Viktor Prutyanov Message-Id: <20181220012441.13694-5-viktor.prutyanov@phystech.edu> Signed-off-by: Paolo Bonzini --- contrib/elf2dmp/kdbg.h | 12 ++++++++---- contrib/elf2dmp/pdb.h | 2 ++ contrib/elf2dmp/pe.h | 6 ++++-- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/contrib/elf2dmp/kdbg.h b/contrib/elf2dmp/kdbg.h index 851b57c321c..002e3d0cd5f 100644 --- a/contrib/elf2dmp/kdbg.h +++ b/contrib/elf2dmp/kdbg.h @@ -25,11 +25,15 @@ typedef struct DBGKD_GET_VERSION64 { uint64_t DebuggerDataList; } DBGKD_GET_VERSION64; +#ifndef _WIN32 +typedef struct LIST_ENTRY64 { + struct LIST_ENTRY64 *Flink; + struct LIST_ENTRY64 *Blink; +} LIST_ENTRY64; +#endif + typedef struct DBGKD_DEBUG_DATA_HEADER64 { - struct LIST_ENTRY64 { - struct LIST_ENTRY64 *Flink; - struct LIST_ENTRY64 *Blink; - } List; + LIST_ENTRY64 List; uint32_t OwnerTag; uint32_t Size; } DBGKD_DEBUG_DATA_HEADER64; diff --git a/contrib/elf2dmp/pdb.h b/contrib/elf2dmp/pdb.h index 1640d544eb0..4ea8925ee82 100644 --- a/contrib/elf2dmp/pdb.h +++ b/contrib/elf2dmp/pdb.h @@ -9,12 +9,14 @@ #define PDB_H +#ifndef _WIN32 typedef struct GUID { unsigned int Data1; unsigned short Data2; unsigned short Data3; unsigned char Data4[8]; } GUID; +#endif struct PDB_FILE { uint32_t size; diff --git a/contrib/elf2dmp/pe.h b/contrib/elf2dmp/pe.h index dafb26afbb3..c2a4a6ba7c2 100644 --- a/contrib/elf2dmp/pe.h +++ b/contrib/elf2dmp/pe.h @@ -9,6 +9,7 @@ #define PE_H +#ifndef _WIN32 typedef struct IMAGE_DOS_HEADER { uint16_t e_magic; /* 0x00: MZ Header signature */ uint16_t e_cblp; /* 0x02: Bytes on last page of file */ @@ -87,8 +88,6 @@ typedef struct IMAGE_NT_HEADERS64 { IMAGE_OPTIONAL_HEADER64 OptionalHeader; } __attribute__ ((packed)) IMAGE_NT_HEADERS64; -#define IMAGE_FILE_DEBUG_DIRECTORY 6 - typedef struct IMAGE_DEBUG_DIRECTORY { uint32_t Characteristics; uint32_t TimeDateStamp; @@ -101,6 +100,9 @@ typedef struct IMAGE_DEBUG_DIRECTORY { } __attribute__ ((packed)) IMAGE_DEBUG_DIRECTORY; #define IMAGE_DEBUG_TYPE_CODEVIEW 2 +#endif + +#define IMAGE_FILE_DEBUG_DIRECTORY 6 typedef struct guid_t { uint32_t a; From 6ec6e988fb3ada137ccf38252ca622b1ef96de12 Mon Sep 17 00:00:00 2001 From: Viktor Prutyanov Date: Thu, 20 Dec 2018 04:24:40 +0300 Subject: [PATCH 30/76] contrib/elf2dmp: fix printf format Format strings for printf are changed for successful build for Windows hosts. Signed-off-by: Viktor Prutyanov Message-Id: <20181220012441.13694-6-viktor.prutyanov@phystech.edu> Signed-off-by: Paolo Bonzini --- contrib/elf2dmp/main.c | 27 +++++++++++++++------------ contrib/elf2dmp/pdb.c | 4 +++- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/contrib/elf2dmp/main.c b/contrib/elf2dmp/main.c index 7115b0d6d0b..1a45eaf565d 100644 --- a/contrib/elf2dmp/main.c +++ b/contrib/elf2dmp/main.c @@ -5,6 +5,8 @@ * */ +#include + #include "qemu/osdep.h" #include "err.h" #include "addrspace.h" @@ -41,7 +43,8 @@ static const uint64_t SharedUserData = 0xfffff78000000000; #define KUSD_OFFSET_PRODUCT_TYPE 0x264 #define SYM_RESOLVE(base, r, s) ((s = pdb_resolve(base, r, #s)),\ - s ? printf(#s" = 0x%016lx\n", s) : eprintf("Failed to resolve "#s"\n"), s) + s ? printf(#s" = 0x%016"PRIx64"\n", s) :\ + eprintf("Failed to resolve "#s"\n"), s) static uint64_t rol(uint64_t x, uint64_t y) { @@ -98,8 +101,8 @@ static KDDEBUGGER_DATA64 *get_kdbg(uint64_t KernBase, struct pdb_reader *pdb, return NULL; } - printf("[KiWaitNever] = 0x%016lx\n", kwn); - printf("[KiWaitAlways] = 0x%016lx\n", kwa); + printf("[KiWaitNever] = 0x%016"PRIx64"\n", kwn); + printf("[KiWaitAlways] = 0x%016"PRIx64"\n", kwa); /* * If KDBG header can be decoded, KDBG size is available @@ -202,7 +205,7 @@ static int fix_dtb(struct va_space *vs, QEMU_Elf *qe) if (is_system(s)) { va_space_set_dtb(vs, s->cr[3]); - printf("DTB 0x%016lx has been found from CPU #%zu" + printf("DTB 0x%016"PRIx64" has been found from CPU #%zu" " as system task CR3\n", vs->dtb, i); return !(va_space_resolve(vs, SharedUserData)); } @@ -222,7 +225,7 @@ static int fix_dtb(struct va_space *vs, QEMU_Elf *qe) } va_space_set_dtb(vs, *cr3); - printf("DirectoryTableBase = 0x%016lx has been found from CPU #0" + printf("DirectoryTableBase = 0x%016"PRIx64" has been found from CPU #0" " as interrupt handling CR3\n", vs->dtb); return !(va_space_resolve(vs, SharedUserData)); } @@ -393,8 +396,8 @@ static int pe_get_pdb_symstore_hash(uint64_t base, void *start_addr, return 1; } - printf("Debug Directory RVA = 0x%016x\n", - data_dir[IMAGE_FILE_DEBUG_DIRECTORY].VirtualAddress); + printf("Debug Directory RVA = 0x%08"PRIx32"\n", + (uint32_t)data_dir[IMAGE_FILE_DEBUG_DIRECTORY].VirtualAddress); if (va_space_rw(vs, base + data_dir[IMAGE_FILE_DEBUG_DIRECTORY].VirtualAddress, @@ -488,7 +491,7 @@ int main(int argc, char *argv[]) } state = qemu_elf.state[0]; - printf("CPU #0 CR3 is 0x%016lx\n", state->cr[3]); + printf("CPU #0 CR3 is 0x%016"PRIx64"\n", state->cr[3]); va_space_create(&vs, &ps, state->cr[3]); if (fix_dtb(&vs, &qemu_elf)) { @@ -497,7 +500,7 @@ int main(int argc, char *argv[]) goto out_elf; } - printf("CPU #0 IDT is at 0x%016lx\n", state->idt.base); + printf("CPU #0 IDT is at 0x%016"PRIx64"\n", state->idt.base); if (va_space_rw(&vs, state->idt.base, &first_idt_desc, sizeof(first_idt_desc), 0)) { @@ -505,10 +508,10 @@ int main(int argc, char *argv[]) err = 1; goto out_ps; } - printf("CPU #0 IDT[0] -> 0x%016lx\n", idt_desc_addr(first_idt_desc)); + printf("CPU #0 IDT[0] -> 0x%016"PRIx64"\n", idt_desc_addr(first_idt_desc)); KernBase = idt_desc_addr(first_idt_desc) & ~(PAGE_SIZE - 1); - printf("Searching kernel downwards from 0x%16lx...\n", KernBase); + printf("Searching kernel downwards from 0x%016"PRIx64"...\n", KernBase); for (; KernBase >= 0xfffff78000000000; KernBase -= PAGE_SIZE) { nt_start_addr = va_space_resolve(&vs, KernBase); @@ -521,7 +524,7 @@ int main(int argc, char *argv[]) } } - printf("KernBase = 0x%16lx, signature is \'%.2s\'\n", KernBase, + printf("KernBase = 0x%016"PRIx64", signature is \'%.2s\'\n", KernBase, (char *)nt_start_addr); if (pe_get_pdb_symstore_hash(KernBase, nt_start_addr, pdb_hash, &vs)) { diff --git a/contrib/elf2dmp/pdb.c b/contrib/elf2dmp/pdb.c index 52e352df79d..64af20f5842 100644 --- a/contrib/elf2dmp/pdb.c +++ b/contrib/elf2dmp/pdb.c @@ -18,6 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include + #include "qemu/osdep.h" #include "pdb.h" #include "err.h" @@ -66,7 +68,7 @@ uint64_t pdb_find_public_v3_symbol(struct pdb_reader *r, const char *name) uint32_t sect_rva = segment->dword[1]; uint64_t rva = sect_rva + sym->public_v3.offset; - printf("%s: 0x%016x(%d:\'%.8s\') + 0x%08x = 0x%09lx\n", name, + printf("%s: 0x%016x(%d:\'%.8s\') + 0x%08x = 0x%09"PRIx64"\n", name, sect_rva, sym->public_v3.segment, ((char *)segment - 8), sym->public_v3.offset, rva); return rva; From 1b9d35f33c85e63377b02eba276dd1bb102247f9 Mon Sep 17 00:00:00 2001 From: Viktor Prutyanov Date: Thu, 20 Dec 2018 04:24:41 +0300 Subject: [PATCH 31/76] configure: enable elf2dmp build for Windows hosts After this patch contrib/elf2dmp can be built for Windows x86 and x86_64 hosts by mingw. Signed-off-by: Viktor Prutyanov Message-Id: <20181220012441.13694-7-viktor.prutyanov@phystech.edu> Signed-off-by: Paolo Bonzini --- Makefile | 4 ++-- configure | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 76f6ab4b7e8..3658310b95f 100644 --- a/Makefile +++ b/Makefile @@ -570,8 +570,8 @@ ifneq ($(EXESUF),) qemu-ga: qemu-ga$(EXESUF) $(QGA_VSS_PROVIDER) $(QEMU_GA_MSI) endif -elf2dmp: LIBS = $(CURL_LIBS) -elf2dmp: $(elf2dmp-obj-y) +elf2dmp$(EXESUF): LIBS += $(CURL_LIBS) +elf2dmp$(EXESUF): $(elf2dmp-obj-y) $(call LINK, $^) ifdef CONFIG_IVSHMEM diff --git a/configure b/configure index f6a51e07651..244bc7acd5d 100755 --- a/configure +++ b/configure @@ -5790,8 +5790,8 @@ if test "$want_tools" = "yes" ; then if [ "$ivshmem" = "yes" ]; then tools="ivshmem-client\$(EXESUF) ivshmem-server\$(EXESUF) $tools" fi - if [ "$posix" = "yes" ] && [ "$curl" = "yes" ]; then - tools="elf2dmp $tools" + if [ "$curl" = "yes" ]; then + tools="elf2dmp\$(EXESUF) $tools" fi fi if test "$softmmu" = yes ; then From 82e870bac441f231deb72b64c9baf2f2fbd5bdbb Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 28 Dec 2018 14:40:41 +0100 Subject: [PATCH 32/76] monitor: do not use QTAILQ_FOREACH_SAFE across critical sections monitor_qmp_requests_pop_any_with_lock cannot modify the monitor list concurrently with monitor_cleanup, since the dispatch bottom half runs in the main thread, but anyway it is a bit ugly to keep "next" live across critical sections of monitor_lock and Coverity complains (CID 1397072). Replace QTAILQ_FOREACH_SAFE with a while loop and QTAILQ_FIRST, it is cleaner and more future-proof. Signed-off-by: Paolo Bonzini --- monitor.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/monitor.c b/monitor.c index c09fa639409..e5de5765b8d 100644 --- a/monitor.c +++ b/monitor.c @@ -4617,8 +4617,6 @@ void monitor_init(Chardev *chr, int flags) void monitor_cleanup(void) { - Monitor *mon, *next; - /* * We need to explicitly stop the I/O thread (but not destroy it), * clean up the monitor resources, then destroy the I/O thread since @@ -4632,7 +4630,8 @@ void monitor_cleanup(void) /* Flush output buffers and destroy monitors */ qemu_mutex_lock(&monitor_lock); monitor_destroyed = true; - QTAILQ_FOREACH_SAFE(mon, &mon_list, entry, next) { + while (!QTAILQ_EMPTY(&mon_list)) { + Monitor *mon = QTAILQ_FIRST(&mon_list); QTAILQ_REMOVE(&mon_list, mon, entry); /* Permit QAPI event emission from character frontend release */ qemu_mutex_unlock(&monitor_lock); From 2f9f96b242edd7cdbba16d5d88a827a68ff27395 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 14 Dec 2018 12:38:17 +0100 Subject: [PATCH 33/76] crypto: finish removing TABs Suggested-by: Daniel P. Berrange Signed-off-by: Paolo Bonzini --- crypto/aes.c | 414 ++++++++++++++++----------------- crypto/desrfb.c | 594 ++++++++++++++++++++++++------------------------ 2 files changed, 504 insertions(+), 504 deletions(-) diff --git a/crypto/aes.c b/crypto/aes.c index 773d246b000..86b3092324d 100644 --- a/crypto/aes.c +++ b/crypto/aes.c @@ -1059,109 +1059,109 @@ const uint32_t AES_Td4[256] = { 0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU, }; static const u32 rcon[] = { - 0x01000000, 0x02000000, 0x04000000, 0x08000000, - 0x10000000, 0x20000000, 0x40000000, 0x80000000, - 0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ + 0x01000000, 0x02000000, 0x04000000, 0x08000000, + 0x10000000, 0x20000000, 0x40000000, 0x80000000, + 0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ }; /** * Expand the cipher key into the encryption key schedule. */ int AES_set_encrypt_key(const unsigned char *userKey, const int bits, - AES_KEY *key) { + AES_KEY *key) { - u32 *rk; - int i = 0; - u32 temp; + u32 *rk; + int i = 0; + u32 temp; - if (!userKey || !key) - return -1; - if (bits != 128 && bits != 192 && bits != 256) - return -2; + if (!userKey || !key) + return -1; + if (bits != 128 && bits != 192 && bits != 256) + return -2; - rk = key->rd_key; + rk = key->rd_key; - if (bits==128) - key->rounds = 10; - else if (bits==192) - key->rounds = 12; - else - key->rounds = 14; + if (bits==128) + key->rounds = 10; + else if (bits==192) + key->rounds = 12; + else + key->rounds = 14; - rk[0] = GETU32(userKey ); - rk[1] = GETU32(userKey + 4); - rk[2] = GETU32(userKey + 8); - rk[3] = GETU32(userKey + 12); - if (bits == 128) { - while (1) { - temp = rk[3]; - rk[4] = rk[0] ^ + rk[0] = GETU32(userKey ); + rk[1] = GETU32(userKey + 4); + rk[2] = GETU32(userKey + 8); + rk[3] = GETU32(userKey + 12); + if (bits == 128) { + while (1) { + temp = rk[3]; + rk[4] = rk[0] ^ (AES_Te4[(temp >> 16) & 0xff] & 0xff000000) ^ (AES_Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ (AES_Te4[(temp ) & 0xff] & 0x0000ff00) ^ (AES_Te4[(temp >> 24) ] & 0x000000ff) ^ - rcon[i]; - rk[5] = rk[1] ^ rk[4]; - rk[6] = rk[2] ^ rk[5]; - rk[7] = rk[3] ^ rk[6]; - if (++i == 10) { - return 0; - } - rk += 4; - } - } - rk[4] = GETU32(userKey + 16); - rk[5] = GETU32(userKey + 20); - if (bits == 192) { - while (1) { - temp = rk[ 5]; - rk[ 6] = rk[ 0] ^ + rcon[i]; + rk[5] = rk[1] ^ rk[4]; + rk[6] = rk[2] ^ rk[5]; + rk[7] = rk[3] ^ rk[6]; + if (++i == 10) { + return 0; + } + rk += 4; + } + } + rk[4] = GETU32(userKey + 16); + rk[5] = GETU32(userKey + 20); + if (bits == 192) { + while (1) { + temp = rk[ 5]; + rk[ 6] = rk[ 0] ^ (AES_Te4[(temp >> 16) & 0xff] & 0xff000000) ^ (AES_Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ (AES_Te4[(temp ) & 0xff] & 0x0000ff00) ^ (AES_Te4[(temp >> 24) ] & 0x000000ff) ^ - rcon[i]; - rk[ 7] = rk[ 1] ^ rk[ 6]; - rk[ 8] = rk[ 2] ^ rk[ 7]; - rk[ 9] = rk[ 3] ^ rk[ 8]; - if (++i == 8) { - return 0; - } - rk[10] = rk[ 4] ^ rk[ 9]; - rk[11] = rk[ 5] ^ rk[10]; - rk += 6; - } - } - rk[6] = GETU32(userKey + 24); - rk[7] = GETU32(userKey + 28); - if (bits == 256) { - while (1) { - temp = rk[ 7]; - rk[ 8] = rk[ 0] ^ + rcon[i]; + rk[ 7] = rk[ 1] ^ rk[ 6]; + rk[ 8] = rk[ 2] ^ rk[ 7]; + rk[ 9] = rk[ 3] ^ rk[ 8]; + if (++i == 8) { + return 0; + } + rk[10] = rk[ 4] ^ rk[ 9]; + rk[11] = rk[ 5] ^ rk[10]; + rk += 6; + } + } + rk[6] = GETU32(userKey + 24); + rk[7] = GETU32(userKey + 28); + if (bits == 256) { + while (1) { + temp = rk[ 7]; + rk[ 8] = rk[ 0] ^ (AES_Te4[(temp >> 16) & 0xff] & 0xff000000) ^ (AES_Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^ (AES_Te4[(temp ) & 0xff] & 0x0000ff00) ^ (AES_Te4[(temp >> 24) ] & 0x000000ff) ^ - rcon[i]; - rk[ 9] = rk[ 1] ^ rk[ 8]; - rk[10] = rk[ 2] ^ rk[ 9]; - rk[11] = rk[ 3] ^ rk[10]; - if (++i == 7) { - return 0; - } - temp = rk[11]; - rk[12] = rk[ 4] ^ + rcon[i]; + rk[ 9] = rk[ 1] ^ rk[ 8]; + rk[10] = rk[ 2] ^ rk[ 9]; + rk[11] = rk[ 3] ^ rk[10]; + if (++i == 7) { + return 0; + } + temp = rk[11]; + rk[12] = rk[ 4] ^ (AES_Te4[(temp >> 24) ] & 0xff000000) ^ (AES_Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^ (AES_Te4[(temp >> 8) & 0xff] & 0x0000ff00) ^ (AES_Te4[(temp ) & 0xff] & 0x000000ff); - rk[13] = rk[ 5] ^ rk[12]; - rk[14] = rk[ 6] ^ rk[13]; - rk[15] = rk[ 7] ^ rk[14]; + rk[13] = rk[ 5] ^ rk[12]; + rk[14] = rk[ 6] ^ rk[13]; + rk[15] = rk[ 7] ^ rk[14]; - rk += 8; - } - } + rk += 8; + } + } abort(); } @@ -1169,51 +1169,51 @@ int AES_set_encrypt_key(const unsigned char *userKey, const int bits, * Expand the cipher key into the decryption key schedule. */ int AES_set_decrypt_key(const unsigned char *userKey, const int bits, - AES_KEY *key) { + AES_KEY *key) { u32 *rk; - int i, j, status; - u32 temp; + int i, j, status; + u32 temp; - /* first, start with an encryption schedule */ - status = AES_set_encrypt_key(userKey, bits, key); - if (status < 0) - return status; + /* first, start with an encryption schedule */ + status = AES_set_encrypt_key(userKey, bits, key); + if (status < 0) + return status; - rk = key->rd_key; + rk = key->rd_key; - /* invert the order of the round keys: */ - for (i = 0, j = 4*(key->rounds); i < j; i += 4, j -= 4) { - temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp; - temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp; - temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp; - temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp; - } - /* apply the inverse MixColumn transform to all round keys but the first and the last: */ - for (i = 1; i < (key->rounds); i++) { - rk += 4; - rk[0] = + /* invert the order of the round keys: */ + for (i = 0, j = 4*(key->rounds); i < j; i += 4, j -= 4) { + temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp; + temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp; + temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp; + temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp; + } + /* apply the inverse MixColumn transform to all round keys but the first and the last: */ + for (i = 1; i < (key->rounds); i++) { + rk += 4; + rk[0] = AES_Td0[AES_Te4[(rk[0] >> 24) ] & 0xff] ^ AES_Td1[AES_Te4[(rk[0] >> 16) & 0xff] & 0xff] ^ AES_Td2[AES_Te4[(rk[0] >> 8) & 0xff] & 0xff] ^ AES_Td3[AES_Te4[(rk[0] ) & 0xff] & 0xff]; - rk[1] = + rk[1] = AES_Td0[AES_Te4[(rk[1] >> 24) ] & 0xff] ^ AES_Td1[AES_Te4[(rk[1] >> 16) & 0xff] & 0xff] ^ AES_Td2[AES_Te4[(rk[1] >> 8) & 0xff] & 0xff] ^ AES_Td3[AES_Te4[(rk[1] ) & 0xff] & 0xff]; - rk[2] = + rk[2] = AES_Td0[AES_Te4[(rk[2] >> 24) ] & 0xff] ^ AES_Td1[AES_Te4[(rk[2] >> 16) & 0xff] & 0xff] ^ AES_Td2[AES_Te4[(rk[2] >> 8) & 0xff] & 0xff] ^ AES_Td3[AES_Te4[(rk[2] ) & 0xff] & 0xff]; - rk[3] = + rk[3] = AES_Td0[AES_Te4[(rk[3] >> 24) ] & 0xff] ^ AES_Td1[AES_Te4[(rk[3] >> 16) & 0xff] & 0xff] ^ AES_Td2[AES_Te4[(rk[3] >> 8) & 0xff] & 0xff] ^ AES_Td3[AES_Te4[(rk[3] ) & 0xff] & 0xff]; - } - return 0; + } + return 0; } #ifndef AES_ASM @@ -1222,67 +1222,67 @@ int AES_set_decrypt_key(const unsigned char *userKey, const int bits, * in and out can overlap */ void AES_encrypt(const unsigned char *in, unsigned char *out, - const AES_KEY *key) { + const AES_KEY *key) { - const u32 *rk; - u32 s0, s1, s2, s3, t0, t1, t2, t3; + const u32 *rk; + u32 s0, s1, s2, s3, t0, t1, t2, t3; #ifndef FULL_UNROLL - int r; + int r; #endif /* ?FULL_UNROLL */ - assert(in && out && key); - rk = key->rd_key; + assert(in && out && key); + rk = key->rd_key; - /* - * map byte array block to cipher state - * and add initial round key: - */ - s0 = GETU32(in ) ^ rk[0]; - s1 = GETU32(in + 4) ^ rk[1]; - s2 = GETU32(in + 8) ^ rk[2]; - s3 = GETU32(in + 12) ^ rk[3]; + /* + * map byte array block to cipher state + * and add initial round key: + */ + s0 = GETU32(in ) ^ rk[0]; + s1 = GETU32(in + 4) ^ rk[1]; + s2 = GETU32(in + 8) ^ rk[2]; + s3 = GETU32(in + 12) ^ rk[3]; #ifdef FULL_UNROLL - /* round 1: */ + /* round 1: */ t0 = AES_Te0[s0 >> 24] ^ AES_Te1[(s1 >> 16) & 0xff] ^ AES_Te2[(s2 >> 8) & 0xff] ^ AES_Te3[s3 & 0xff] ^ rk[ 4]; t1 = AES_Te0[s1 >> 24] ^ AES_Te1[(s2 >> 16) & 0xff] ^ AES_Te2[(s3 >> 8) & 0xff] ^ AES_Te3[s0 & 0xff] ^ rk[ 5]; t2 = AES_Te0[s2 >> 24] ^ AES_Te1[(s3 >> 16) & 0xff] ^ AES_Te2[(s0 >> 8) & 0xff] ^ AES_Te3[s1 & 0xff] ^ rk[ 6]; t3 = AES_Te0[s3 >> 24] ^ AES_Te1[(s0 >> 16) & 0xff] ^ AES_Te2[(s1 >> 8) & 0xff] ^ AES_Te3[s2 & 0xff] ^ rk[ 7]; - /* round 2: */ + /* round 2: */ s0 = AES_Te0[t0 >> 24] ^ AES_Te1[(t1 >> 16) & 0xff] ^ AES_Te2[(t2 >> 8) & 0xff] ^ AES_Te3[t3 & 0xff] ^ rk[ 8]; s1 = AES_Te0[t1 >> 24] ^ AES_Te1[(t2 >> 16) & 0xff] ^ AES_Te2[(t3 >> 8) & 0xff] ^ AES_Te3[t0 & 0xff] ^ rk[ 9]; s2 = AES_Te0[t2 >> 24] ^ AES_Te1[(t3 >> 16) & 0xff] ^ AES_Te2[(t0 >> 8) & 0xff] ^ AES_Te3[t1 & 0xff] ^ rk[10]; s3 = AES_Te0[t3 >> 24] ^ AES_Te1[(t0 >> 16) & 0xff] ^ AES_Te2[(t1 >> 8) & 0xff] ^ AES_Te3[t2 & 0xff] ^ rk[11]; - /* round 3: */ + /* round 3: */ t0 = AES_Te0[s0 >> 24] ^ AES_Te1[(s1 >> 16) & 0xff] ^ AES_Te2[(s2 >> 8) & 0xff] ^ AES_Te3[s3 & 0xff] ^ rk[12]; t1 = AES_Te0[s1 >> 24] ^ AES_Te1[(s2 >> 16) & 0xff] ^ AES_Te2[(s3 >> 8) & 0xff] ^ AES_Te3[s0 & 0xff] ^ rk[13]; t2 = AES_Te0[s2 >> 24] ^ AES_Te1[(s3 >> 16) & 0xff] ^ AES_Te2[(s0 >> 8) & 0xff] ^ AES_Te3[s1 & 0xff] ^ rk[14]; t3 = AES_Te0[s3 >> 24] ^ AES_Te1[(s0 >> 16) & 0xff] ^ AES_Te2[(s1 >> 8) & 0xff] ^ AES_Te3[s2 & 0xff] ^ rk[15]; - /* round 4: */ + /* round 4: */ s0 = AES_Te0[t0 >> 24] ^ AES_Te1[(t1 >> 16) & 0xff] ^ AES_Te2[(t2 >> 8) & 0xff] ^ AES_Te3[t3 & 0xff] ^ rk[16]; s1 = AES_Te0[t1 >> 24] ^ AES_Te1[(t2 >> 16) & 0xff] ^ AES_Te2[(t3 >> 8) & 0xff] ^ AES_Te3[t0 & 0xff] ^ rk[17]; s2 = AES_Te0[t2 >> 24] ^ AES_Te1[(t3 >> 16) & 0xff] ^ AES_Te2[(t0 >> 8) & 0xff] ^ AES_Te3[t1 & 0xff] ^ rk[18]; s3 = AES_Te0[t3 >> 24] ^ AES_Te1[(t0 >> 16) & 0xff] ^ AES_Te2[(t1 >> 8) & 0xff] ^ AES_Te3[t2 & 0xff] ^ rk[19]; - /* round 5: */ + /* round 5: */ t0 = AES_Te0[s0 >> 24] ^ AES_Te1[(s1 >> 16) & 0xff] ^ AES_Te2[(s2 >> 8) & 0xff] ^ AES_Te3[s3 & 0xff] ^ rk[20]; t1 = AES_Te0[s1 >> 24] ^ AES_Te1[(s2 >> 16) & 0xff] ^ AES_Te2[(s3 >> 8) & 0xff] ^ AES_Te3[s0 & 0xff] ^ rk[21]; t2 = AES_Te0[s2 >> 24] ^ AES_Te1[(s3 >> 16) & 0xff] ^ AES_Te2[(s0 >> 8) & 0xff] ^ AES_Te3[s1 & 0xff] ^ rk[22]; t3 = AES_Te0[s3 >> 24] ^ AES_Te1[(s0 >> 16) & 0xff] ^ AES_Te2[(s1 >> 8) & 0xff] ^ AES_Te3[s2 & 0xff] ^ rk[23]; - /* round 6: */ + /* round 6: */ s0 = AES_Te0[t0 >> 24] ^ AES_Te1[(t1 >> 16) & 0xff] ^ AES_Te2[(t2 >> 8) & 0xff] ^ AES_Te3[t3 & 0xff] ^ rk[24]; s1 = AES_Te0[t1 >> 24] ^ AES_Te1[(t2 >> 16) & 0xff] ^ AES_Te2[(t3 >> 8) & 0xff] ^ AES_Te3[t0 & 0xff] ^ rk[25]; s2 = AES_Te0[t2 >> 24] ^ AES_Te1[(t3 >> 16) & 0xff] ^ AES_Te2[(t0 >> 8) & 0xff] ^ AES_Te3[t1 & 0xff] ^ rk[26]; s3 = AES_Te0[t3 >> 24] ^ AES_Te1[(t0 >> 16) & 0xff] ^ AES_Te2[(t1 >> 8) & 0xff] ^ AES_Te3[t2 & 0xff] ^ rk[27]; - /* round 7: */ + /* round 7: */ t0 = AES_Te0[s0 >> 24] ^ AES_Te1[(s1 >> 16) & 0xff] ^ AES_Te2[(s2 >> 8) & 0xff] ^ AES_Te3[s3 & 0xff] ^ rk[28]; t1 = AES_Te0[s1 >> 24] ^ AES_Te1[(s2 >> 16) & 0xff] ^ AES_Te2[(s3 >> 8) & 0xff] ^ AES_Te3[s0 & 0xff] ^ rk[29]; t2 = AES_Te0[s2 >> 24] ^ AES_Te1[(s3 >> 16) & 0xff] ^ AES_Te2[(s0 >> 8) & 0xff] ^ AES_Te3[s1 & 0xff] ^ rk[30]; t3 = AES_Te0[s3 >> 24] ^ AES_Te1[(s0 >> 16) & 0xff] ^ AES_Te2[(s1 >> 8) & 0xff] ^ AES_Te3[s2 & 0xff] ^ rk[31]; - /* round 8: */ + /* round 8: */ s0 = AES_Te0[t0 >> 24] ^ AES_Te1[(t1 >> 16) & 0xff] ^ AES_Te2[(t2 >> 8) & 0xff] ^ AES_Te3[t3 & 0xff] ^ rk[32]; s1 = AES_Te0[t1 >> 24] ^ AES_Te1[(t2 >> 16) & 0xff] ^ AES_Te2[(t3 >> 8) & 0xff] ^ AES_Te3[t0 & 0xff] ^ rk[33]; s2 = AES_Te0[t2 >> 24] ^ AES_Te1[(t3 >> 16) & 0xff] ^ AES_Te2[(t0 >> 8) & 0xff] ^ AES_Te3[t1 & 0xff] ^ rk[34]; s3 = AES_Te0[t3 >> 24] ^ AES_Te1[(t0 >> 16) & 0xff] ^ AES_Te2[(t1 >> 8) & 0xff] ^ AES_Te3[t2 & 0xff] ^ rk[35]; - /* round 9: */ + /* round 9: */ t0 = AES_Te0[s0 >> 24] ^ AES_Te1[(s1 >> 16) & 0xff] ^ AES_Te2[(s2 >> 8) & 0xff] ^ AES_Te3[s3 & 0xff] ^ rk[36]; t1 = AES_Te0[s1 >> 24] ^ AES_Te1[(s2 >> 16) & 0xff] ^ AES_Te2[(s3 >> 8) & 0xff] ^ AES_Te3[s0 & 0xff] ^ rk[37]; t2 = AES_Te0[s2 >> 24] ^ AES_Te1[(s3 >> 16) & 0xff] ^ AES_Te2[(s0 >> 8) & 0xff] ^ AES_Te3[s1 & 0xff] ^ rk[38]; @@ -1375,37 +1375,37 @@ void AES_encrypt(const unsigned char *in, unsigned char *out, } #endif /* ?FULL_UNROLL */ /* - * apply last round and - * map cipher state to byte array block: - */ - s0 = + * apply last round and + * map cipher state to byte array block: + */ + s0 = (AES_Te4[(t0 >> 24) ] & 0xff000000) ^ (AES_Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^ (AES_Te4[(t2 >> 8) & 0xff] & 0x0000ff00) ^ (AES_Te4[(t3 ) & 0xff] & 0x000000ff) ^ - rk[0]; - PUTU32(out , s0); - s1 = + rk[0]; + PUTU32(out , s0); + s1 = (AES_Te4[(t1 >> 24) ] & 0xff000000) ^ (AES_Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^ (AES_Te4[(t3 >> 8) & 0xff] & 0x0000ff00) ^ (AES_Te4[(t0 ) & 0xff] & 0x000000ff) ^ - rk[1]; - PUTU32(out + 4, s1); - s2 = + rk[1]; + PUTU32(out + 4, s1); + s2 = (AES_Te4[(t2 >> 24) ] & 0xff000000) ^ (AES_Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^ (AES_Te4[(t0 >> 8) & 0xff] & 0x0000ff00) ^ (AES_Te4[(t1 ) & 0xff] & 0x000000ff) ^ - rk[2]; - PUTU32(out + 8, s2); - s3 = + rk[2]; + PUTU32(out + 8, s2); + s3 = (AES_Te4[(t3 >> 24) ] & 0xff000000) ^ (AES_Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^ (AES_Te4[(t1 >> 8) & 0xff] & 0x0000ff00) ^ (AES_Te4[(t2 ) & 0xff] & 0x000000ff) ^ - rk[3]; - PUTU32(out + 12, s3); + rk[3]; + PUTU32(out + 12, s3); } /* @@ -1413,21 +1413,21 @@ void AES_encrypt(const unsigned char *in, unsigned char *out, * in and out can overlap */ void AES_decrypt(const unsigned char *in, unsigned char *out, - const AES_KEY *key) { + const AES_KEY *key) { - const u32 *rk; - u32 s0, s1, s2, s3, t0, t1, t2, t3; + const u32 *rk; + u32 s0, s1, s2, s3, t0, t1, t2, t3; #ifndef FULL_UNROLL - int r; + int r; #endif /* ?FULL_UNROLL */ - assert(in && out && key); - rk = key->rd_key; + assert(in && out && key); + rk = key->rd_key; - /* - * map byte array block to cipher state - * and add initial round key: - */ + /* + * map byte array block to cipher state + * and add initial round key: + */ s0 = GETU32(in ) ^ rk[0]; s1 = GETU32(in + 4) ^ rk[1]; s2 = GETU32(in + 8) ^ rk[2]; @@ -1502,7 +1502,7 @@ void AES_decrypt(const unsigned char *in, unsigned char *out, t3 = AES_Td0[s3 >> 24] ^ AES_Td1[(s2 >> 16) & 0xff] ^ AES_Td2[(s1 >> 8) & 0xff] ^ AES_Td3[s0 & 0xff] ^ rk[55]; } } - rk += key->rounds << 2; + rk += key->rounds << 2; #else /* !FULL_UNROLL */ /* * Nr - 1 full rounds: @@ -1566,88 +1566,88 @@ void AES_decrypt(const unsigned char *in, unsigned char *out, } #endif /* ?FULL_UNROLL */ /* - * apply last round and - * map cipher state to byte array block: - */ - s0 = + * apply last round and + * map cipher state to byte array block: + */ + s0 = (AES_Td4[(t0 >> 24) ] & 0xff000000) ^ (AES_Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^ (AES_Td4[(t2 >> 8) & 0xff] & 0x0000ff00) ^ (AES_Td4[(t1 ) & 0xff] & 0x000000ff) ^ - rk[0]; - PUTU32(out , s0); - s1 = + rk[0]; + PUTU32(out , s0); + s1 = (AES_Td4[(t1 >> 24) ] & 0xff000000) ^ (AES_Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^ (AES_Td4[(t3 >> 8) & 0xff] & 0x0000ff00) ^ (AES_Td4[(t2 ) & 0xff] & 0x000000ff) ^ - rk[1]; - PUTU32(out + 4, s1); - s2 = + rk[1]; + PUTU32(out + 4, s1); + s2 = (AES_Td4[(t2 >> 24) ] & 0xff000000) ^ (AES_Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^ (AES_Td4[(t0 >> 8) & 0xff] & 0x0000ff00) ^ (AES_Td4[(t3 ) & 0xff] & 0x000000ff) ^ - rk[2]; - PUTU32(out + 8, s2); - s3 = + rk[2]; + PUTU32(out + 8, s2); + s3 = (AES_Td4[(t3 >> 24) ] & 0xff000000) ^ (AES_Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^ (AES_Td4[(t1 >> 8) & 0xff] & 0x0000ff00) ^ (AES_Td4[(t0 ) & 0xff] & 0x000000ff) ^ - rk[3]; - PUTU32(out + 12, s3); + rk[3]; + PUTU32(out + 12, s3); } #endif /* AES_ASM */ void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, - const unsigned long length, const AES_KEY *key, - unsigned char *ivec, const int enc) + const unsigned long length, const AES_KEY *key, + unsigned char *ivec, const int enc) { - unsigned long n; - unsigned long len = length; - unsigned char tmp[AES_BLOCK_SIZE]; + unsigned long n; + unsigned long len = length; + unsigned char tmp[AES_BLOCK_SIZE]; - assert(in && out && key && ivec); + assert(in && out && key && ivec); - if (enc) { - while (len >= AES_BLOCK_SIZE) { - for(n=0; n < AES_BLOCK_SIZE; ++n) - tmp[n] = in[n] ^ ivec[n]; - AES_encrypt(tmp, out, key); - memcpy(ivec, out, AES_BLOCK_SIZE); - len -= AES_BLOCK_SIZE; - in += AES_BLOCK_SIZE; - out += AES_BLOCK_SIZE; - } - if (len) { - for(n=0; n < len; ++n) - tmp[n] = in[n] ^ ivec[n]; - for(n=len; n < AES_BLOCK_SIZE; ++n) - tmp[n] = ivec[n]; - AES_encrypt(tmp, tmp, key); - memcpy(out, tmp, AES_BLOCK_SIZE); - memcpy(ivec, tmp, AES_BLOCK_SIZE); - } - } else { - while (len >= AES_BLOCK_SIZE) { - memcpy(tmp, in, AES_BLOCK_SIZE); - AES_decrypt(in, out, key); - for(n=0; n < AES_BLOCK_SIZE; ++n) - out[n] ^= ivec[n]; - memcpy(ivec, tmp, AES_BLOCK_SIZE); - len -= AES_BLOCK_SIZE; - in += AES_BLOCK_SIZE; - out += AES_BLOCK_SIZE; - } - if (len) { - memcpy(tmp, in, AES_BLOCK_SIZE); - AES_decrypt(tmp, tmp, key); - for(n=0; n < len; ++n) - out[n] = tmp[n] ^ ivec[n]; - memcpy(ivec, tmp, AES_BLOCK_SIZE); - } - } + if (enc) { + while (len >= AES_BLOCK_SIZE) { + for(n=0; n < AES_BLOCK_SIZE; ++n) + tmp[n] = in[n] ^ ivec[n]; + AES_encrypt(tmp, out, key); + memcpy(ivec, out, AES_BLOCK_SIZE); + len -= AES_BLOCK_SIZE; + in += AES_BLOCK_SIZE; + out += AES_BLOCK_SIZE; + } + if (len) { + for(n=0; n < len; ++n) + tmp[n] = in[n] ^ ivec[n]; + for(n=len; n < AES_BLOCK_SIZE; ++n) + tmp[n] = ivec[n]; + AES_encrypt(tmp, tmp, key); + memcpy(out, tmp, AES_BLOCK_SIZE); + memcpy(ivec, tmp, AES_BLOCK_SIZE); + } + } else { + while (len >= AES_BLOCK_SIZE) { + memcpy(tmp, in, AES_BLOCK_SIZE); + AES_decrypt(in, out, key); + for(n=0; n < AES_BLOCK_SIZE; ++n) + out[n] ^= ivec[n]; + memcpy(ivec, tmp, AES_BLOCK_SIZE); + len -= AES_BLOCK_SIZE; + in += AES_BLOCK_SIZE; + out += AES_BLOCK_SIZE; + } + if (len) { + memcpy(tmp, in, AES_BLOCK_SIZE); + AES_decrypt(tmp, tmp, key); + for(n=0; n < len; ++n) + out[n] = tmp[n] ^ ivec[n]; + memcpy(ivec, tmp, AES_BLOCK_SIZE); + } + } } diff --git a/crypto/desrfb.c b/crypto/desrfb.c index ec47dea3bbe..3274c36510d 100644 --- a/crypto/desrfb.c +++ b/crypto/desrfb.c @@ -37,353 +37,353 @@ static void cookey(unsigned long *); static unsigned long KnL[32] = { 0L }; static const unsigned short bytebit[8] = { - 01, 02, 04, 010, 020, 040, 0100, 0200 }; + 01, 02, 04, 010, 020, 040, 0100, 0200 }; static const unsigned long bigbyte[24] = { - 0x800000L, 0x400000L, 0x200000L, 0x100000L, - 0x80000L, 0x40000L, 0x20000L, 0x10000L, - 0x8000L, 0x4000L, 0x2000L, 0x1000L, - 0x800L, 0x400L, 0x200L, 0x100L, - 0x80L, 0x40L, 0x20L, 0x10L, - 0x8L, 0x4L, 0x2L, 0x1L }; + 0x800000L, 0x400000L, 0x200000L, 0x100000L, + 0x80000L, 0x40000L, 0x20000L, 0x10000L, + 0x8000L, 0x4000L, 0x2000L, 0x1000L, + 0x800L, 0x400L, 0x200L, 0x100L, + 0x80L, 0x40L, 0x20L, 0x10L, + 0x8L, 0x4L, 0x2L, 0x1L }; /* Use the key schedule specified in the Standard (ANSI X3.92-1981). */ static const unsigned char pc1[56] = { - 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, - 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, - 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, - 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 }; + 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, + 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, + 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, + 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 }; static const unsigned char totrot[16] = { - 1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28 }; + 1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28 }; static const unsigned char pc2[48] = { - 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, - 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, - 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, - 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 }; + 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, + 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, + 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, + 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 }; /* Thanks to James Gillogly & Phil Karn! */ void deskey(unsigned char *key, int edf) { - register int i, j, l, m, n; - unsigned char pc1m[56], pcr[56]; - unsigned long kn[32]; - - for ( j = 0; j < 56; j++ ) { - l = pc1[j]; - m = l & 07; - pc1m[j] = (key[l >> 3] & bytebit[m]) ? 1 : 0; - } - for( i = 0; i < 16; i++ ) { - if( edf == DE1 ) m = (15 - i) << 1; - else m = i << 1; - n = m + 1; - kn[m] = kn[n] = 0L; - for( j = 0; j < 28; j++ ) { - l = j + totrot[i]; - if( l < 28 ) pcr[j] = pc1m[l]; - else pcr[j] = pc1m[l - 28]; - } - for( j = 28; j < 56; j++ ) { - l = j + totrot[i]; - if( l < 56 ) pcr[j] = pc1m[l]; - else pcr[j] = pc1m[l - 28]; - } - for( j = 0; j < 24; j++ ) { - if( pcr[pc2[j]] ) kn[m] |= bigbyte[j]; - if( pcr[pc2[j+24]] ) kn[n] |= bigbyte[j]; - } - } - cookey(kn); - return; - } + register int i, j, l, m, n; + unsigned char pc1m[56], pcr[56]; + unsigned long kn[32]; + + for ( j = 0; j < 56; j++ ) { + l = pc1[j]; + m = l & 07; + pc1m[j] = (key[l >> 3] & bytebit[m]) ? 1 : 0; + } + for( i = 0; i < 16; i++ ) { + if( edf == DE1 ) m = (15 - i) << 1; + else m = i << 1; + n = m + 1; + kn[m] = kn[n] = 0L; + for( j = 0; j < 28; j++ ) { + l = j + totrot[i]; + if( l < 28 ) pcr[j] = pc1m[l]; + else pcr[j] = pc1m[l - 28]; + } + for( j = 28; j < 56; j++ ) { + l = j + totrot[i]; + if( l < 56 ) pcr[j] = pc1m[l]; + else pcr[j] = pc1m[l - 28]; + } + for( j = 0; j < 24; j++ ) { + if( pcr[pc2[j]] ) kn[m] |= bigbyte[j]; + if( pcr[pc2[j+24]] ) kn[n] |= bigbyte[j]; + } + } + cookey(kn); + return; + } static void cookey(register unsigned long *raw1) { - register unsigned long *cook, *raw0; - unsigned long dough[32]; - register int i; - - cook = dough; - for( i = 0; i < 16; i++, raw1++ ) { - raw0 = raw1++; - *cook = (*raw0 & 0x00fc0000L) << 6; - *cook |= (*raw0 & 0x00000fc0L) << 10; - *cook |= (*raw1 & 0x00fc0000L) >> 10; - *cook++ |= (*raw1 & 0x00000fc0L) >> 6; - *cook = (*raw0 & 0x0003f000L) << 12; - *cook |= (*raw0 & 0x0000003fL) << 16; - *cook |= (*raw1 & 0x0003f000L) >> 4; - *cook++ |= (*raw1 & 0x0000003fL); - } - usekey(dough); - return; - } + register unsigned long *cook, *raw0; + unsigned long dough[32]; + register int i; + + cook = dough; + for( i = 0; i < 16; i++, raw1++ ) { + raw0 = raw1++; + *cook = (*raw0 & 0x00fc0000L) << 6; + *cook |= (*raw0 & 0x00000fc0L) << 10; + *cook |= (*raw1 & 0x00fc0000L) >> 10; + *cook++ |= (*raw1 & 0x00000fc0L) >> 6; + *cook = (*raw0 & 0x0003f000L) << 12; + *cook |= (*raw0 & 0x0000003fL) << 16; + *cook |= (*raw1 & 0x0003f000L) >> 4; + *cook++ |= (*raw1 & 0x0000003fL); + } + usekey(dough); + return; + } void usekey(register unsigned long *from) { - register unsigned long *to, *endp; + register unsigned long *to, *endp; - to = KnL, endp = &KnL[32]; - while( to < endp ) *to++ = *from++; - return; - } + to = KnL, endp = &KnL[32]; + while( to < endp ) *to++ = *from++; + return; + } void des(unsigned char *inblock, unsigned char *outblock) { - unsigned long work[2]; + unsigned long work[2]; - scrunch(inblock, work); - desfunc(work, KnL); - unscrun(work, outblock); - return; - } + scrunch(inblock, work); + desfunc(work, KnL); + unscrun(work, outblock); + return; + } static void scrunch(register unsigned char *outof, register unsigned long *into) { - *into = (*outof++ & 0xffL) << 24; - *into |= (*outof++ & 0xffL) << 16; - *into |= (*outof++ & 0xffL) << 8; - *into++ |= (*outof++ & 0xffL); - *into = (*outof++ & 0xffL) << 24; - *into |= (*outof++ & 0xffL) << 16; - *into |= (*outof++ & 0xffL) << 8; - *into |= (*outof & 0xffL); - return; - } + *into = (*outof++ & 0xffL) << 24; + *into |= (*outof++ & 0xffL) << 16; + *into |= (*outof++ & 0xffL) << 8; + *into++ |= (*outof++ & 0xffL); + *into = (*outof++ & 0xffL) << 24; + *into |= (*outof++ & 0xffL) << 16; + *into |= (*outof++ & 0xffL) << 8; + *into |= (*outof & 0xffL); + return; + } static void unscrun(register unsigned long *outof, register unsigned char *into) { - *into++ = (unsigned char)((*outof >> 24) & 0xffL); - *into++ = (unsigned char)((*outof >> 16) & 0xffL); - *into++ = (unsigned char)((*outof >> 8) & 0xffL); - *into++ = (unsigned char)(*outof++ & 0xffL); - *into++ = (unsigned char)((*outof >> 24) & 0xffL); - *into++ = (unsigned char)((*outof >> 16) & 0xffL); - *into++ = (unsigned char)((*outof >> 8) & 0xffL); - *into = (unsigned char)(*outof & 0xffL); - return; - } + *into++ = (unsigned char)((*outof >> 24) & 0xffL); + *into++ = (unsigned char)((*outof >> 16) & 0xffL); + *into++ = (unsigned char)((*outof >> 8) & 0xffL); + *into++ = (unsigned char)(*outof++ & 0xffL); + *into++ = (unsigned char)((*outof >> 24) & 0xffL); + *into++ = (unsigned char)((*outof >> 16) & 0xffL); + *into++ = (unsigned char)((*outof >> 8) & 0xffL); + *into = (unsigned char)(*outof & 0xffL); + return; + } static const unsigned long SP1[64] = { - 0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L, - 0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L, - 0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L, - 0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L, - 0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L, - 0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L, - 0x00010004L, 0x01000004L, 0x01000004L, 0x00010004L, - 0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L, - 0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L, - 0x01010400L, 0x01000000L, 0x01000000L, 0x00000400L, - 0x01010004L, 0x00010000L, 0x00010400L, 0x01000004L, - 0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L, - 0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L, - 0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L, - 0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L, - 0x00010004L, 0x00010400L, 0x00000000L, 0x01010004L }; + 0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L, + 0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L, + 0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L, + 0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L, + 0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L, + 0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L, + 0x00010004L, 0x01000004L, 0x01000004L, 0x00010004L, + 0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L, + 0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L, + 0x01010400L, 0x01000000L, 0x01000000L, 0x00000400L, + 0x01010004L, 0x00010000L, 0x00010400L, 0x01000004L, + 0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L, + 0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L, + 0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L, + 0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L, + 0x00010004L, 0x00010400L, 0x00000000L, 0x01010004L }; static const unsigned long SP2[64] = { - 0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L, - 0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L, - 0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L, - 0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L, - 0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L, - 0x80000000L, 0x00008000L, 0x00108020L, 0x80100000L, - 0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L, - 0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L, - 0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L, - 0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L, - 0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L, - 0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L, - 0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L, - 0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L, - 0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L, - 0x80000000L, 0x80100020L, 0x80108020L, 0x00108000L }; + 0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L, + 0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L, + 0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L, + 0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L, + 0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L, + 0x80000000L, 0x00008000L, 0x00108020L, 0x80100000L, + 0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L, + 0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L, + 0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L, + 0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L, + 0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L, + 0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L, + 0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L, + 0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L, + 0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L, + 0x80000000L, 0x80100020L, 0x80108020L, 0x00108000L }; static const unsigned long SP3[64] = { - 0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L, - 0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L, - 0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L, - 0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L, - 0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L, - 0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L, - 0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L, - 0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L, - 0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L, - 0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L, - 0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L, - 0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L, - 0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L, - 0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L, - 0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L, - 0x00020208L, 0x00000008L, 0x08020008L, 0x00020200L }; + 0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L, + 0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L, + 0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L, + 0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L, + 0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L, + 0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L, + 0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L, + 0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L, + 0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L, + 0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L, + 0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L, + 0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L, + 0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L, + 0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L, + 0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L, + 0x00020208L, 0x00000008L, 0x08020008L, 0x00020200L }; static const unsigned long SP4[64] = { - 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L, - 0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L, - 0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L, - 0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L, - 0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L, - 0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L, - 0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L, - 0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L, - 0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L, - 0x00000081L, 0x00000000L, 0x00000000L, 0x00802000L, - 0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L, - 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L, - 0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L, - 0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L, - 0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L, - 0x00000080L, 0x00800000L, 0x00002000L, 0x00802080L }; + 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L, + 0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L, + 0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L, + 0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L, + 0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L, + 0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L, + 0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L, + 0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L, + 0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L, + 0x00000081L, 0x00000000L, 0x00000000L, 0x00802000L, + 0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L, + 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L, + 0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L, + 0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L, + 0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L, + 0x00000080L, 0x00800000L, 0x00002000L, 0x00802080L }; static const unsigned long SP5[64] = { - 0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L, - 0x00080000L, 0x00000100L, 0x40000000L, 0x02080000L, - 0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L, - 0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L, - 0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L, - 0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L, - 0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L, - 0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L, - 0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L, - 0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L, - 0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L, - 0x40080100L, 0x00000100L, 0x02000000L, 0x42080000L, - 0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L, - 0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L, - 0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L, - 0x00000000L, 0x40080000L, 0x02080100L, 0x40000100L }; + 0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L, + 0x00080000L, 0x00000100L, 0x40000000L, 0x02080000L, + 0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L, + 0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L, + 0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L, + 0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L, + 0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L, + 0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L, + 0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L, + 0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L, + 0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L, + 0x40080100L, 0x00000100L, 0x02000000L, 0x42080000L, + 0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L, + 0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L, + 0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L, + 0x00000000L, 0x40080000L, 0x02080100L, 0x40000100L }; static const unsigned long SP6[64] = { - 0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L, - 0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L, - 0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L, - 0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L, - 0x00000000L, 0x00400010L, 0x20004010L, 0x00004000L, - 0x00404000L, 0x20004010L, 0x00000010L, 0x20400010L, - 0x20400010L, 0x00000000L, 0x00404010L, 0x20404000L, - 0x00004010L, 0x00404000L, 0x20404000L, 0x20000000L, - 0x20004000L, 0x00000010L, 0x20400010L, 0x00404000L, - 0x20404010L, 0x00400000L, 0x00004010L, 0x20000010L, - 0x00400000L, 0x20004000L, 0x20000000L, 0x00004010L, - 0x20000010L, 0x20404010L, 0x00404000L, 0x20400000L, - 0x00404010L, 0x20404000L, 0x00000000L, 0x20400010L, - 0x00000010L, 0x00004000L, 0x20400000L, 0x00404010L, - 0x00004000L, 0x00400010L, 0x20004010L, 0x00000000L, - 0x20404000L, 0x20000000L, 0x00400010L, 0x20004010L }; + 0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L, + 0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L, + 0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L, + 0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L, + 0x00000000L, 0x00400010L, 0x20004010L, 0x00004000L, + 0x00404000L, 0x20004010L, 0x00000010L, 0x20400010L, + 0x20400010L, 0x00000000L, 0x00404010L, 0x20404000L, + 0x00004010L, 0x00404000L, 0x20404000L, 0x20000000L, + 0x20004000L, 0x00000010L, 0x20400010L, 0x00404000L, + 0x20404010L, 0x00400000L, 0x00004010L, 0x20000010L, + 0x00400000L, 0x20004000L, 0x20000000L, 0x00004010L, + 0x20000010L, 0x20404010L, 0x00404000L, 0x20400000L, + 0x00404010L, 0x20404000L, 0x00000000L, 0x20400010L, + 0x00000010L, 0x00004000L, 0x20400000L, 0x00404010L, + 0x00004000L, 0x00400010L, 0x20004010L, 0x00000000L, + 0x20404000L, 0x20000000L, 0x00400010L, 0x20004010L }; static const unsigned long SP7[64] = { - 0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L, - 0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L, - 0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L, - 0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L, - 0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L, - 0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L, - 0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L, - 0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L, - 0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L, - 0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L, - 0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L, - 0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L, - 0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L, - 0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L, - 0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L, - 0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L }; + 0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L, + 0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L, + 0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L, + 0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L, + 0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L, + 0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L, + 0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L, + 0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L, + 0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L, + 0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L, + 0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L, + 0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L, + 0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L, + 0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L, + 0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L, + 0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L }; static const unsigned long SP8[64] = { - 0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L, - 0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L, - 0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L, - 0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L, - 0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L, - 0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L, - 0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L, - 0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L, - 0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L, - 0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L, - 0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L, - 0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L, - 0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L, - 0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L, - 0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L, - 0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L }; + 0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L, + 0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L, + 0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L, + 0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L, + 0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L, + 0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L, + 0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L, + 0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L, + 0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L, + 0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L, + 0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L, + 0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L, + 0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L, + 0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L, + 0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L, + 0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L }; static void desfunc(register unsigned long *block, register unsigned long *keys) { - register unsigned long fval, work, right, leftt; - register int round; - - leftt = block[0]; - right = block[1]; - work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL; - right ^= work; - leftt ^= (work << 4); - work = ((leftt >> 16) ^ right) & 0x0000ffffL; - right ^= work; - leftt ^= (work << 16); - work = ((right >> 2) ^ leftt) & 0x33333333L; - leftt ^= work; - right ^= (work << 2); - work = ((right >> 8) ^ leftt) & 0x00ff00ffL; - leftt ^= work; - right ^= (work << 8); - right = ((right << 1) | ((right >> 31) & 1L)) & 0xffffffffL; - work = (leftt ^ right) & 0xaaaaaaaaL; - leftt ^= work; - right ^= work; - leftt = ((leftt << 1) | ((leftt >> 31) & 1L)) & 0xffffffffL; - - for( round = 0; round < 8; round++ ) { - work = (right << 28) | (right >> 4); - work ^= *keys++; - fval = SP7[ work & 0x3fL]; - fval |= SP5[(work >> 8) & 0x3fL]; - fval |= SP3[(work >> 16) & 0x3fL]; - fval |= SP1[(work >> 24) & 0x3fL]; - work = right ^ *keys++; - fval |= SP8[ work & 0x3fL]; - fval |= SP6[(work >> 8) & 0x3fL]; - fval |= SP4[(work >> 16) & 0x3fL]; - fval |= SP2[(work >> 24) & 0x3fL]; - leftt ^= fval; - work = (leftt << 28) | (leftt >> 4); - work ^= *keys++; - fval = SP7[ work & 0x3fL]; - fval |= SP5[(work >> 8) & 0x3fL]; - fval |= SP3[(work >> 16) & 0x3fL]; - fval |= SP1[(work >> 24) & 0x3fL]; - work = leftt ^ *keys++; - fval |= SP8[ work & 0x3fL]; - fval |= SP6[(work >> 8) & 0x3fL]; - fval |= SP4[(work >> 16) & 0x3fL]; - fval |= SP2[(work >> 24) & 0x3fL]; - right ^= fval; - } - - right = (right << 31) | (right >> 1); - work = (leftt ^ right) & 0xaaaaaaaaL; - leftt ^= work; - right ^= work; - leftt = (leftt << 31) | (leftt >> 1); - work = ((leftt >> 8) ^ right) & 0x00ff00ffL; - right ^= work; - leftt ^= (work << 8); - work = ((leftt >> 2) ^ right) & 0x33333333L; - right ^= work; - leftt ^= (work << 2); - work = ((right >> 16) ^ leftt) & 0x0000ffffL; - leftt ^= work; - right ^= (work << 16); - work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL; - leftt ^= work; - right ^= (work << 4); - *block++ = right; - *block = leftt; - return; - } + register unsigned long fval, work, right, leftt; + register int round; + + leftt = block[0]; + right = block[1]; + work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL; + right ^= work; + leftt ^= (work << 4); + work = ((leftt >> 16) ^ right) & 0x0000ffffL; + right ^= work; + leftt ^= (work << 16); + work = ((right >> 2) ^ leftt) & 0x33333333L; + leftt ^= work; + right ^= (work << 2); + work = ((right >> 8) ^ leftt) & 0x00ff00ffL; + leftt ^= work; + right ^= (work << 8); + right = ((right << 1) | ((right >> 31) & 1L)) & 0xffffffffL; + work = (leftt ^ right) & 0xaaaaaaaaL; + leftt ^= work; + right ^= work; + leftt = ((leftt << 1) | ((leftt >> 31) & 1L)) & 0xffffffffL; + + for( round = 0; round < 8; round++ ) { + work = (right << 28) | (right >> 4); + work ^= *keys++; + fval = SP7[ work & 0x3fL]; + fval |= SP5[(work >> 8) & 0x3fL]; + fval |= SP3[(work >> 16) & 0x3fL]; + fval |= SP1[(work >> 24) & 0x3fL]; + work = right ^ *keys++; + fval |= SP8[ work & 0x3fL]; + fval |= SP6[(work >> 8) & 0x3fL]; + fval |= SP4[(work >> 16) & 0x3fL]; + fval |= SP2[(work >> 24) & 0x3fL]; + leftt ^= fval; + work = (leftt << 28) | (leftt >> 4); + work ^= *keys++; + fval = SP7[ work & 0x3fL]; + fval |= SP5[(work >> 8) & 0x3fL]; + fval |= SP3[(work >> 16) & 0x3fL]; + fval |= SP1[(work >> 24) & 0x3fL]; + work = leftt ^ *keys++; + fval |= SP8[ work & 0x3fL]; + fval |= SP6[(work >> 8) & 0x3fL]; + fval |= SP4[(work >> 16) & 0x3fL]; + fval |= SP2[(work >> 24) & 0x3fL]; + right ^= fval; + } + + right = (right << 31) | (right >> 1); + work = (leftt ^ right) & 0xaaaaaaaaL; + leftt ^= work; + right ^= work; + leftt = (leftt << 31) | (leftt >> 1); + work = ((leftt >> 8) ^ right) & 0x00ff00ffL; + right ^= work; + leftt ^= (work << 8); + work = ((leftt >> 2) ^ right) & 0x33333333L; + right ^= work; + leftt ^= (work << 2); + work = ((right >> 16) ^ leftt) & 0x0000ffffL; + leftt ^= work; + right ^= (work << 16); + work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL; + leftt ^= work; + right ^= (work << 4); + *block++ = right; + *block = leftt; + return; + } /* Validation sets: * From b86d01ba47cfe3fc7505924ca2804f370383ad97 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 14 Dec 2018 12:38:28 +0100 Subject: [PATCH 34/76] ui: vnc: finish removing TABs Suggested-by: Daniel P. Berrange Signed-off-by: Paolo Bonzini --- ui/vnc-enc-hextile-template.h | 268 +++++++++++------------ ui/vnc-enc-zywrle.h | 394 +++++++++++++++++----------------- 2 files changed, 331 insertions(+), 331 deletions(-) diff --git a/ui/vnc-enc-hextile-template.h b/ui/vnc-enc-hextile-template.h index d868d75720b..0c56262afff 100644 --- a/ui/vnc-enc-hextile-template.h +++ b/ui/vnc-enc-hextile-template.h @@ -30,127 +30,127 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs, int n_subtiles = 0; for (j = 0; j < h; j++) { - for (i = 0; i < w; i++) { - switch (n_colors) { - case 0: - bg = irow[i]; - n_colors = 1; - break; - case 1: - if (irow[i] != bg) { - fg = irow[i]; - n_colors = 2; - } - break; - case 2: - if (irow[i] != bg && irow[i] != fg) { - n_colors = 3; - } else { - if (irow[i] == bg) - bg_count++; - else if (irow[i] == fg) - fg_count++; - } - break; - default: - break; - } - } - if (n_colors > 2) - break; - irow += vnc_server_fb_stride(vd) / sizeof(pixel_t); + for (i = 0; i < w; i++) { + switch (n_colors) { + case 0: + bg = irow[i]; + n_colors = 1; + break; + case 1: + if (irow[i] != bg) { + fg = irow[i]; + n_colors = 2; + } + break; + case 2: + if (irow[i] != bg && irow[i] != fg) { + n_colors = 3; + } else { + if (irow[i] == bg) + bg_count++; + else if (irow[i] == fg) + fg_count++; + } + break; + default: + break; + } + } + if (n_colors > 2) + break; + irow += vnc_server_fb_stride(vd) / sizeof(pixel_t); } if (n_colors > 1 && fg_count > bg_count) { - pixel_t tmp = fg; - fg = bg; - bg = tmp; + pixel_t tmp = fg; + fg = bg; + bg = tmp; } if (!*has_bg || *last_bg != bg) { - flags |= 0x02; - *has_bg = 1; - *last_bg = bg; + flags |= 0x02; + *has_bg = 1; + *last_bg = bg; } if (n_colors < 3 && (!*has_fg || *last_fg != fg)) { - flags |= 0x04; - *has_fg = 1; - *last_fg = fg; + flags |= 0x04; + *has_fg = 1; + *last_fg = fg; } switch (n_colors) { case 1: - n_data = 0; - break; + n_data = 0; + break; case 2: - flags |= 0x08; - - irow = (pixel_t *)row; - - for (j = 0; j < h; j++) { - int min_x = -1; - for (i = 0; i < w; i++) { - if (irow[i] == fg) { - if (min_x == -1) - min_x = i; - } else if (min_x != -1) { - hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1); - n_data += 2; - n_subtiles++; - min_x = -1; - } - } - if (min_x != -1) { - hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1); - n_data += 2; - n_subtiles++; - } - irow += vnc_server_fb_stride(vd) / sizeof(pixel_t); - } - break; + flags |= 0x08; + + irow = (pixel_t *)row; + + for (j = 0; j < h; j++) { + int min_x = -1; + for (i = 0; i < w; i++) { + if (irow[i] == fg) { + if (min_x == -1) + min_x = i; + } else if (min_x != -1) { + hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1); + n_data += 2; + n_subtiles++; + min_x = -1; + } + } + if (min_x != -1) { + hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1); + n_data += 2; + n_subtiles++; + } + irow += vnc_server_fb_stride(vd) / sizeof(pixel_t); + } + break; case 3: - flags |= 0x18; - - irow = (pixel_t *)row; - - if (!*has_bg || *last_bg != bg) - flags |= 0x02; - - for (j = 0; j < h; j++) { - int has_color = 0; - int min_x = -1; - pixel_t color = 0; /* shut up gcc */ - - for (i = 0; i < w; i++) { - if (!has_color) { - if (irow[i] == bg) - continue; - color = irow[i]; - min_x = i; - has_color = 1; - } else if (irow[i] != color) { - has_color = 0; + flags |= 0x18; + + irow = (pixel_t *)row; + + if (!*has_bg || *last_bg != bg) + flags |= 0x02; + + for (j = 0; j < h; j++) { + int has_color = 0; + int min_x = -1; + pixel_t color = 0; /* shut up gcc */ + + for (i = 0; i < w; i++) { + if (!has_color) { + if (irow[i] == bg) + continue; + color = irow[i]; + min_x = i; + has_color = 1; + } else if (irow[i] != color) { + has_color = 0; #ifdef GENERIC vnc_convert_pixel(vs, data + n_data, color); n_data += vs->client_pf.bytes_per_pixel; #else - memcpy(data + n_data, &color, sizeof(color)); + memcpy(data + n_data, &color, sizeof(color)); n_data += sizeof(pixel_t); #endif - hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1); - n_data += 2; - n_subtiles++; - - min_x = -1; - if (irow[i] != bg) { - color = irow[i]; - min_x = i; - has_color = 1; - } - } - } - if (has_color) { + hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1); + n_data += 2; + n_subtiles++; + + min_x = -1; + if (irow[i] != bg) { + color = irow[i]; + min_x = i; + has_color = 1; + } + } + } + if (has_color) { #ifdef GENERIC vnc_convert_pixel(vs, data + n_data, color); n_data += vs->client_pf.bytes_per_pixel; @@ -158,50 +158,50 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs, memcpy(data + n_data, &color, sizeof(color)); n_data += sizeof(pixel_t); #endif - hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1); - n_data += 2; - n_subtiles++; - } - irow += vnc_server_fb_stride(vd) / sizeof(pixel_t); - } - - /* A SubrectsColoured subtile invalidates the foreground color */ - *has_fg = 0; - if (n_data > (w * h * sizeof(pixel_t))) { - n_colors = 4; - flags = 0x01; - *has_bg = 0; - - /* we really don't have to invalidate either the bg or fg - but we've lost the old values. oh well. */ - } + hextile_enc_cord(data + n_data, min_x, j, i - min_x, 1); + n_data += 2; + n_subtiles++; + } + irow += vnc_server_fb_stride(vd) / sizeof(pixel_t); + } + + /* A SubrectsColoured subtile invalidates the foreground color */ + *has_fg = 0; + if (n_data > (w * h * sizeof(pixel_t))) { + n_colors = 4; + flags = 0x01; + *has_bg = 0; + + /* we really don't have to invalidate either the bg or fg + but we've lost the old values. oh well. */ + } break; default: - break; + break; } if (n_colors > 3) { - flags = 0x01; - *has_fg = 0; - *has_bg = 0; - n_colors = 4; + flags = 0x01; + *has_fg = 0; + *has_bg = 0; + n_colors = 4; } vnc_write_u8(vs, flags); if (n_colors < 4) { - if (flags & 0x02) - vs->write_pixels(vs, last_bg, sizeof(pixel_t)); - if (flags & 0x04) - vs->write_pixels(vs, last_fg, sizeof(pixel_t)); - if (n_subtiles) { - vnc_write_u8(vs, n_subtiles); - vnc_write(vs, data, n_data); - } + if (flags & 0x02) + vs->write_pixels(vs, last_bg, sizeof(pixel_t)); + if (flags & 0x04) + vs->write_pixels(vs, last_fg, sizeof(pixel_t)); + if (n_subtiles) { + vnc_write_u8(vs, n_subtiles); + vnc_write(vs, data, n_data); + } } else { - for (j = 0; j < h; j++) { - vs->write_pixels(vs, row, w * 4); - row += vnc_server_fb_stride(vd); - } + for (j = 0; j < h; j++) { + vs->write_pixels(vs, row, w * 4); + row += vnc_server_fb_stride(vd); + } } } diff --git a/ui/vnc-enc-zywrle.h b/ui/vnc-enc-zywrle.h index 610bd79d1a8..9b7f6989750 100644 --- a/ui/vnc-enc-zywrle.h +++ b/ui/vnc-enc-zywrle.h @@ -48,162 +48,162 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef ZYWRLE_QUANTIZE /* Type A:lower bit omitting of EZW style. */ static const unsigned int zywrle_param[3][3]={ - {0x0000F000, 0x00000000, 0x00000000}, - {0x0000C000, 0x00F0F0F0, 0x00000000}, - {0x0000C000, 0x00C0C0C0, 0x00F0F0F0}, + {0x0000F000, 0x00000000, 0x00000000}, + {0x0000C000, 0x00F0F0F0, 0x00000000}, + {0x0000C000, 0x00C0C0C0, 0x00F0F0F0}, /* {0x0000FF00, 0x00000000, 0x00000000}, - {0x0000FF00, 0x00FFFFFF, 0x00000000}, - {0x0000FF00, 0x00FFFFFF, 0x00FFFFFF}, */ + {0x0000FF00, 0x00FFFFFF, 0x00000000}, + {0x0000FF00, 0x00FFFFFF, 0x00FFFFFF}, */ }; #else /* Type B:Non liner quantization filter. */ static const int8_t zywrle_conv[4][256]={ { /* bi=5, bo=5 r=0.0:PSNR=24.849 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, }, { /* bi=5, bo=5 r=2.0:PSNR=74.031 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 56, 56, 56, 56, 56, - 56, 56, 56, 56, 64, 64, 64, 64, - 64, 64, 64, 64, 72, 72, 72, 72, - 72, 72, 72, 72, 80, 80, 80, 80, - 80, 80, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 96, 96, - 96, 96, 96, 104, 104, 104, 104, 104, - 104, 104, 104, 104, 104, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, - 0, -120, -120, -120, -120, -120, -120, -120, - -120, -120, -120, -112, -112, -112, -112, -112, - -112, -112, -112, -112, -104, -104, -104, -104, - -104, -104, -104, -104, -104, -104, -96, -96, - -96, -96, -96, -88, -88, -88, -88, -88, - -88, -88, -88, -88, -88, -88, -88, -80, - -80, -80, -80, -80, -80, -72, -72, -72, - -72, -72, -72, -72, -72, -64, -64, -64, - -64, -64, -64, -64, -64, -56, -56, -56, - -56, -56, -56, -56, -56, -56, -48, -48, - -48, -48, -48, -48, -48, -48, -48, -48, - -48, -32, -32, -32, -32, -32, -32, -32, - -32, -32, -32, -32, -32, -32, -32, -32, - -32, -32, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 64, 64, 64, 64, + 64, 64, 64, 64, 72, 72, 72, 72, + 72, 72, 72, 72, 80, 80, 80, 80, + 80, 80, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 96, 96, + 96, 96, 96, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, + 0, -120, -120, -120, -120, -120, -120, -120, + -120, -120, -120, -112, -112, -112, -112, -112, + -112, -112, -112, -112, -104, -104, -104, -104, + -104, -104, -104, -104, -104, -104, -96, -96, + -96, -96, -96, -88, -88, -88, -88, -88, + -88, -88, -88, -88, -88, -88, -88, -80, + -80, -80, -80, -80, -80, -72, -72, -72, + -72, -72, -72, -72, -72, -64, -64, -64, + -64, -64, -64, -64, -64, -56, -56, -56, + -56, -56, -56, -56, -56, -56, -48, -48, + -48, -48, -48, -48, -48, -48, -48, -48, + -48, -32, -32, -32, -32, -32, -32, -32, + -32, -32, -32, -32, -32, -32, -32, -32, + -32, -32, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, }, { /* bi=5, bo=4 r=2.0:PSNR=64.441 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, - 64, 64, 64, 64, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 64, 64, 64, - 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 104, 104, 104, 104, 104, 104, 104, 104, - 104, 104, 104, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 120, 120, 120, 120, - 120, 120, 120, 120, 120, 120, 120, 120, - 0, -120, -120, -120, -120, -120, -120, -120, - -120, -120, -120, -120, -120, -112, -112, -112, - -112, -112, -112, -112, -112, -112, -104, -104, - -104, -104, -104, -104, -104, -104, -104, -104, - -104, -88, -88, -88, -88, -88, -88, -88, - -88, -88, -88, -88, -80, -80, -80, -80, - -80, -80, -80, -80, -80, -80, -80, -80, - -80, -64, -64, -64, -64, -64, -64, -64, - -64, -64, -64, -64, -64, -64, -64, -64, - -64, -48, -48, -48, -48, -48, -48, -48, - -48, -48, -48, -48, -48, -48, -48, -48, - -48, -48, -48, -48, -48, -48, -48, -48, - -48, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, + 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, + 0, -120, -120, -120, -120, -120, -120, -120, + -120, -120, -120, -120, -120, -112, -112, -112, + -112, -112, -112, -112, -112, -112, -104, -104, + -104, -104, -104, -104, -104, -104, -104, -104, + -104, -88, -88, -88, -88, -88, -88, -88, + -88, -88, -88, -88, -80, -80, -80, -80, + -80, -80, -80, -80, -80, -80, -80, -80, + -80, -64, -64, -64, -64, -64, -64, -64, + -64, -64, -64, -64, -64, -64, -64, -64, + -64, -48, -48, -48, -48, -48, -48, -48, + -48, -48, -48, -48, -48, -48, -48, -48, + -48, -48, -48, -48, -48, -48, -48, -48, + -48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, }, { /* bi=5, bo=2 r=2.0:PSNR=43.175 */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 88, 88, 88, 88, 88, 88, 88, 88, - 0, -88, -88, -88, -88, -88, -88, -88, - -88, -88, -88, -88, -88, -88, -88, -88, - -88, -88, -88, -88, -88, -88, -88, -88, - -88, -88, -88, -88, -88, -88, -88, -88, - -88, -88, -88, -88, -88, -88, -88, -88, - -88, -88, -88, -88, -88, -88, -88, -88, - -88, -88, -88, -88, -88, -88, -88, -88, - -88, -88, -88, -88, -88, -88, -88, -88, - -88, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, + 0, -88, -88, -88, -88, -88, -88, -88, + -88, -88, -88, -88, -88, -88, -88, -88, + -88, -88, -88, -88, -88, -88, -88, -88, + -88, -88, -88, -88, -88, -88, -88, -88, + -88, -88, -88, -88, -88, -88, -88, -88, + -88, -88, -88, -88, -88, -88, -88, -88, + -88, -88, -88, -88, -88, -88, -88, -88, + -88, -88, -88, -88, -88, -88, -88, -88, + -88, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, } }; static const int8_t *zywrle_param[3][3][3]={ - {{zywrle_conv[0], zywrle_conv[2], zywrle_conv[0]}, + {{zywrle_conv[0], zywrle_conv[2], zywrle_conv[0]}, {zywrle_conv[0], zywrle_conv[0], zywrle_conv[0]}, {zywrle_conv[0], zywrle_conv[0], zywrle_conv[0]}}, - {{zywrle_conv[0], zywrle_conv[3], zywrle_conv[0]}, + {{zywrle_conv[0], zywrle_conv[3], zywrle_conv[0]}, {zywrle_conv[1], zywrle_conv[1], zywrle_conv[1]}, {zywrle_conv[0], zywrle_conv[0], zywrle_conv[0]}}, - {{zywrle_conv[0], zywrle_conv[3], zywrle_conv[0]}, + {{zywrle_conv[0], zywrle_conv[3], zywrle_conv[0]}, {zywrle_conv[2], zywrle_conv[2], zywrle_conv[2]}, {zywrle_conv[1], zywrle_conv[1], zywrle_conv[1]}}, }; @@ -214,53 +214,53 @@ static const int8_t *zywrle_param[3][3][3]={ #define ZYWRLE_UVMASK15 0xFFFFFFF8 #define ZYWRLE_LOAD_PIXEL15(src, r, g, b) \ do { \ - r = (((uint8_t*)src)[S_1]<< 1)& 0xF8; \ - g = (((uint8_t*)src)[S_1]<< 6) | (((uint8_t*)src)[S_0]>> 2); \ + r = (((uint8_t*)src)[S_1]<< 1)& 0xF8; \ + g = (((uint8_t*)src)[S_1]<< 6) | (((uint8_t*)src)[S_0]>> 2); \ g &= 0xF8; \ - b = (((uint8_t*)src)[S_0]<< 3)& 0xF8; \ + b = (((uint8_t*)src)[S_0]<< 3)& 0xF8; \ } while (0) #define ZYWRLE_SAVE_PIXEL15(dst, r, g, b) \ do { \ - r &= 0xF8; \ - g &= 0xF8; \ - b &= 0xF8; \ - ((uint8_t*)dst)[S_1] = (uint8_t)((r >> 1)|(g >> 6)); \ - ((uint8_t*)dst)[S_0] = (uint8_t)(((b >> 3)|(g << 2))& 0xFF); \ + r &= 0xF8; \ + g &= 0xF8; \ + b &= 0xF8; \ + ((uint8_t*)dst)[S_1] = (uint8_t)((r >> 1)|(g >> 6)); \ + ((uint8_t*)dst)[S_0] = (uint8_t)(((b >> 3)|(g << 2))& 0xFF); \ } while (0) #define ZYWRLE_YMASK16 0xFFFFFFFC #define ZYWRLE_UVMASK16 0xFFFFFFF8 #define ZYWRLE_LOAD_PIXEL16(src, r, g, b) \ do { \ - r = ((uint8_t*)src)[S_1] & 0xF8; \ - g = (((uint8_t*)src)[S_1]<< 5) | (((uint8_t*)src)[S_0] >> 3); \ + r = ((uint8_t*)src)[S_1] & 0xF8; \ + g = (((uint8_t*)src)[S_1]<< 5) | (((uint8_t*)src)[S_0] >> 3); \ g &= 0xFC; \ - b = (((uint8_t*)src)[S_0]<< 3) & 0xF8; \ + b = (((uint8_t*)src)[S_0]<< 3) & 0xF8; \ } while (0) #define ZYWRLE_SAVE_PIXEL16(dst, r, g,b) \ do { \ - r &= 0xF8; \ - g &= 0xFC; \ - b &= 0xF8; \ - ((uint8_t*)dst)[S_1] = (uint8_t)(r | (g >> 5)); \ - ((uint8_t*)dst)[S_0] = (uint8_t)(((b >> 3)|(g << 3)) & 0xFF); \ + r &= 0xF8; \ + g &= 0xFC; \ + b &= 0xF8; \ + ((uint8_t*)dst)[S_1] = (uint8_t)(r | (g >> 5)); \ + ((uint8_t*)dst)[S_0] = (uint8_t)(((b >> 3)|(g << 3)) & 0xFF); \ } while (0) #define ZYWRLE_YMASK32 0xFFFFFFFF #define ZYWRLE_UVMASK32 0xFFFFFFFF #define ZYWRLE_LOAD_PIXEL32(src, r, g, b) \ do { \ - r = ((uint8_t*)src)[L_2]; \ - g = ((uint8_t*)src)[L_1]; \ - b = ((uint8_t*)src)[L_0]; \ + r = ((uint8_t*)src)[L_2]; \ + g = ((uint8_t*)src)[L_1]; \ + b = ((uint8_t*)src)[L_0]; \ } while (0) #define ZYWRLE_SAVE_PIXEL32(dst, r, g, b) \ do { \ - ((uint8_t*)dst)[L_2] = (uint8_t)r; \ - ((uint8_t*)dst)[L_1] = (uint8_t)g; \ - ((uint8_t*)dst)[L_0] = (uint8_t)b; \ + ((uint8_t*)dst)[L_2] = (uint8_t)r; \ + ((uint8_t*)dst)[L_1] = (uint8_t)g; \ + ((uint8_t*)dst)[L_0] = (uint8_t)b; \ } while (0) static inline void harr(int8_t *px0, int8_t *px1) @@ -443,27 +443,27 @@ static inline void filter_wavelet_square(int *buf, int width, int height, static inline void wavelet(int *buf, int width, int height, int level) { - int l, s; - int *top; - int *end; - - for (l = 0; l < level; l++) { - top = buf; - end = buf + height * width; - s = width << l; - while (top < end) { - wavelet_level(top, width, l, 1); - top += s; - } - top = buf; - end = buf + width; - s = 1<> 2; \ - u = b - g; \ - v = r - g; \ - y -= 128; \ - u >>= 1; \ - v >>= 1; \ - y &= ymask; \ - u &= uvmask; \ - v &= uvmask; \ - if (y == -128) { \ + y = (r + (g << 1) + b) >> 2; \ + u = b - g; \ + v = r - g; \ + y -= 128; \ + u >>= 1; \ + v >>= 1; \ + y &= ymask; \ + u &= uvmask; \ + v &= uvmask; \ + if (y == -128) { \ y += (0xFFFFFFFF - ymask + 1); \ } \ - if (u == -128) { \ + if (u == -128) { \ u += (0xFFFFFFFF - uvmask + 1); \ } \ - if (v == -128) { \ + if (v == -128) { \ v += (0xFFFFFFFF - uvmask + 1); \ } \ } while (0) From 0c249ff71c094c0e009e2ccaef5237af3610b0fb Mon Sep 17 00:00:00 2001 From: Li Zhijian Date: Thu, 17 Jan 2019 20:49:01 +0800 Subject: [PATCH 35/76] unify len and addr type for memory/address APIs Some address/memory APIs have different type between 'hwaddr/target_ulong addr' and 'int len'. It is very unsafe, especially some APIs will be passed a non-int len by caller which might cause overflow quietly. Below is an potential overflow case: dma_memory_read(uint32_t len) -> dma_memory_rw(uint32_t len) -> dma_memory_rw_relaxed(uint32_t len) -> address_space_rw(int len) # len overflow CC: Paolo Bonzini CC: Peter Crosthwaite CC: Richard Henderson CC: Peter Maydell CC: Stefano Garzarella Signed-off-by: Li Zhijian Reviewed-by: Peter Maydell Reviewed-by: Richard Henderson Reviewed-by: Stefano Garzarella Signed-off-by: Paolo Bonzini --- exec.c | 47 +++++++++++++++++++-------------------- include/exec/cpu-all.h | 2 +- include/exec/cpu-common.h | 8 +++---- include/exec/memory.h | 22 +++++++++--------- 4 files changed, 39 insertions(+), 40 deletions(-) diff --git a/exec.c b/exec.c index 03dd673d36d..518064530bd 100644 --- a/exec.c +++ b/exec.c @@ -2851,10 +2851,10 @@ static const MemoryRegionOps watch_mem_ops = { }; static MemTxResult flatview_read(FlatView *fv, hwaddr addr, - MemTxAttrs attrs, uint8_t *buf, int len); + MemTxAttrs attrs, uint8_t *buf, hwaddr len); static MemTxResult flatview_write(FlatView *fv, hwaddr addr, MemTxAttrs attrs, - const uint8_t *buf, int len); -static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len, + const uint8_t *buf, hwaddr len); +static bool flatview_access_valid(FlatView *fv, hwaddr addr, hwaddr len, bool is_write, MemTxAttrs attrs); static MemTxResult subpage_read(void *opaque, hwaddr addr, uint64_t *data, @@ -3102,10 +3102,10 @@ MemoryRegion *get_system_io(void) /* physical memory access (slow version, mainly for debug) */ #if defined(CONFIG_USER_ONLY) int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr, - uint8_t *buf, int len, int is_write) + uint8_t *buf, target_ulong len, int is_write) { - int l, flags; - target_ulong page; + int flags; + target_ulong l, page; void * p; while (len > 0) { @@ -3231,7 +3231,7 @@ static bool prepare_mmio_access(MemoryRegion *mr) static MemTxResult flatview_write_continue(FlatView *fv, hwaddr addr, MemTxAttrs attrs, const uint8_t *buf, - int len, hwaddr addr1, + hwaddr len, hwaddr addr1, hwaddr l, MemoryRegion *mr) { uint8_t *ptr; @@ -3276,7 +3276,7 @@ static MemTxResult flatview_write_continue(FlatView *fv, hwaddr addr, /* Called from RCU critical section. */ static MemTxResult flatview_write(FlatView *fv, hwaddr addr, MemTxAttrs attrs, - const uint8_t *buf, int len) + const uint8_t *buf, hwaddr len) { hwaddr l; hwaddr addr1; @@ -3294,7 +3294,7 @@ static MemTxResult flatview_write(FlatView *fv, hwaddr addr, MemTxAttrs attrs, /* Called within RCU critical section. */ MemTxResult flatview_read_continue(FlatView *fv, hwaddr addr, MemTxAttrs attrs, uint8_t *buf, - int len, hwaddr addr1, hwaddr l, + hwaddr len, hwaddr addr1, hwaddr l, MemoryRegion *mr) { uint8_t *ptr; @@ -3337,7 +3337,7 @@ MemTxResult flatview_read_continue(FlatView *fv, hwaddr addr, /* Called from RCU critical section. */ static MemTxResult flatview_read(FlatView *fv, hwaddr addr, - MemTxAttrs attrs, uint8_t *buf, int len) + MemTxAttrs attrs, uint8_t *buf, hwaddr len) { hwaddr l; hwaddr addr1; @@ -3350,7 +3350,7 @@ static MemTxResult flatview_read(FlatView *fv, hwaddr addr, } MemTxResult address_space_read_full(AddressSpace *as, hwaddr addr, - MemTxAttrs attrs, uint8_t *buf, int len) + MemTxAttrs attrs, uint8_t *buf, hwaddr len) { MemTxResult result = MEMTX_OK; FlatView *fv; @@ -3367,7 +3367,7 @@ MemTxResult address_space_read_full(AddressSpace *as, hwaddr addr, MemTxResult address_space_write(AddressSpace *as, hwaddr addr, MemTxAttrs attrs, - const uint8_t *buf, int len) + const uint8_t *buf, hwaddr len) { MemTxResult result = MEMTX_OK; FlatView *fv; @@ -3383,7 +3383,7 @@ MemTxResult address_space_write(AddressSpace *as, hwaddr addr, } MemTxResult address_space_rw(AddressSpace *as, hwaddr addr, MemTxAttrs attrs, - uint8_t *buf, int len, bool is_write) + uint8_t *buf, hwaddr len, bool is_write) { if (is_write) { return address_space_write(as, addr, attrs, buf, len); @@ -3393,7 +3393,7 @@ MemTxResult address_space_rw(AddressSpace *as, hwaddr addr, MemTxAttrs attrs, } void cpu_physical_memory_rw(hwaddr addr, uint8_t *buf, - int len, int is_write) + hwaddr len, int is_write) { address_space_rw(&address_space_memory, addr, MEMTXATTRS_UNSPECIFIED, buf, len, is_write); @@ -3408,7 +3408,7 @@ static inline MemTxResult address_space_write_rom_internal(AddressSpace *as, hwaddr addr, MemTxAttrs attrs, const uint8_t *buf, - int len, + hwaddr len, enum write_rom_type type) { hwaddr l; @@ -3448,13 +3448,13 @@ static inline MemTxResult address_space_write_rom_internal(AddressSpace *as, /* used for ROM loading : can write in RAM and ROM */ MemTxResult address_space_write_rom(AddressSpace *as, hwaddr addr, MemTxAttrs attrs, - const uint8_t *buf, int len) + const uint8_t *buf, hwaddr len) { return address_space_write_rom_internal(as, addr, attrs, buf, len, WRITE_DATA); } -void cpu_flush_icache_range(hwaddr start, int len) +void cpu_flush_icache_range(hwaddr start, hwaddr len) { /* * This function should do the same thing as an icache flush that was @@ -3557,7 +3557,7 @@ static void cpu_notify_map_clients(void) qemu_mutex_unlock(&map_client_list_lock); } -static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len, +static bool flatview_access_valid(FlatView *fv, hwaddr addr, hwaddr len, bool is_write, MemTxAttrs attrs) { MemoryRegion *mr; @@ -3580,7 +3580,7 @@ static bool flatview_access_valid(FlatView *fv, hwaddr addr, int len, } bool address_space_access_valid(AddressSpace *as, hwaddr addr, - int len, bool is_write, + hwaddr len, bool is_write, MemTxAttrs attrs) { FlatView *fv; @@ -3833,7 +3833,7 @@ static inline MemoryRegion *address_space_translate_cached( */ void address_space_read_cached_slow(MemoryRegionCache *cache, hwaddr addr, - void *buf, int len) + void *buf, hwaddr len) { hwaddr addr1, l; MemoryRegion *mr; @@ -3851,7 +3851,7 @@ address_space_read_cached_slow(MemoryRegionCache *cache, hwaddr addr, */ void address_space_write_cached_slow(MemoryRegionCache *cache, hwaddr addr, - const void *buf, int len) + const void *buf, hwaddr len) { hwaddr addr1, l; MemoryRegion *mr; @@ -3874,11 +3874,10 @@ address_space_write_cached_slow(MemoryRegionCache *cache, hwaddr addr, /* virtual memory access for debug (includes writing to ROM) */ int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr, - uint8_t *buf, int len, int is_write) + uint8_t *buf, target_ulong len, int is_write) { - int l; hwaddr phys_addr; - target_ulong page; + target_ulong l, page; cpu_synchronize_state(cpu); while (len > 0) { diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h index 117d2fbbcac..b16c9ec513f 100644 --- a/include/exec/cpu-all.h +++ b/include/exec/cpu-all.h @@ -367,7 +367,7 @@ void dump_opcount_info(FILE *f, fprintf_function cpu_fprintf); #endif /* !CONFIG_USER_ONLY */ int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr, - uint8_t *buf, int len, int is_write); + uint8_t *buf, target_ulong len, int is_write); int cpu_exec(CPUState *cpu); diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h index 2ad2d6d86bb..63ec1f9b373 100644 --- a/include/exec/cpu-common.h +++ b/include/exec/cpu-common.h @@ -83,14 +83,14 @@ size_t qemu_ram_pagesize(RAMBlock *block); size_t qemu_ram_pagesize_largest(void); void cpu_physical_memory_rw(hwaddr addr, uint8_t *buf, - int len, int is_write); + hwaddr len, int is_write); static inline void cpu_physical_memory_read(hwaddr addr, - void *buf, int len) + void *buf, hwaddr len) { cpu_physical_memory_rw(addr, buf, len, 0); } static inline void cpu_physical_memory_write(hwaddr addr, - const void *buf, int len) + const void *buf, hwaddr len) { cpu_physical_memory_rw(addr, (void *)buf, len, 1); } @@ -111,7 +111,7 @@ bool cpu_physical_memory_is_io(hwaddr phys_addr); */ void qemu_flush_coalesced_mmio_buffer(void); -void cpu_flush_icache_range(hwaddr start, int len); +void cpu_flush_icache_range(hwaddr start, hwaddr len); extern struct MemoryRegion io_mem_rom; extern struct MemoryRegion io_mem_notdirty; diff --git a/include/exec/memory.h b/include/exec/memory.h index abe9cc79c0d..1625913f84e 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -1791,7 +1791,7 @@ void address_space_destroy(AddressSpace *as); */ MemTxResult address_space_rw(AddressSpace *as, hwaddr addr, MemTxAttrs attrs, uint8_t *buf, - int len, bool is_write); + hwaddr len, bool is_write); /** * address_space_write: write to address space. @@ -1808,7 +1808,7 @@ MemTxResult address_space_rw(AddressSpace *as, hwaddr addr, */ MemTxResult address_space_write(AddressSpace *as, hwaddr addr, MemTxAttrs attrs, - const uint8_t *buf, int len); + const uint8_t *buf, hwaddr len); /** * address_space_write_rom: write to address space, including ROM. @@ -1834,7 +1834,7 @@ MemTxResult address_space_write(AddressSpace *as, hwaddr addr, */ MemTxResult address_space_write_rom(AddressSpace *as, hwaddr addr, MemTxAttrs attrs, - const uint8_t *buf, int len); + const uint8_t *buf, hwaddr len); /* address_space_ld*: load from an address space * address_space_st*: store to an address space @@ -2035,7 +2035,7 @@ static inline MemoryRegion *address_space_translate(AddressSpace *as, * @is_write: indicates the transfer direction * @attrs: memory attributes */ -bool address_space_access_valid(AddressSpace *as, hwaddr addr, int len, +bool address_space_access_valid(AddressSpace *as, hwaddr addr, hwaddr len, bool is_write, MemTxAttrs attrs); /* address_space_map: map a physical memory region into a host virtual address @@ -2072,19 +2072,19 @@ void address_space_unmap(AddressSpace *as, void *buffer, hwaddr len, /* Internal functions, part of the implementation of address_space_read. */ MemTxResult address_space_read_full(AddressSpace *as, hwaddr addr, - MemTxAttrs attrs, uint8_t *buf, int len); + MemTxAttrs attrs, uint8_t *buf, hwaddr len); MemTxResult flatview_read_continue(FlatView *fv, hwaddr addr, MemTxAttrs attrs, uint8_t *buf, - int len, hwaddr addr1, hwaddr l, + hwaddr len, hwaddr addr1, hwaddr l, MemoryRegion *mr); void *qemu_map_ram_ptr(RAMBlock *ram_block, ram_addr_t addr); /* Internal functions, part of the implementation of address_space_read_cached * and address_space_write_cached. */ void address_space_read_cached_slow(MemoryRegionCache *cache, - hwaddr addr, void *buf, int len); + hwaddr addr, void *buf, hwaddr len); void address_space_write_cached_slow(MemoryRegionCache *cache, - hwaddr addr, const void *buf, int len); + hwaddr addr, const void *buf, hwaddr len); static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write) { @@ -2112,7 +2112,7 @@ static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write) static inline __attribute__((__always_inline__)) MemTxResult address_space_read(AddressSpace *as, hwaddr addr, MemTxAttrs attrs, uint8_t *buf, - int len) + hwaddr len) { MemTxResult result = MEMTX_OK; hwaddr l, addr1; @@ -2151,7 +2151,7 @@ MemTxResult address_space_read(AddressSpace *as, hwaddr addr, */ static inline void address_space_read_cached(MemoryRegionCache *cache, hwaddr addr, - void *buf, int len) + void *buf, hwaddr len) { assert(addr < cache->len && len <= cache->len - addr); if (likely(cache->ptr)) { @@ -2171,7 +2171,7 @@ address_space_read_cached(MemoryRegionCache *cache, hwaddr addr, */ static inline void address_space_write_cached(MemoryRegionCache *cache, hwaddr addr, - void *buf, int len) + void *buf, hwaddr len) { assert(addr < cache->len && len <= cache->len - addr); if (likely(cache->ptr)) { From 1f40547f5ce0c135faa7d14f066b97002fd8c204 Mon Sep 17 00:00:00 2001 From: Li Zhijian Date: Thu, 17 Jan 2019 20:49:02 +0800 Subject: [PATCH 36/76] hw/core/loader.c: Read as long as possible in load_image_size() Don't expect read(2) can always read as many as it's told. CC: Richard Henderson CC: Stefano Garzarella Signed-off-by: Li Zhijian Reviewed-by: Richard Henderson Reviewed-by: Stefano Garzarella Signed-off-by: Paolo Bonzini --- hw/core/loader.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/hw/core/loader.c b/hw/core/loader.c index 3a000d576b3..fe5cb241225 100644 --- a/hw/core/loader.c +++ b/hw/core/loader.c @@ -77,21 +77,20 @@ int64_t get_image_size(const char *filename) ssize_t load_image_size(const char *filename, void *addr, size_t size) { int fd; - ssize_t actsize; + ssize_t actsize, l = 0; fd = open(filename, O_RDONLY | O_BINARY); if (fd < 0) { return -1; } - actsize = read(fd, addr, size); - if (actsize < 0) { - close(fd); - return -1; + while ((actsize = read(fd, addr + l, size - l)) > 0) { + l += actsize; } + close(fd); - return actsize; + return actsize < 0 ? -1 : l; } /* read()-like version */ From 06e0259a7c6acc25da7683d14a02e42660ed9933 Mon Sep 17 00:00:00 2001 From: Li Zhijian Date: Thu, 17 Jan 2019 20:49:03 +0800 Subject: [PATCH 37/76] i386: import & use bootparam.h it's from v4.20-rc5. CC: Stefano Garzarella CC: Michael S. Tsirkin Signed-off-by: Li Zhijian Reviewed-by: Michael S. Tsirkin Reviewed-by: Stefano Garzarella Signed-off-by: Paolo Bonzini --- hw/i386/pc.c | 8 +---- include/standard-headers/asm-x86/bootparam.h | 34 ++++++++++++++++++++ scripts/update-linux-headers.sh | 6 ++++ 3 files changed, 41 insertions(+), 7 deletions(-) create mode 100644 include/standard-headers/asm-x86/bootparam.h diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 00166d19d82..9664822fc8f 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -76,6 +76,7 @@ #include "hw/usb.h" #include "hw/i386/intel_iommu.h" #include "hw/net/ne2000-isa.h" +#include "standard-headers/asm-x86/bootparam.h" /* debug PC/ISA interrupts */ //#define DEBUG_IRQ @@ -1059,13 +1060,6 @@ static long get_file_size(FILE *f) return size; } -/* setup_data types */ -#define SETUP_NONE 0 -#define SETUP_E820_EXT 1 -#define SETUP_DTB 2 -#define SETUP_PCI 3 -#define SETUP_EFI 4 - struct setup_data { uint64_t next; uint32_t type; diff --git a/include/standard-headers/asm-x86/bootparam.h b/include/standard-headers/asm-x86/bootparam.h new file mode 100644 index 00000000000..67d4f0119f4 --- /dev/null +++ b/include/standard-headers/asm-x86/bootparam.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +#ifndef _ASM_X86_BOOTPARAM_H +#define _ASM_X86_BOOTPARAM_H + +/* setup_data types */ +#define SETUP_NONE 0 +#define SETUP_E820_EXT 1 +#define SETUP_DTB 2 +#define SETUP_PCI 3 +#define SETUP_EFI 4 +#define SETUP_APPLE_PROPERTIES 5 +#define SETUP_JAILHOUSE 6 + +/* ram_size flags */ +#define RAMDISK_IMAGE_START_MASK 0x07FF +#define RAMDISK_PROMPT_FLAG 0x8000 +#define RAMDISK_LOAD_FLAG 0x4000 + +/* loadflags */ +#define LOADED_HIGH (1<<0) +#define KASLR_FLAG (1<<1) +#define QUIET_FLAG (1<<5) +#define KEEP_SEGMENTS (1<<6) +#define CAN_USE_HEAP (1<<7) + +/* xloadflags */ +#define XLF_KERNEL_64 (1<<0) +#define XLF_CAN_BE_LOADED_ABOVE_4G (1<<1) +#define XLF_EFI_HANDOVER_32 (1<<2) +#define XLF_EFI_HANDOVER_64 (1<<3) +#define XLF_EFI_KEXEC (1<<4) + + +#endif /* _ASM_X86_BOOTPARAM_H */ diff --git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers.sh index 0a964fe240d..3578cfe5724 100755 --- a/scripts/update-linux-headers.sh +++ b/scripts/update-linux-headers.sh @@ -120,6 +120,12 @@ for arch in $ARCHLIST; do cp "$tmpdir/include/asm/unistd_x32.h" "$output/linux-headers/asm-x86/" cp "$tmpdir/include/asm/unistd_64.h" "$output/linux-headers/asm-x86/" cp_portable "$tmpdir/include/asm/kvm_para.h" "$output/include/standard-headers/asm-$arch" + # Remove everything except the macros from bootparam.h avoiding the + # unnecessary import of several video/ist/etc headers + sed -e '/__ASSEMBLY__/,/__ASSEMBLY__/d' \ + "$tmpdir/include/asm/bootparam.h" > "$tmpdir/bootparam.h" + cp_portable "$tmpdir/bootparam.h" \ + "$output/include/standard-headers/asm-$arch" fi done From aab50e53440b2fe432a5a59cbd0e7ec241a1169b Mon Sep 17 00:00:00 2001 From: Li Zhijian Date: Thu, 17 Jan 2019 20:49:04 +0800 Subject: [PATCH 38/76] i386: allow to load initrd below 4 GB for recent linux Since linux commit: cf8fa920cb42 ("i386: handle an initrd in highmem (version 2)") linux has supported initrd up to 4 GB, but the header field ramdisk_max is still set to 2 GB to avoid "possible bootloader bugs". When use '-kernel vmlinux -initrd initrd.cgz' to launch a VM, the firmware(it could be linuxboot_dma.bin) helps to read initrd contents into guest memory(below ramdisk_max) and jump to kernel. that's similar with what bootloader does, like grub. In addition, initrd_max is uint32_t simply because QEMU doesn't support the 64-bit boot protocol (specifically the ext_ramdisk_image field). Therefore here just limit initrd_max to UINT32_MAX simply as well to allow initrd to be loaded below 4 GB. NOTE: it's possible that linux protocol within [0x208, 0x20c] supports up to 4 GB initrd as well. CC: Paolo Bonzini CC: Richard Henderson CC: Eduardo Habkost CC: "Michael S. Tsirkin" CC: Marcel Apfelbaum Signed-off-by: Li Zhijian Reviewed-by: Eduardo Habkost Reviewed-by: Stefano Garzarella Signed-off-by: Paolo Bonzini --- hw/i386/pc.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 9664822fc8f..7d8f351b1df 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1299,7 +1299,26 @@ static void load_linux(PCMachineState *pcms, #endif /* highest address for loading the initrd */ - if (protocol >= 0x203) { + if (protocol >= 0x20c && + lduw_p(header+0x236) & XLF_CAN_BE_LOADED_ABOVE_4G) { + /* + * Linux has supported initrd up to 4 GB for a very long time (2007, + * long before XLF_CAN_BE_LOADED_ABOVE_4G which was added in 2013), + * though it only sets initrd_max to 2 GB to "work around bootloader + * bugs". Luckily, QEMU firmware(which does something like bootloader) + * has supported this. + * + * It's believed that if XLF_CAN_BE_LOADED_ABOVE_4G is set, initrd can + * be loaded into any address. + * + * In addition, initrd_max is uint32_t simply because QEMU doesn't + * support the 64-bit boot protocol (specifically the ext_ramdisk_image + * field). + * + * Therefore here just limit initrd_max to UINT32_MAX simply as well. + */ + initrd_max = UINT32_MAX; + } else if (protocol >= 0x203) { initrd_max = ldl_p(header+0x22c); } else { initrd_max = 0x37ffffff; From dce5874fc70fe8a50e4dab9f6b105e84768cae07 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 12 Dec 2018 15:22:18 +0100 Subject: [PATCH 39/76] docker: adjust Xen repository for CentOS 7 The Xen repository is failing to install, pick the right name for the release package. Signed-off-by: Paolo Bonzini --- tests/docker/dockerfiles/centos7.docker | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/docker/dockerfiles/centos7.docker b/tests/docker/dockerfiles/centos7.docker index e0f18f5a41b..e0b9d7dbe9f 100644 --- a/tests/docker/dockerfiles/centos7.docker +++ b/tests/docker/dockerfiles/centos7.docker @@ -1,5 +1,6 @@ FROM centos:7 -RUN yum install -y epel-release centos-release-xen +RUN yum install -y epel-release centos-release-xen-48 + RUN yum -y update ENV PACKAGES \ bison \ @@ -8,7 +9,7 @@ ENV PACKAGES \ ccache \ csnappy-devel \ flex \ - g++ \ + gcc-c++ \ gcc \ gettext \ git \ From 1edead0f72acc146298c3d4913a7705b2c4a1baa Mon Sep 17 00:00:00 2001 From: Roman Bolshakov Date: Fri, 25 Jan 2019 18:47:43 +0300 Subject: [PATCH 40/76] i386: hvf: Don't miss 16-bit displacement In 16-bit addressing mode, when Mod = 0 and R/M = 6, decoded displacement doesn't reach decode_linear_addr and gets lost. Instructions that involve the combination of ModRM always get a pointer with zero offset from the beginning of DS segment. The change fixes drawing in F-BIRD from day 1 of '18 advent calendar. Signed-off-by: Roman Bolshakov Message-Id: <20190125154743.14498-1-r.bolshakov@yadro.com> Signed-off-by: Paolo Bonzini --- target/i386/hvf/x86_decode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/i386/hvf/x86_decode.c b/target/i386/hvf/x86_decode.c index 5f513c55635..9ef7d7513f8 100644 --- a/target/i386/hvf/x86_decode.c +++ b/target/i386/hvf/x86_decode.c @@ -1642,7 +1642,7 @@ void calc_modrm_operand16(CPUX86State *env, struct x86_decode *decode, X86Seg seg = R_DS; if (!decode->modrm.mod && 6 == decode->modrm.rm) { - op->ptr = (uint16_t)decode->displacement; + ptr = decode->displacement; goto calc_addr; } From 7b0f97bade8a30eb756739442ea998ef0ab8ab96 Mon Sep 17 00:00:00 2001 From: Doug Gale Date: Thu, 24 Jan 2019 00:34:57 -0330 Subject: [PATCH 41/76] gdbstub: Fix i386/x86_64 machine description and add control registers The machine description we send is being (silently) thrown on the floor by GDB and GDB silently uses the default machine description, because the xml parse fails on nested within . Changes to the xml in qemu source code have no effect. In addition, the default machine description has fs_base, which fails to be retrieved, which breaks the whole register window. Add it and the other control registers. Signed-off-by: Doug Gale Message-Id: <20190124040457.2546-1-doug16k@gmail.com> Signed-off-by: Paolo Bonzini --- configure | 4 +- gdb-xml/i386-32bit-core.xml | 65 ----------- gdb-xml/i386-32bit-sse.xml | 52 --------- gdb-xml/i386-32bit.xml | 184 ++++++++++++++++++++++++++++++- gdb-xml/i386-64bit-core.xml | 73 ------------- gdb-xml/i386-64bit-sse.xml | 60 ----------- gdb-xml/i386-64bit.xml | 210 +++++++++++++++++++++++++++++++++++- target/i386/cpu.c | 4 +- target/i386/gdbstub.c | 193 ++++++++++++++++++++++++++++++++- 9 files changed, 580 insertions(+), 265 deletions(-) delete mode 100644 gdb-xml/i386-32bit-core.xml delete mode 100644 gdb-xml/i386-32bit-sse.xml delete mode 100644 gdb-xml/i386-64bit-core.xml delete mode 100644 gdb-xml/i386-64bit-sse.xml diff --git a/configure b/configure index 244bc7acd5d..558170cb64e 100755 --- a/configure +++ b/configure @@ -7137,14 +7137,14 @@ TARGET_ABI_DIR="" case "$target_name" in i386) mttcg="yes" - gdb_xml_files="i386-32bit.xml i386-32bit-core.xml i386-32bit-sse.xml" + gdb_xml_files="i386-32bit.xml" target_compiler=$cross_cc_i386 target_compiler_cflags=$cross_cc_ccflags_i386 ;; x86_64) TARGET_BASE_ARCH=i386 mttcg="yes" - gdb_xml_files="i386-64bit.xml i386-64bit-core.xml i386-64bit-sse.xml" + gdb_xml_files="i386-64bit.xml" target_compiler=$cross_cc_x86_64 ;; alpha) diff --git a/gdb-xml/i386-32bit-core.xml b/gdb-xml/i386-32bit-core.xml deleted file mode 100644 index 7aeeeca3b2c..00000000000 --- a/gdb-xml/i386-32bit-core.xml +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/gdb-xml/i386-32bit-sse.xml b/gdb-xml/i386-32bit-sse.xml deleted file mode 100644 index 57678473d6e..00000000000 --- a/gdb-xml/i386-32bit-sse.xml +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/gdb-xml/i386-32bit.xml b/gdb-xml/i386-32bit.xml index 956fc7f45f9..872fcea9c25 100644 --- a/gdb-xml/i386-32bit.xml +++ b/gdb-xml/i386-32bit.xml @@ -8,7 +8,185 @@ - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gdb-xml/i386-64bit-core.xml b/gdb-xml/i386-64bit-core.xml deleted file mode 100644 index 5088d84ceb1..00000000000 --- a/gdb-xml/i386-64bit-core.xml +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/gdb-xml/i386-64bit-sse.xml b/gdb-xml/i386-64bit-sse.xml deleted file mode 100644 index e86efc9ce54..00000000000 --- a/gdb-xml/i386-64bit-sse.xml +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/gdb-xml/i386-64bit.xml b/gdb-xml/i386-64bit.xml index 0b2f00ccbe8..6d889692114 100644 --- a/gdb-xml/i386-64bit.xml +++ b/gdb-xml/i386-64bit.xml @@ -5,10 +5,212 @@ are permitted in any medium without royalty provided the copyright notice and this notice are preserved. --> - + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 6f3b841723b..b0771966111 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -5870,10 +5870,10 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data) cc->gdb_arch_name = x86_gdb_arch_name; #ifdef TARGET_X86_64 cc->gdb_core_xml_file = "i386-64bit.xml"; - cc->gdb_num_core_regs = 57; + cc->gdb_num_core_regs = 66; #else cc->gdb_core_xml_file = "i386-32bit.xml"; - cc->gdb_num_core_regs = 41; + cc->gdb_num_core_regs = 50; #endif #if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY) cc->debug_excp_handler = breakpoint_handler; diff --git a/target/i386/gdbstub.c b/target/i386/gdbstub.c index 9b94ab852c7..1221433bc72 100644 --- a/target/i386/gdbstub.c +++ b/target/i386/gdbstub.c @@ -32,18 +32,61 @@ static const int gpr_map[16] = { #endif static const int gpr_map32[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; +/* + * Keep these in sync with assignment to + * gdb_num_core_regs in target/i386/cpu.c + * and with the machine description + */ + +/* + * SEG: 6 segments, plus fs_base, gs_base, kernel_gs_base + */ + +/* + * general regs -----> 8 or 16 + */ +#define IDX_NB_IP 1 +#define IDX_NB_FLAGS 1 +#define IDX_NB_SEG (6 + 3) +#define IDX_NB_CTL 6 +#define IDX_NB_FP 16 +/* + * fpu regs ----------> 8 or 16 + */ +#define IDX_NB_MXCSR 1 +/* + * total ----> 8+1+1+9+6+16+8+1=50 or 16+1+1+9+6+16+16+1=66 + */ + #define IDX_IP_REG CPU_NB_REGS -#define IDX_FLAGS_REG (IDX_IP_REG + 1) -#define IDX_SEG_REGS (IDX_FLAGS_REG + 1) -#define IDX_FP_REGS (IDX_SEG_REGS + 6) -#define IDX_XMM_REGS (IDX_FP_REGS + 16) +#define IDX_FLAGS_REG (IDX_IP_REG + IDX_NB_IP) +#define IDX_SEG_REGS (IDX_FLAGS_REG + IDX_NB_FLAGS) +#define IDX_CTL_REGS (IDX_SEG_REGS + IDX_NB_SEG) +#define IDX_FP_REGS (IDX_CTL_REGS + IDX_NB_CTL) +#define IDX_XMM_REGS (IDX_FP_REGS + IDX_NB_FP) #define IDX_MXCSR_REG (IDX_XMM_REGS + CPU_NB_REGS) +#define IDX_CTL_CR0_REG (IDX_CTL_REGS + 0) +#define IDX_CTL_CR2_REG (IDX_CTL_REGS + 1) +#define IDX_CTL_CR3_REG (IDX_CTL_REGS + 2) +#define IDX_CTL_CR4_REG (IDX_CTL_REGS + 3) +#define IDX_CTL_CR8_REG (IDX_CTL_REGS + 4) +#define IDX_CTL_EFER_REG (IDX_CTL_REGS + 5) + +#ifdef TARGET_X86_64 +#define GDB_FORCE_64 1 +#else +#define GDB_FORCE_64 0 +#endif + + int x86_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) { X86CPU *cpu = X86_CPU(cs); CPUX86State *env = &cpu->env; + uint64_t tpr; + /* N.B. GDB can't deal with changes in registers or sizes in the middle of a session. So if we're in 32-bit mode on a 64-bit cpu, still act as if we're on a 64-bit cpu. */ @@ -105,6 +148,28 @@ int x86_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) case IDX_SEG_REGS + 5: return gdb_get_reg32(mem_buf, env->segs[R_GS].selector); + case IDX_SEG_REGS + 6: + if ((env->hflags & HF_CS64_MASK) || GDB_FORCE_64) { + return gdb_get_reg64(mem_buf, env->segs[R_FS].base); + } + return gdb_get_reg32(mem_buf, env->segs[R_FS].base); + + case IDX_SEG_REGS + 7: + if ((env->hflags & HF_CS64_MASK) || GDB_FORCE_64) { + return gdb_get_reg64(mem_buf, env->segs[R_GS].base); + } + return gdb_get_reg32(mem_buf, env->segs[R_GS].base); + + case IDX_SEG_REGS + 8: +#ifdef TARGET_X86_64 + if ((env->hflags & HF_CS64_MASK) || GDB_FORCE_64) { + return gdb_get_reg64(mem_buf, env->kernelgsbase); + } + return gdb_get_reg32(mem_buf, env->kernelgsbase); +#else + return gdb_get_reg32(mem_buf, 0); +#endif + case IDX_FP_REGS + 8: return gdb_get_reg32(mem_buf, env->fpuc); case IDX_FP_REGS + 9: @@ -125,6 +190,47 @@ int x86_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) case IDX_MXCSR_REG: return gdb_get_reg32(mem_buf, env->mxcsr); + + case IDX_CTL_CR0_REG: + if ((env->hflags & HF_CS64_MASK) || GDB_FORCE_64) { + return gdb_get_reg64(mem_buf, env->cr[0]); + } + return gdb_get_reg32(mem_buf, env->cr[0]); + + case IDX_CTL_CR2_REG: + if ((env->hflags & HF_CS64_MASK) || GDB_FORCE_64) { + return gdb_get_reg64(mem_buf, env->cr[2]); + } + return gdb_get_reg32(mem_buf, env->cr[2]); + + case IDX_CTL_CR3_REG: + if ((env->hflags & HF_CS64_MASK) || GDB_FORCE_64) { + return gdb_get_reg64(mem_buf, env->cr[3]); + } + return gdb_get_reg32(mem_buf, env->cr[3]); + + case IDX_CTL_CR4_REG: + if ((env->hflags & HF_CS64_MASK) || GDB_FORCE_64) { + return gdb_get_reg64(mem_buf, env->cr[4]); + } + return gdb_get_reg32(mem_buf, env->cr[4]); + + case IDX_CTL_CR8_REG: +#ifdef CONFIG_SOFTMMU + tpr = cpu_get_apic_tpr(cpu->apic_state); +#else + tpr = 0; +#endif + if ((env->hflags & HF_CS64_MASK) || GDB_FORCE_64) { + return gdb_get_reg64(mem_buf, tpr); + } + return gdb_get_reg32(mem_buf, tpr); + + case IDX_CTL_EFER_REG: + if ((env->hflags & HF_CS64_MASK) || GDB_FORCE_64) { + return gdb_get_reg64(mem_buf, env->efer); + } + return gdb_get_reg32(mem_buf, env->efer); } } return 0; @@ -229,6 +335,32 @@ int x86_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) case IDX_SEG_REGS + 5: return x86_cpu_gdb_load_seg(cpu, R_GS, mem_buf); + case IDX_SEG_REGS + 6: + if (env->hflags & HF_CS64_MASK) { + env->segs[R_FS].base = ldq_p(mem_buf); + return 8; + } + env->segs[R_FS].base = ldl_p(mem_buf); + return 4; + + case IDX_SEG_REGS + 7: + if (env->hflags & HF_CS64_MASK) { + env->segs[R_GS].base = ldq_p(mem_buf); + return 8; + } + env->segs[R_GS].base = ldl_p(mem_buf); + return 4; + +#ifdef TARGET_X86_64 + case IDX_SEG_REGS + 8: + if (env->hflags & HF_CS64_MASK) { + env->kernelgsbase = ldq_p(mem_buf); + return 8; + } + env->kernelgsbase = ldl_p(mem_buf); + return 4; +#endif + case IDX_FP_REGS + 8: cpu_set_fpuc(env, ldl_p(mem_buf)); return 4; @@ -253,6 +385,59 @@ int x86_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) case IDX_MXCSR_REG: cpu_set_mxcsr(env, ldl_p(mem_buf)); return 4; + + case IDX_CTL_CR0_REG: + if (env->hflags & HF_CS64_MASK) { + cpu_x86_update_cr0(env, ldq_p(mem_buf)); + return 8; + } + cpu_x86_update_cr0(env, ldl_p(mem_buf)); + return 4; + + case IDX_CTL_CR2_REG: + if (env->hflags & HF_CS64_MASK) { + env->cr[2] = ldq_p(mem_buf); + return 8; + } + env->cr[2] = ldl_p(mem_buf); + return 4; + + case IDX_CTL_CR3_REG: + if (env->hflags & HF_CS64_MASK) { + cpu_x86_update_cr3(env, ldq_p(mem_buf)); + return 8; + } + cpu_x86_update_cr3(env, ldl_p(mem_buf)); + return 4; + + case IDX_CTL_CR4_REG: + if (env->hflags & HF_CS64_MASK) { + cpu_x86_update_cr4(env, ldq_p(mem_buf)); + return 8; + } + cpu_x86_update_cr4(env, ldl_p(mem_buf)); + return 4; + + case IDX_CTL_CR8_REG: + if (env->hflags & HF_CS64_MASK) { +#ifdef CONFIG_SOFTMMU + cpu_set_apic_tpr(cpu->apic_state, ldq_p(mem_buf)); +#endif + return 8; + } +#ifdef CONFIG_SOFTMMU + cpu_set_apic_tpr(cpu->apic_state, ldl_p(mem_buf)); +#endif + return 4; + + case IDX_CTL_EFER_REG: + if (env->hflags & HF_CS64_MASK) { + cpu_load_efer(env, ldq_p(mem_buf)); + return 8; + } + cpu_load_efer(env, ldl_p(mem_buf)); + return 4; + } } /* Unrecognised register. */ From e909ff93698851777faac3c45d03c1b73f311ea6 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Fri, 11 Jan 2019 17:27:31 +0100 Subject: [PATCH 42/76] scsi-generic: avoid possible out-of-bounds access to r->buf Whenever the allocation length of a SCSI request is shorter than the size of the VPD page list, page_idx is used blindly to index into r->buf. Even though the stores in the insertion sort are protected against overflows, the same is not true of the reads and the final store of 0xb0. This basically does the same thing as commit 57dbb58d80 ("scsi-generic: avoid out-of-bounds access to VPD page list", 2018-11-06), except that here the allocation length can be chosen by the guest. Note that according to the SCSI standard, the contents of the PAGE LENGTH field are not altered based on the allocation length. The code was introduced by commit 6c219fc8a1 ("scsi-generic: keep VPD page list sorted", 2018-11-06) but the overflow was already possible before. Reported-by: Kevin Wolf Fixes: a71c775b24ebc664129eb1d9b4c360590353efd5 Signed-off-by: Paolo Bonzini --- hw/scsi/scsi-generic.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c index 7237b4162e5..42700e88978 100644 --- a/hw/scsi/scsi-generic.c +++ b/hw/scsi/scsi-generic.c @@ -182,7 +182,7 @@ static void scsi_handle_inquiry_reply(SCSIGenericReq *r, SCSIDevice *s) /* Also take care of the opt xfer len. */ stl_be_p(&r->buf[12], MIN_NON_ZERO(max_transfer, ldl_be_p(&r->buf[12]))); - } else if (s->needs_vpd_bl_emulation && page == 0x00) { + } else if (s->needs_vpd_bl_emulation && page == 0x00 && r->buflen >= 4) { /* * Now we're capable of supplying the VPD Block Limits * response if the hardware can't. Add it in the INQUIRY @@ -193,18 +193,20 @@ static void scsi_handle_inquiry_reply(SCSIGenericReq *r, SCSIDevice *s) * and will use it to proper setup the SCSI device. * * VPD page numbers must be sorted, so insert 0xb0 at the - * right place with an in-place insert. After the initialization - * part of the for loop is executed, the device response is - * at r[0] to r[page_idx - 1]. + * right place with an in-place insert. When the while loop + * begins the device response is at r[0] to r[page_idx - 1]. */ - for (page_idx = lduw_be_p(r->buf + 2) + 4; - page_idx > 4 && r->buf[page_idx - 1] >= 0xb0; - page_idx--) { + page_idx = lduw_be_p(r->buf + 2) + 4; + page_idx = MIN(page_idx, r->buflen); + while (page_idx > 4 && r->buf[page_idx - 1] >= 0xb0) { if (page_idx < r->buflen) { r->buf[page_idx] = r->buf[page_idx - 1]; } + page_idx--; + } + if (page_idx < r->buflen) { + r->buf[page_idx] = 0xb0; } - r->buf[page_idx] = 0xb0; stw_be_p(r->buf + 2, lduw_be_p(r->buf + 2) + 1); } } From 292fa230cb9ef7d2ca2a1db59f0ff843e538f075 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Fri, 14 Dec 2018 13:21:13 +0100 Subject: [PATCH 43/76] Remove deprecated -enable-hax option Our command line interface is really quite overcrowded, we should avoid duplicated options that do the same thing in just a slightly different way. "-accel hax" is shorter and more generic that "-enable-hax", so there is really no real usage for the latter option. "-enable-hax" has been deprecated since two releases, and nobody complained so far, so it's time to remove this now. Signed-off-by: Thomas Huth Message-Id: <1544790073-23049-1-git-send-email-thuth@redhat.com> Signed-off-by: Paolo Bonzini --- qemu-deprecated.texi | 5 ----- qemu-options.hx | 11 ----------- vl.c | 5 ----- 3 files changed, 21 deletions(-) diff --git a/qemu-deprecated.texi b/qemu-deprecated.texi index 8a6174df0c1..dcf85a999bf 100644 --- a/qemu-deprecated.texi +++ b/qemu-deprecated.texi @@ -53,11 +53,6 @@ Option @option{-virtioconsole} has been replaced by The @code{-clock} option is ignored since QEMU version 1.7.0. There is no replacement since it is not needed anymore. -@subsection -enable-hax (since 3.0.0) - -The @option{-enable-hax} option has been replaced by @option{-accel hax}. -Both options have been introduced in QEMU version 2.9.0. - @subsection -drive file=json:@{...@{'driver':'file'@}@} (since 3.0) The 'file' driver for drives is no longer appropriate for character or host diff --git a/qemu-options.hx b/qemu-options.hx index 521511ec130..8f34dce71ba 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -3381,17 +3381,6 @@ Enable KVM full virtualization support. This option is only available if KVM support is enabled when compiling. ETEXI -DEF("enable-hax", 0, QEMU_OPTION_enable_hax, \ - "-enable-hax enable HAX virtualization support\n", QEMU_ARCH_I386) -STEXI -@item -enable-hax -@findex -enable-hax -Enable HAX (Hardware-based Acceleration eXecution) support. This option -is only available if HAX support is enabled when compiling. HAX is only -applicable to MAC and Windows platform, and thus does not conflict with -KVM. This option is deprecated, use @option{-accel hax} instead. -ETEXI - DEF("xen-domid", HAS_ARG, QEMU_OPTION_xen_domid, "-xen-domid id specify xen guest domain id\n", QEMU_ARCH_ALL) DEF("xen-attach", 0, QEMU_OPTION_xen_attach, diff --git a/vl.c b/vl.c index 9cf0fbe0b8c..804fbdb0e36 100644 --- a/vl.c +++ b/vl.c @@ -3655,11 +3655,6 @@ int main(int argc, char **argv, char **envp) olist = qemu_find_opts("machine"); qemu_opts_parse_noisily(olist, "accel=kvm", false); break; - case QEMU_OPTION_enable_hax: - warn_report("Option is deprecated, use '-accel hax' instead"); - olist = qemu_find_opts("machine"); - qemu_opts_parse_noisily(olist, "accel=hax", false); - break; case QEMU_OPTION_M: case QEMU_OPTION_machine: olist = qemu_find_opts("machine"); From 9fd7e96aab30d219bceb67f768fed01bedf1199f Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Sat, 2 Feb 2019 11:45:32 +0100 Subject: [PATCH 44/76] qemu-options: Remove deprecated "-virtioconsole" option It's been deprecated since QEMU 3.0, and nobody complained so far, so it is time to remove this option now. Signed-off-by: Thomas Huth Message-Id: <1544684731-18828-1-git-send-email-thuth@redhat.com> Signed-off-by: Paolo Bonzini --- docs/qdev-device-use.txt | 4 --- include/hw/boards.h | 1 - qemu-deprecated.texi | 5 ---- qemu-options.hx | 10 ------- vl.c | 61 +--------------------------------------- 5 files changed, 1 insertion(+), 80 deletions(-) diff --git a/docs/qdev-device-use.txt b/docs/qdev-device-use.txt index 98229b3405b..cc53e97dcda 100644 --- a/docs/qdev-device-use.txt +++ b/docs/qdev-device-use.txt @@ -190,10 +190,6 @@ The appropriate DEVNAME depends on the machine type. For type "pc": -device usb-braille,chardev=braille -chardev braille,id=braille -* -virtioconsole becomes - -device virtio-serial-pci,class=C,vectors=V,ioeventfd=IOEVENTFD,max_ports=N - -device virtconsole,is_console=NUM,nr=NR,name=NAME - LEGACY-CHARDEV translates to -chardev HOST-OPTS... as follows: * null becomes -chardev null diff --git a/include/hw/boards.h b/include/hw/boards.h index 02f114085f4..05f9f45c3d0 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -180,7 +180,6 @@ struct MachineClass { int default_cpus; unsigned int no_serial:1, no_parallel:1, - use_virtcon:1, no_floppy:1, no_cdrom:1, no_sdcard:1, diff --git a/qemu-deprecated.texi b/qemu-deprecated.texi index dcf85a999bf..87c4e55cfcd 100644 --- a/qemu-deprecated.texi +++ b/qemu-deprecated.texi @@ -43,11 +43,6 @@ The @code{--no-frame} argument works with SDL 1.2 only. The other user interfaces never implemented this in the first place. So this will be removed together with SDL 1.2 support. -@subsection -virtioconsole (since 3.0.0) - -Option @option{-virtioconsole} has been replaced by -@option{-device virtconsole}. - @subsection -clock (since 3.0.0) The @code{-clock} option is ignored since QEMU version 1.7.0. There is no diff --git a/qemu-options.hx b/qemu-options.hx index 8f34dce71ba..2769c0c0a3e 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -3616,16 +3616,6 @@ character to Control-t. @end table ETEXI -DEF("virtioconsole", HAS_ARG, QEMU_OPTION_virtiocon, \ - "-virtioconsole c\n" \ - " set virtio console\n", QEMU_ARCH_ALL) -STEXI -@item -virtioconsole @var{c} -@findex -virtioconsole -Set virtio console. -This option is deprecated, please use @option{-device virtconsole} instead. -ETEXI - DEF("show-cursor", 0, QEMU_OPTION_show_cursor, \ "-show-cursor show cursor\n", QEMU_ARCH_ALL) STEXI diff --git a/vl.c b/vl.c index 804fbdb0e36..41d6af29473 100644 --- a/vl.c +++ b/vl.c @@ -164,7 +164,6 @@ int no_frame; static int num_serial_hds; static Chardev **serial_hds; Chardev *parallel_hds[MAX_PARALLEL_PORTS]; -Chardev *virtcon_hds[MAX_VIRTIO_CONSOLES]; int win2k_install_hack = 0; int singlestep = 0; int smp_cpus; @@ -215,7 +214,6 @@ bool xen_domid_restrict; static int has_defaults = 1; static int default_serial = 1; static int default_parallel = 1; -static int default_virtcon = 1; static int default_monitor = 1; static int default_floppy = 1; static int default_cdrom = 1; @@ -236,8 +234,6 @@ static struct { { .driver = "ide-drive", .flag = &default_cdrom }, { .driver = "scsi-cd", .flag = &default_cdrom }, { .driver = "scsi-hd", .flag = &default_cdrom }, - { .driver = "virtio-serial-pci", .flag = &default_virtcon }, - { .driver = "virtio-serial", .flag = &default_virtcon }, { .driver = "VGA", .flag = &default_vga }, { .driver = "isa-vga", .flag = &default_vga }, { .driver = "cirrus-vga", .flag = &default_vga }, @@ -2405,7 +2401,6 @@ struct device_config { DEV_BT, /* -bt */ DEV_SERIAL, /* -serial */ DEV_PARALLEL, /* -parallel */ - DEV_VIRTCON, /* -virtioconsole */ DEV_DEBUGCON, /* -debugcon */ DEV_GDB, /* -gdb, -s */ DEV_SCLP, /* s390 sclp */ @@ -2503,39 +2498,6 @@ static int parallel_parse(const char *devname) return 0; } -static int virtcon_parse(const char *devname) -{ - QemuOptsList *device = qemu_find_opts("device"); - static int index = 0; - char label[32]; - QemuOpts *bus_opts, *dev_opts; - - if (strcmp(devname, "none") == 0) - return 0; - if (index == MAX_VIRTIO_CONSOLES) { - error_report("too many virtio consoles"); - exit(1); - } - - bus_opts = qemu_opts_create(device, NULL, 0, &error_abort); - qemu_opt_set(bus_opts, "driver", "virtio-serial", &error_abort); - - dev_opts = qemu_opts_create(device, NULL, 0, &error_abort); - qemu_opt_set(dev_opts, "driver", "virtconsole", &error_abort); - - snprintf(label, sizeof(label), "virtcon%d", index); - virtcon_hds[index] = qemu_chr_new_mux_mon(label, devname); - if (!virtcon_hds[index]) { - error_report("could not connect virtio console" - " to character backend '%s'", devname); - return -1; - } - qemu_opt_set(dev_opts, "chardev", label, &error_abort); - - index++; - return 0; -} - static int debugcon_parse(const char *devname) { QemuOpts *opts; @@ -3570,15 +3532,6 @@ int main(int argc, char **argv, char **envp) exit(1); } break; - case QEMU_OPTION_virtiocon: - warn_report("This option is deprecated, " - "use '-device virtconsole' instead"); - add_device_config(DEV_VIRTCON, optarg); - default_virtcon = 0; - if (strncmp(optarg, "mon:", 4) == 0) { - default_monitor = 0; - } - break; case QEMU_OPTION_parallel: add_device_config(DEV_PARALLEL, optarg); default_parallel = 0; @@ -4183,9 +4136,6 @@ int main(int argc, char **argv, char **envp) if (!has_defaults || machine_class->no_parallel) { default_parallel = 0; } - if (!has_defaults || !machine_class->use_virtcon) { - default_virtcon = 0; - } if (!has_defaults || machine_class->no_floppy) { default_floppy = 0; } @@ -4218,8 +4168,7 @@ int main(int argc, char **argv, char **envp) * usage, -nographic is just a no-op in this case. */ if (nographic - && (default_parallel || default_serial - || default_monitor || default_virtcon)) { + && (default_parallel || default_serial || default_monitor)) { error_report("-nographic cannot be used with -daemonize"); exit(1); } @@ -4236,13 +4185,9 @@ int main(int argc, char **argv, char **envp) add_device_config(DEV_PARALLEL, "null"); if (default_serial && default_monitor) { add_device_config(DEV_SERIAL, "mon:stdio"); - } else if (default_virtcon && default_monitor) { - add_device_config(DEV_VIRTCON, "mon:stdio"); } else { if (default_serial) add_device_config(DEV_SERIAL, "stdio"); - if (default_virtcon) - add_device_config(DEV_VIRTCON, "stdio"); if (default_monitor) monitor_parse("stdio", "readline", false); } @@ -4253,8 +4198,6 @@ int main(int argc, char **argv, char **envp) add_device_config(DEV_PARALLEL, "vc:80Cx24C"); if (default_monitor) monitor_parse("vc:80Cx24C", "readline", false); - if (default_virtcon) - add_device_config(DEV_VIRTCON, "vc:80Cx24C"); } #if defined(CONFIG_VNC) @@ -4485,8 +4428,6 @@ int main(int argc, char **argv, char **envp) exit(1); if (foreach_device_config(DEV_PARALLEL, parallel_parse) < 0) exit(1); - if (foreach_device_config(DEV_VIRTCON, virtcon_parse) < 0) - exit(1); if (foreach_device_config(DEV_DEBUGCON, debugcon_parse) < 0) exit(1); From d9bf2c5535b207c34d7b67ad93285f42bcd34aca Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Sat, 2 Feb 2019 15:24:30 +0800 Subject: [PATCH 45/76] arm: disable CONFIG_SERIAL_ISA ARM should not have an ISA bus, this device should not be enabled. Kconfig allows to clean up the dependencies and remove CONFIG_ISA_BUS=y from ARM, and then catches a contradiction between the hardcoded CONFIG_SERIAL_ISA=y and CONFIG_ISA_BUS=n. Signed-off-by: Paolo Bonzini Reviewed-by: Thomas Huth Message-Id: <20190202072456.6468-2-yang.zhong@intel.com> Signed-off-by: Paolo Bonzini --- default-configs/arm-softmmu.mak | 1 - 1 file changed, 1 deletion(-) diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak index be88870799c..d7b540cb25d 100644 --- a/default-configs/arm-softmmu.mak +++ b/default-configs/arm-softmmu.mak @@ -6,7 +6,6 @@ CONFIG_VGA=y CONFIG_NAND=y CONFIG_ECC=y CONFIG_SERIAL=y -CONFIG_SERIAL_ISA=y CONFIG_PTIMER=y CONFIG_SD=y CONFIG_MAX7310=y From 83d14054f95554fd4bdcf88b3c269b8aa13413f6 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Sat, 2 Feb 2019 15:24:31 +0800 Subject: [PATCH 46/76] ide: split ioport registration to a separate file This is not needed on ARM, and brings in ISA bus code which is otherwise not necessary. Signed-off-by: Paolo Bonzini Reviewed-by: Thomas Huth Message-Id: <20190202072456.6468-3-yang.zhong@intel.com> Signed-off-by: Paolo Bonzini --- hw/ide/Makefile.objs | 4 +-- hw/ide/core.c | 25 ----------------- hw/ide/ioport.c | 66 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 27 deletions(-) create mode 100644 hw/ide/ioport.c diff --git a/hw/ide/Makefile.objs b/hw/ide/Makefile.objs index fc328ffbe87..a142add90e9 100644 --- a/hw/ide/Makefile.objs +++ b/hw/ide/Makefile.objs @@ -1,8 +1,8 @@ common-obj-$(CONFIG_IDE_CORE) += core.o atapi.o common-obj-$(CONFIG_IDE_QDEV) += qdev.o common-obj-$(CONFIG_IDE_PCI) += pci.o -common-obj-$(CONFIG_IDE_ISA) += isa.o -common-obj-$(CONFIG_IDE_PIIX) += piix.o +common-obj-$(CONFIG_IDE_ISA) += isa.o ioport.o +common-obj-$(CONFIG_IDE_PIIX) += piix.o ioport.o common-obj-$(CONFIG_IDE_CMD646) += cmd646.o common-obj-$(CONFIG_IDE_MACIO) += macio.o common-obj-$(CONFIG_IDE_MMIO) += mmio.o diff --git a/hw/ide/core.c b/hw/ide/core.c index c3d779db6e0..84832008b82 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -2686,31 +2686,6 @@ void ide_exit(IDEState *s) qemu_vfree(s->io_buffer); } -static const MemoryRegionPortio ide_portio_list[] = { - { 0, 8, 1, .read = ide_ioport_read, .write = ide_ioport_write }, - { 0, 1, 2, .read = ide_data_readw, .write = ide_data_writew }, - { 0, 1, 4, .read = ide_data_readl, .write = ide_data_writel }, - PORTIO_END_OF_LIST(), -}; - -static const MemoryRegionPortio ide_portio2_list[] = { - { 0, 1, 1, .read = ide_status_read, .write = ide_cmd_write }, - PORTIO_END_OF_LIST(), -}; - -void ide_init_ioport(IDEBus *bus, ISADevice *dev, int iobase, int iobase2) -{ - /* ??? Assume only ISA and PCI configurations, and that the PCI-ISA - bridge has been setup properly to always register with ISA. */ - isa_register_portio_list(dev, &bus->portio_list, - iobase, ide_portio_list, bus, "ide"); - - if (iobase2) { - isa_register_portio_list(dev, &bus->portio2_list, - iobase2, ide_portio2_list, bus, "ide"); - } -} - static bool is_identify_set(void *opaque, int version_id) { IDEState *s = opaque; diff --git a/hw/ide/ioport.c b/hw/ide/ioport.c new file mode 100644 index 00000000000..a0b3c1f6a16 --- /dev/null +++ b/hw/ide/ioport.c @@ -0,0 +1,66 @@ +/* + * QEMU IDE disk and CD/DVD-ROM Emulator + * + * Copyright (c) 2003 Fabrice Bellard + * Copyright (c) 2006 Openedhand Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "qemu/osdep.h" +#include "hw/hw.h" +#include "hw/isa/isa.h" +#include "qemu/error-report.h" +#include "qemu/timer.h" +#include "sysemu/sysemu.h" +#include "sysemu/blockdev.h" +#include "sysemu/dma.h" +#include "hw/block/block.h" +#include "sysemu/block-backend.h" +#include "qapi/error.h" +#include "qemu/cutils.h" +#include "sysemu/replay.h" + +#include "hw/ide/internal.h" +#include "trace.h" + +static const MemoryRegionPortio ide_portio_list[] = { + { 0, 8, 1, .read = ide_ioport_read, .write = ide_ioport_write }, + { 0, 1, 2, .read = ide_data_readw, .write = ide_data_writew }, + { 0, 1, 4, .read = ide_data_readl, .write = ide_data_writel }, + PORTIO_END_OF_LIST(), +}; + +static const MemoryRegionPortio ide_portio2_list[] = { + { 0, 1, 1, .read = ide_status_read, .write = ide_cmd_write }, + PORTIO_END_OF_LIST(), +}; + +void ide_init_ioport(IDEBus *bus, ISADevice *dev, int iobase, int iobase2) +{ + /* ??? Assume only ISA and PCI configurations, and that the PCI-ISA + bridge has been setup properly to always register with ISA. */ + isa_register_portio_list(dev, &bus->portio_list, + iobase, ide_portio_list, bus, "ide"); + + if (iobase2) { + isa_register_portio_list(dev, &bus->portio2_list, + iobase2, ide_portio2_list, bus, "ide"); + } +} From e01ee04f8ba2cf561aee2660aa226d59040e8193 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Sat, 2 Feb 2019 15:24:32 +0800 Subject: [PATCH 47/76] vfio: move conditional up to hw/Makefile.objs Instead of wrapping the entire Makefile.objs with an ifeq/endif, just include the directory only for Linux. Signed-off-by: Paolo Bonzini Reviewed-by: Thomas Huth Message-Id: <20190202072456.6468-4-yang.zhong@intel.com> Signed-off-by: Paolo Bonzini --- hw/Makefile.objs | 2 +- hw/vfio/Makefile.objs | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/hw/Makefile.objs b/hw/Makefile.objs index 39d882af6f7..22dd2113636 100644 --- a/hw/Makefile.objs +++ b/hw/Makefile.objs @@ -30,7 +30,7 @@ devices-dirs-$(CONFIG_SOFTMMU) += ssi/ devices-dirs-$(CONFIG_SOFTMMU) += timer/ devices-dirs-$(CONFIG_TPM) += tpm/ devices-dirs-$(CONFIG_SOFTMMU) += usb/ -devices-dirs-$(CONFIG_SOFTMMU) += vfio/ +devices-dirs-$(CONFIG_LINUX) += vfio/ devices-dirs-$(CONFIG_SOFTMMU) += virtio/ devices-dirs-$(CONFIG_SOFTMMU) += watchdog/ devices-dirs-$(CONFIG_SOFTMMU) += xen/ diff --git a/hw/vfio/Makefile.objs b/hw/vfio/Makefile.objs index 8b3f664d85f..91805893f73 100644 --- a/hw/vfio/Makefile.objs +++ b/hw/vfio/Makefile.objs @@ -1,4 +1,3 @@ -ifeq ($(CONFIG_LINUX), y) obj-$(CONFIG_SOFTMMU) += common.o obj-$(CONFIG_PCI) += pci.o pci-quirks.o display.o obj-$(CONFIG_VFIO_CCW) += ccw.o @@ -7,4 +6,3 @@ obj-$(CONFIG_VFIO_XGMAC) += calxeda-xgmac.o obj-$(CONFIG_VFIO_AMD_XGBE) += amd-xgbe.o obj-$(CONFIG_SOFTMMU) += spapr.o obj-$(CONFIG_VFIO_AP) += ap.o -endif From 5afdd57ca00f1271094f9a6fb0e29d415a732fc7 Mon Sep 17 00:00:00 2001 From: Yang Zhong Date: Sat, 2 Feb 2019 15:24:33 +0800 Subject: [PATCH 48/76] hw/pci-host/Makefile.objs: make CONFIGS clear for PCI EXPRESS Change the CONFIGs for PCI EXPRESS and make module name more clear for code files. Signed-off-by: Yang Zhong Cc: Michael S. Tsirkin Signed-off-by: Paolo Bonzini Reviewed-by: Thomas Huth Message-Id: <20190202072456.6468-5-yang.zhong@intel.com> Signed-off-by: Paolo Bonzini --- default-configs/arm-softmmu.mak | 4 ++-- default-configs/i386-softmmu.mak | 2 +- default-configs/mips64el-softmmu.mak | 2 +- default-configs/pci.mak | 2 +- default-configs/riscv32-softmmu.mak | 2 +- default-configs/riscv64-softmmu.mak | 2 +- hw/net/Makefile.objs | 4 ++-- hw/pci-host/Makefile.objs | 8 ++++---- 8 files changed, 13 insertions(+), 13 deletions(-) diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak index d7b540cb25d..32f4a4ac272 100644 --- a/default-configs/arm-softmmu.mak +++ b/default-configs/arm-softmmu.mak @@ -123,7 +123,7 @@ CONFIG_VERSATILE=y CONFIG_VERSATILE_PCI=y CONFIG_VERSATILE_I2C=y -CONFIG_PCI_GENERIC=y +CONFIG_PCI_EXPRESS_GENERIC_BRIDGE=y CONFIG_VFIO_XGMAC=y CONFIG_VFIO_AMD_XGBE=y @@ -154,7 +154,7 @@ CONFIG_GPIO_KEY=y CONFIG_MSF2=y CONFIG_FW_CFG_DMA=y CONFIG_XILINX_AXI=y -CONFIG_PCI_DESIGNWARE=y +CONFIG_PCI_EXPRESS_DESIGNWARE=y CONFIG_STRONGARM=y CONFIG_HIGHBANK=y diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak index 64c998c4c81..2f919df3468 100644 --- a/default-configs/i386-softmmu.mak +++ b/default-configs/i386-softmmu.mak @@ -47,7 +47,7 @@ CONFIG_ISA_TESTDEV=y CONFIG_VMPORT=y CONFIG_SGA=y CONFIG_LPC_ICH9=y -CONFIG_PCI_Q35=y +CONFIG_PCI_EXPRESS_Q35=y CONFIG_APIC=y CONFIG_IOAPIC=y CONFIG_PVPANIC=y diff --git a/default-configs/mips64el-softmmu.mak b/default-configs/mips64el-softmmu.mak index c2ae313f473..9eb1208b582 100644 --- a/default-configs/mips64el-softmmu.mak +++ b/default-configs/mips64el-softmmu.mak @@ -12,4 +12,4 @@ CONFIG_JAZZ_LED=y CONFIG_VT82C686=y CONFIG_MIPS_BOSTON=y CONFIG_FITLOADER=y -CONFIG_PCI_XILINX=y +CONFIG_PCI_EXPRESS_XILINX=y diff --git a/default-configs/pci.mak b/default-configs/pci.mak index 6c7be127798..83738cbb65e 100644 --- a/default-configs/pci.mak +++ b/default-configs/pci.mak @@ -22,7 +22,7 @@ CONFIG_MEGASAS_SCSI_PCI=y CONFIG_MPTSAS_SCSI_PCI=y CONFIG_RTL8139_PCI=y CONFIG_E1000_PCI=y -CONFIG_E1000E_PCI=y +CONFIG_E1000E_PCI_EXPRESS=y CONFIG_IDE_CORE=y CONFIG_IDE_QDEV=y CONFIG_IDE_PCI=y diff --git a/default-configs/riscv32-softmmu.mak b/default-configs/riscv32-softmmu.mak index c9c59714093..fbfd1d4e4b5 100644 --- a/default-configs/riscv32-softmmu.mak +++ b/default-configs/riscv32-softmmu.mak @@ -8,7 +8,7 @@ CONFIG_VIRTIO_MMIO=y CONFIG_CADENCE=y -CONFIG_PCI_GENERIC=y +CONFIG_PCI_EXPRESS_GENERIC_BRIDGE=y CONFIG_VGA=y CONFIG_VGA_PCI=y diff --git a/default-configs/riscv64-softmmu.mak b/default-configs/riscv64-softmmu.mak index c9c59714093..fbfd1d4e4b5 100644 --- a/default-configs/riscv64-softmmu.mak +++ b/default-configs/riscv64-softmmu.mak @@ -8,7 +8,7 @@ CONFIG_VIRTIO_MMIO=y CONFIG_CADENCE=y -CONFIG_PCI_GENERIC=y +CONFIG_PCI_EXPRESS_GENERIC_BRIDGE=y CONFIG_VGA=y CONFIG_VGA_PCI=y diff --git a/hw/net/Makefile.objs b/hw/net/Makefile.objs index fa461d4463c..a43351aa04e 100644 --- a/hw/net/Makefile.objs +++ b/hw/net/Makefile.objs @@ -7,8 +7,8 @@ common-obj-$(CONFIG_EEPRO100_PCI) += eepro100.o common-obj-$(CONFIG_PCNET_PCI) += pcnet-pci.o common-obj-$(CONFIG_PCNET_COMMON) += pcnet.o common-obj-$(CONFIG_E1000_PCI) += e1000.o e1000x_common.o -common-obj-$(CONFIG_E1000E_PCI) += net_tx_pkt.o net_rx_pkt.o -common-obj-$(CONFIG_E1000E_PCI) += e1000e.o e1000e_core.o e1000x_common.o +common-obj-$(CONFIG_E1000E_PCI_EXPRESS) += net_tx_pkt.o net_rx_pkt.o +common-obj-$(CONFIG_E1000E_PCI_EXPRESS) += e1000e.o e1000e_core.o e1000x_common.o common-obj-$(CONFIG_RTL8139_PCI) += rtl8139.o common-obj-$(CONFIG_VMXNET3_PCI) += net_tx_pkt.o net_rx_pkt.o common-obj-$(CONFIG_VMXNET3_PCI) += vmxnet3.o diff --git a/hw/pci-host/Makefile.objs b/hw/pci-host/Makefile.objs index 6d6597c0656..073d5124d12 100644 --- a/hw/pci-host/Makefile.objs +++ b/hw/pci-host/Makefile.objs @@ -14,8 +14,8 @@ common-obj-$(CONFIG_VERSATILE_PCI) += versatile.o common-obj-$(CONFIG_PCI_SABRE) += sabre.o common-obj-$(CONFIG_FULONG) += bonito.o common-obj-$(CONFIG_PCI_PIIX) += piix.o -common-obj-$(CONFIG_PCI_Q35) += q35.o -common-obj-$(CONFIG_PCI_GENERIC) += gpex.o -common-obj-$(CONFIG_PCI_XILINX) += xilinx-pcie.o +common-obj-$(CONFIG_PCI_EXPRESS_Q35) += q35.o +common-obj-$(CONFIG_PCI_EXPRESS_GENERIC_BRIDGE) += gpex.o +common-obj-$(CONFIG_PCI_EXPRESS_XILINX) += xilinx-pcie.o -common-obj-$(CONFIG_PCI_DESIGNWARE) += designware.o +common-obj-$(CONFIG_PCI_EXPRESS_DESIGNWARE) += designware.o From 91b82fec16b0a63b5748e25a13f4df5fc41a1e08 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Sat, 2 Feb 2019 15:24:34 +0800 Subject: [PATCH 49/76] build: actually use CONFIG_PAM MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Do not link it unconditionally into all binaries. Signed-off-by: Paolo Bonzini Signed-off-by: Yang Zhong Reviewed-by: Thomas Huth Message-Id: <20190202072456.6468-6-yang.zhong@intel.com> Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Paolo Bonzini --- default-configs/i386-softmmu.mak | 1 + hw/pci-host/Makefile.objs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak index 2f919df3468..48da9968ccf 100644 --- a/default-configs/i386-softmmu.mak +++ b/default-configs/i386-softmmu.mak @@ -67,3 +67,4 @@ CONFIG_I2C=y CONFIG_SEV=$(CONFIG_KVM) CONFIG_VTD=y CONFIG_AMD_IOMMU=y +CONFIG_PAM=y diff --git a/hw/pci-host/Makefile.objs b/hw/pci-host/Makefile.objs index 073d5124d12..a9cd3e022d5 100644 --- a/hw/pci-host/Makefile.objs +++ b/hw/pci-host/Makefile.objs @@ -1,4 +1,4 @@ -common-obj-y += pam.o +common-obj-$(CONFIG_PAM) += pam.o # PPC devices common-obj-$(CONFIG_PREP_PCI) += prep.o From 80500ce6377602e002e0f50caaf6584000e091b5 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Sat, 2 Feb 2019 15:24:35 +0800 Subject: [PATCH 50/76] hw/i386/Makefile.objs: Build pc_piix* and pc_q35 boards MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CONFIG_PIIX and CONFIG_Q35 created for the pc board object files. These are enabled automatically at default-configs/i386-softmmu.mak and default-configs/x86_64-softmmu.mak Signed-off-by: Ákos Kovács Signed-off-by: Paolo Bonzini Reviewed-by: Thomas Huth Message-Id: <20190202072456.6468-7-yang.zhong@intel.com> Signed-off-by: Paolo Bonzini --- default-configs/i386-softmmu.mak | 2 ++ hw/i386/Makefile.objs | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak index 48da9968ccf..71c9f6fbcba 100644 --- a/default-configs/i386-softmmu.mak +++ b/default-configs/i386-softmmu.mak @@ -68,3 +68,5 @@ CONFIG_SEV=$(CONFIG_KVM) CONFIG_VTD=y CONFIG_AMD_IOMMU=y CONFIG_PAM=y +CONFIG_I440FX=y +CONFIG_Q35=y diff --git a/hw/i386/Makefile.objs b/hw/i386/Makefile.objs index fa87a141523..3de7ca2bb9e 100644 --- a/hw/i386/Makefile.objs +++ b/hw/i386/Makefile.objs @@ -1,6 +1,8 @@ obj-$(CONFIG_KVM) += kvm/ obj-y += multiboot.o -obj-y += pc.o pc_piix.o pc_q35.o +obj-y += pc.o +obj-$(CONFIG_I440FX) += pc_piix.o +obj-$(CONFIG_Q35) += pc_q35.o obj-y += pc_sysfw.o obj-$(CONFIG_VTD) += x86-iommu.o intel_iommu.o obj-$(CONFIG_AMD_IOMMU) += x86-iommu.o amd_iommu.o From abab3fdeef05be8b57baefa7d0f234b9bc471df3 Mon Sep 17 00:00:00 2001 From: Yang Zhong Date: Sat, 2 Feb 2019 15:24:36 +0800 Subject: [PATCH 51/76] hw/arm/Makefile.objs: CONFIG_ARM_VIRT created for virt board Make ARM virt code configurable and the new CONFIG_ARM_VIRT definitions added to the default-configs/arm-softmmu.mak. Signed-off-by: Yang Zhong Signed-off-by: Paolo Bonzini Reviewed-by: Richard Henderson Reviewed-by: Thomas Huth Message-Id: <20190202072456.6468-8-yang.zhong@intel.com> Signed-off-by: Paolo Bonzini --- default-configs/arm-softmmu.mak | 1 + hw/arm/Makefile.objs | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak index 32f4a4ac272..1db36396b1a 100644 --- a/default-configs/arm-softmmu.mak +++ b/default-configs/arm-softmmu.mak @@ -148,6 +148,7 @@ CONFIG_XIO3130=y CONFIG_IOH3420=y CONFIG_I82801B11=y CONFIG_ACPI=y +CONFIG_ARM_VIRT=y CONFIG_SMBIOS=y CONFIG_ASPEED_SOC=y CONFIG_GPIO_KEY=y diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs index 22b7f0ed0ba..fa40e8d6412 100644 --- a/hw/arm/Makefile.objs +++ b/hw/arm/Makefile.objs @@ -1,4 +1,5 @@ -obj-y += boot.o virt.o sysbus-fdt.o +obj-y += boot.o sysbus-fdt.o +obj-$(CONFIG_ARM_VIRT) += virt.o obj-$(CONFIG_ACPI) += virt-acpi-build.o obj-$(CONFIG_DIGIC) += digic_boards.o obj-$(CONFIG_EXYNOS4) += exynos4_boards.o From 48a166cf1d7ecb4a4b9bea79ec12d2e55fb2bb56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81kos=20Kov=C3=A1cs?= Date: Sat, 2 Feb 2019 15:24:37 +0800 Subject: [PATCH 52/76] hw/m68k/Makefile.objs: Conditionally build boards MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CONFIG_AN5206, CONFIG_MCF5206 and CONFIG_MCF5208 make variables created for m68k boards, and added to default-configs/m86k-softmmu.mak. Signed-off-by: Ákos Kovács Signed-off-by: Paolo Bonzini Reviewed-by: Thomas Huth Message-Id: <20190202072456.6468-9-yang.zhong@intel.com> Signed-off-by: Paolo Bonzini --- default-configs/m68k-softmmu.mak | 2 ++ hw/m68k/Makefile.objs | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/default-configs/m68k-softmmu.mak b/default-configs/m68k-softmmu.mak index 60f7cdfbf28..27f5274244a 100644 --- a/default-configs/m68k-softmmu.mak +++ b/default-configs/m68k-softmmu.mak @@ -2,3 +2,5 @@ CONFIG_COLDFIRE=y CONFIG_PTIMER=y +CONFIG_AN5206=y +CONFIG_MCF5208=y diff --git a/hw/m68k/Makefile.objs b/hw/m68k/Makefile.objs index d1f089c08a7..482f8477b46 100644 --- a/hw/m68k/Makefile.objs +++ b/hw/m68k/Makefile.objs @@ -1,2 +1,2 @@ -obj-y += an5206.o mcf5208.o -obj-y += mcf5206.o mcf_intc.o +obj-$(CONFIG_AN5206) += an5206.o mcf5206.o +obj-$(CONFIG_MCF5208) += mcf5208.o mcf_intc.o From 268dfefa690b2bdee1f8c5090d2343871cf3467c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81kos=20Kov=C3=A1cs?= Date: Sat, 2 Feb 2019 15:24:38 +0800 Subject: [PATCH 53/76] hw/microblaze/Makefile.objs: Create configs for petalogix and xilinx boards MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CONFIG_PETALOGIX_* and CONFIG_XLNX_* configs added to default-configs/microblaze-softmmu.mak and default-configs/microblazeel-softmmu.mak. Signed-off-by: Ákos Kovács Signed-off-by: Paolo Bonzini Reviewed-by: Thomas Huth Message-Id: <20190202072456.6468-10-yang.zhong@intel.com> Signed-off-by: Paolo Bonzini --- default-configs/microblaze-softmmu.mak | 3 +++ hw/microblaze/Makefile.objs | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/default-configs/microblaze-softmmu.mak b/default-configs/microblaze-softmmu.mak index 7fca8e4c992..14837cf74ac 100644 --- a/default-configs/microblaze-softmmu.mak +++ b/default-configs/microblaze-softmmu.mak @@ -10,3 +10,6 @@ CONFIG_XILINX_ETHLITE=y CONFIG_SSI=y CONFIG_SSI_M25P80=y CONFIG_XLNX_ZYNQMP=y +CONFIG_PETALOGIX_S3ADSP1800=y +CONFIG_PETALOGIX_ML605=y +CONFIG_XLNX_ZYNQMP_PMU=y diff --git a/hw/microblaze/Makefile.objs b/hw/microblaze/Makefile.objs index ae9fd40de75..8595a62f6c6 100644 --- a/hw/microblaze/Makefile.objs +++ b/hw/microblaze/Makefile.objs @@ -1,4 +1,4 @@ -obj-y += petalogix_s3adsp1800_mmu.o -obj-y += petalogix_ml605_mmu.o -obj-y += xlnx-zynqmp-pmu.o +obj-$(CONFIG_PETALOGIX_S3ADSP1800) += petalogix_s3adsp1800_mmu.o +obj-$(CONFIG_PETALOGIX_ML605) += petalogix_ml605_mmu.o +obj-$(CONFIG_XLNX_ZYNQMP_PMU) += xlnx-zynqmp-pmu.o obj-y += boot.o From ebd76795d4bfb6b429a55c43408672796f850469 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81kos=20Kov=C3=A1cs?= Date: Sat, 2 Feb 2019 15:24:39 +0800 Subject: [PATCH 54/76] hw/mips/Makefile.objs: Create CONFIG_* for r4k, malta, mipssim boards MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the new configs to default-configs/mips*-sofmmu.mak. Signed-off-by: Ákos Kovács Signed-off-by: Paolo Bonzini Signed-off-by: Yang Zhong Reviewed-by: Thomas Huth Message-Id: <20190202072456.6468-11-yang.zhong@intel.com> Signed-off-by: Paolo Bonzini --- default-configs/mips-softmmu-common.mak | 3 +++ hw/mips/Makefile.objs | 5 +++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/default-configs/mips-softmmu-common.mak b/default-configs/mips-softmmu-common.mak index fae2347ee7e..479fb4d900d 100644 --- a/default-configs/mips-softmmu-common.mak +++ b/default-configs/mips-softmmu-common.mak @@ -36,3 +36,6 @@ CONFIG_EMPTY_SLOT=y CONFIG_MIPS_CPS=y CONFIG_MIPS_ITU=y CONFIG_I2C=y +CONFIG_R4K=y +CONFIG_MALTA=y +CONFIG_MIPSSIM=y diff --git a/hw/mips/Makefile.objs b/hw/mips/Makefile.objs index 17a311aaba3..525809af07a 100644 --- a/hw/mips/Makefile.objs +++ b/hw/mips/Makefile.objs @@ -1,7 +1,8 @@ -obj-y += mips_r4k.o mips_malta.o mips_mipssim.o obj-y += addr.o mips_int.o +obj-$(CONFIG_R4K) += mips_r4k.o +obj-$(CONFIG_MALTA) += gt64xxx_pci.o mips_malta.o +obj-$(CONFIG_MIPSSIM) += mips_mipssim.o obj-$(CONFIG_JAZZ) += mips_jazz.o obj-$(CONFIG_FULONG) += mips_fulong2e.o -obj-y += gt64xxx_pci.o obj-$(CONFIG_MIPS_CPS) += cps.o obj-$(CONFIG_MIPS_BOSTON) += boston.o From ee279c460826a73b9867a48cd261a9d124ecad38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81kos=20Kov=C3=A1cs?= Date: Sat, 2 Feb 2019 15:24:40 +0800 Subject: [PATCH 55/76] hw/ppc/Makefile.objs: Build all boards conditinally with CONFIG_* MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CONFIG_PPC405, CONFIG_PPC440, CONFIG_MAC_OLDWORLD, CONFIG_MAX_NEWWORLD and CONFIG_VIRTEX configuration options created for default-configs/ppc*-softmmu.mak. Signed-off-by: Ákos Kovács Signed-off-by: Paolo Bonzini Signed-off-by: Yang Zhong Reviewed-by: Thomas Huth Message-Id: <20190202072456.6468-12-yang.zhong@intel.com> Signed-off-by: Paolo Bonzini --- default-configs/ppc-softmmu.mak | 7 ++++++- hw/ppc/Makefile.objs | 11 ++++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/default-configs/ppc-softmmu.mak b/default-configs/ppc-softmmu.mak index 23d871fb3e1..7f80f0ccbad 100644 --- a/default-configs/ppc-softmmu.mak +++ b/default-configs/ppc-softmmu.mak @@ -21,6 +21,10 @@ CONFIG_E500=y CONFIG_OPENPIC_KVM=$(call land,$(CONFIG_E500),$(CONFIG_KVM)) CONFIG_PLATFORM_BUS=y CONFIG_ETSEC=y +CONFIG_PPC405=y +CONFIG_PPC440=y +CONFIG_VIRTEX=y + # For Sam460ex CONFIG_SAM460EX=y CONFIG_USB_EHCI_SYSBUS=y @@ -34,7 +38,6 @@ CONFIG_M41T80=y CONFIG_VGA_CIRRUS=y # For Macs -CONFIG_MAC=y CONFIG_ESCC=y CONFIG_MACIO=y CONFIG_MACIO_GPIO=y @@ -50,6 +53,8 @@ CONFIG_GRACKLE_PCI=y CONFIG_UNIN_PCI=y CONFIG_DEC_PCI=y CONFIG_IDE_MACIO=y +CONFIG_MAC_OLDWORLD=y +CONFIG_MAC_NEWWORLD=y # For PReP CONFIG_PREP=y diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs index 1e753de09b8..1111b218a04 100644 --- a/hw/ppc/Makefile.objs +++ b/hw/ppc/Makefile.objs @@ -13,19 +13,20 @@ obj-y += spapr_pci_vfio.o endif obj-$(CONFIG_PSERIES) += spapr_rtas_ddw.o # PowerPC 4xx boards -obj-$(CONFIG_PPC4XX) += ppc4xx_devs.o ppc4xx_pci.o ppc405_uc.o ppc405_boards.o -obj-$(CONFIG_PPC4XX) += ppc440_bamboo.o ppc440_pcix.o ppc440_uc.o +obj-$(CONFIG_PPC405) += ppc405_boards.o ppc405_uc.o +obj-$(CONFIG_PPC440) += ppc440_bamboo.o ppc440_pcix.o ppc440_uc.o +obj-$(CONFIG_PPC4XX) += ppc4xx_pci.o ppc4xx_devs.o obj-$(CONFIG_SAM460EX) += sam460ex.o # PReP obj-$(CONFIG_PREP) += prep.o obj-$(CONFIG_PREP) += prep_systemio.o obj-${CONFIG_RS6000_MC} += rs6000_mc.o # OldWorld PowerMac -obj-$(CONFIG_MAC) += mac_oldworld.o +obj-$(CONFIG_MAC_OLDWORLD) += mac_oldworld.o # NewWorld PowerMac -obj-$(CONFIG_MAC) += mac_newworld.o +obj-$(CONFIG_MAC_NEWWORLD) += mac_newworld.o # e500 obj-$(CONFIG_E500) += e500.o mpc8544ds.o e500plat.o obj-$(CONFIG_E500) += mpc8544_guts.o ppce500_spin.o # PowerPC 440 Xilinx ML507 reference board. -obj-$(CONFIG_XILINX) += virtex_ml507.o +obj-$(CONFIG_VIRTEX) += virtex_ml507.o From 774afd9f50b579cfae68c33358b49a6d3f9f0cc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81kos=20Kov=C3=A1cs?= Date: Sat, 2 Feb 2019 15:24:41 +0800 Subject: [PATCH 56/76] hw/sh4/Makefile.objs: New CONFIG_* varibales created for sh4 boards and device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make hw/sh4 configurable and add new CONFIG_* to the default-configs/sh4*-softmmu.mak. Signed-off-by: Ákos Kovács Signed-off-by: Paolo Bonzini Reviewed-by: Thomas Huth Message-Id: <20190202072456.6468-13-yang.zhong@intel.com> Signed-off-by: Paolo Bonzini --- default-configs/sh4-softmmu.mak | 2 ++ default-configs/sh4eb-softmmu.mak | 2 ++ hw/sh4/Makefile.objs | 4 ++-- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/default-configs/sh4-softmmu.mak b/default-configs/sh4-softmmu.mak index caeccd55be7..1fdb009151a 100644 --- a/default-configs/sh4-softmmu.mak +++ b/default-configs/sh4-softmmu.mak @@ -19,3 +19,5 @@ CONFIG_PCSPK=y CONFIG_I82374=y CONFIG_I8257=y CONFIG_MC146818RTC=y +CONFIG_R2D=y +CONFIG_SHIX=y diff --git a/default-configs/sh4eb-softmmu.mak b/default-configs/sh4eb-softmmu.mak index 53b9cd7b5a2..3b550a5fe89 100644 --- a/default-configs/sh4eb-softmmu.mak +++ b/default-configs/sh4eb-softmmu.mak @@ -19,3 +19,5 @@ CONFIG_PCSPK=y CONFIG_I82374=y CONFIG_I8257=y CONFIG_MC146818RTC=y +CONFIG_R2D=y +CONFIG_SHIX=y diff --git a/hw/sh4/Makefile.objs b/hw/sh4/Makefile.objs index 2393702c576..2a707f9473c 100644 --- a/hw/sh4/Makefile.objs +++ b/hw/sh4/Makefile.objs @@ -1,4 +1,4 @@ -obj-y += shix.o r2d.o - obj-y += sh7750.o sh7750_regnames.o obj-y += sh_pci.o +obj-$(CONFIG_R2D) += r2d.o +obj-$(CONFIG_SHIX) += shix.o From bc0c93eab287b3e22e20c730418f4312ec0527f9 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Sat, 2 Feb 2019 15:24:42 +0800 Subject: [PATCH 57/76] hw/s390/Makefile.objs: Create new CONFIG_* variables for s390x boards and devices Make hw/s390x configurable and add new CONFIG_* to the default-configs/s390x*-softmmu.mak. This will be used to enable/disable vfio-ccw. Signed-off-by: Paolo Bonzini Reviewed-by: Thomas Huth Message-Id: <20190202072456.6468-14-yang.zhong@intel.com> Signed-off-by: Paolo Bonzini --- default-configs/s390x-softmmu.mak | 1 + hw/s390x/Makefile.objs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/default-configs/s390x-softmmu.mak b/default-configs/s390x-softmmu.mak index 5eef3759245..8bb7e438c87 100644 --- a/default-configs/s390x-softmmu.mak +++ b/default-configs/s390x-softmmu.mak @@ -8,3 +8,4 @@ CONFIG_S390_FLIC_KVM=$(CONFIG_KVM) CONFIG_VFIO_CCW=$(CONFIG_LINUX) CONFIG_WDT_DIAG288=y CONFIG_VFIO_AP=$(CONFIG_LINUX) +CONFIG_S390_CCW_VIRTIO=y diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs index ca68806e441..a18c4719137 100644 --- a/hw/s390x/Makefile.objs +++ b/hw/s390x/Makefile.objs @@ -5,7 +5,7 @@ obj-y += sclpquiesce.o obj-y += sclpcpu.o obj-y += ipl.o obj-y += css.o -obj-y += s390-virtio-ccw.o +obj-$(CONFIG_S390_CCW_VIRTIO) += s390-virtio-ccw.o obj-y += 3270-ccw.o obj-y += virtio-ccw.o obj-$(CONFIG_VIRTIO_SERIAL) += virtio-ccw-serial.o From f96c37821f7dc6c23b7d7b02ca7c753a42cfa976 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81kos=20Kov=C3=A1cs?= Date: Sat, 2 Feb 2019 15:24:43 +0800 Subject: [PATCH 58/76] hw/sparc/Makefile.objs: CONFIG_* for sun4m and leon3 created MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CONFIG_LEON3 added to default-configs/sparc-softmmu.mak. Signed-off-by: Ákos Kovács Signed-off-by: Paolo Bonzini Reviewed-by: Thomas Huth Message-Id: <20190202072456.6468-15-yang.zhong@intel.com> Signed-off-by: Paolo Bonzini --- default-configs/sparc-softmmu.mak | 2 ++ hw/sparc/Makefile.objs | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/default-configs/sparc-softmmu.mak b/default-configs/sparc-softmmu.mak index 12f97eeb200..59a4a3d693a 100644 --- a/default-configs/sparc-softmmu.mak +++ b/default-configs/sparc-softmmu.mak @@ -18,4 +18,6 @@ CONFIG_CS4231=y CONFIG_GRLIB=y CONFIG_STP2000=y CONFIG_ECCMEMCTL=y + CONFIG_SUN4M=y +CONFIG_LEON3=y diff --git a/hw/sparc/Makefile.objs b/hw/sparc/Makefile.objs index e2d0828c392..d57e33f83ea 100644 --- a/hw/sparc/Makefile.objs +++ b/hw/sparc/Makefile.objs @@ -1 +1,3 @@ -obj-y += sun4m_iommu.o sun4m.o leon3.o +obj-$(CONFIG_SUN4M) += sun4m_iommu.o +obj-$(CONFIG_SUN4M) += sun4m.o +obj-$(CONFIG_LEON3) += leon3.o From 27f3ac3fa64f463cb7cd83519bb89388e049dec7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81kos=20Kov=C3=A1cs?= Date: Sat, 2 Feb 2019 15:24:44 +0800 Subject: [PATCH 59/76] hw/lm32/Makefile.objs: Conditionally build lm32 and milkmyst MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CONFIG_LM32 and CONFIG_MILKYMIST added for lm32 and milkmyst build. Signed-off-by: Ákos Kovács Signed-off-by: Paolo Bonzini Reviewed-by: Thomas Huth Message-Id: <20190202072456.6468-16-yang.zhong@intel.com> Signed-off-by: Paolo Bonzini --- hw/lm32/Makefile.objs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/lm32/Makefile.objs b/hw/lm32/Makefile.objs index ea6418ae595..c3941866c74 100644 --- a/hw/lm32/Makefile.objs +++ b/hw/lm32/Makefile.objs @@ -1,3 +1,3 @@ # LM32 boards -obj-y += lm32_boards.o -obj-y += milkymist.o +obj-$(CONFIG_LM32) += lm32_boards.o +obj-$(CONFIG_MILKYMIST) += milkymist.o From d84929da9af089f1f50115c07099e3b7a1c2f8d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81kos=20Kov=C3=A1cs?= Date: Sat, 2 Feb 2019 15:24:45 +0800 Subject: [PATCH 60/76] hw/xtensa/Makefile.objs: Build xtensa_sim and xtensa_fpga conditionally MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the new CONFIG_* values to default-config/xtensa*-softmmu.mak. Signed-off-by: Ákos Kovács Signed-off-by: Paolo Bonzini Reviewed-by: Thomas Huth Acked-by: Max Filippov Message-Id: <20190202072456.6468-17-yang.zhong@intel.com> Signed-off-by: Paolo Bonzini --- default-configs/xtensa-softmmu.mak | 3 +++ default-configs/xtensaeb-softmmu.mak | 3 +++ hw/xtensa/Makefile.objs | 4 ++-- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/default-configs/xtensa-softmmu.mak b/default-configs/xtensa-softmmu.mak index 9d8899cde7c..baf90ca1624 100644 --- a/default-configs/xtensa-softmmu.mak +++ b/default-configs/xtensa-softmmu.mak @@ -3,3 +3,6 @@ CONFIG_SERIAL=y CONFIG_OPENCORES_ETH=y CONFIG_PFLASH_CFI01=y + +CONFIG_XTENSA_SIM=y +CONFIG_XTENSA_FPGA=y diff --git a/default-configs/xtensaeb-softmmu.mak b/default-configs/xtensaeb-softmmu.mak index 9d8899cde7c..baf90ca1624 100644 --- a/default-configs/xtensaeb-softmmu.mak +++ b/default-configs/xtensaeb-softmmu.mak @@ -3,3 +3,6 @@ CONFIG_SERIAL=y CONFIG_OPENCORES_ETH=y CONFIG_PFLASH_CFI01=y + +CONFIG_XTENSA_SIM=y +CONFIG_XTENSA_FPGA=y diff --git a/hw/xtensa/Makefile.objs b/hw/xtensa/Makefile.objs index f30e4a7e076..fa86730e23f 100644 --- a/hw/xtensa/Makefile.objs +++ b/hw/xtensa/Makefile.objs @@ -1,5 +1,5 @@ obj-y += mx_pic.o obj-y += pic_cpu.o -obj-y += sim.o obj-y += xtensa_memory.o -obj-y += xtfpga.o +obj-$(CONFIG_XTENSA_SIM) += sim.o +obj-$(CONFIG_XTENSA_FPGA) += xtfpga.o From fa83f64855ad4c3b829e3fa2b683fd30c42db4c4 Mon Sep 17 00:00:00 2001 From: Yang Zhong Date: Sat, 2 Feb 2019 15:24:46 +0800 Subject: [PATCH 61/76] hw/nios2/Makefile.objs: Conditionally build nios2 CONFIG_NIOS2_10M50 added for 10m50 dev board. Signed-off-by: Yang Zhong Signed-off-by: Paolo Bonzini Reviewed-by: Thomas Huth Message-Id: <20190202072456.6468-18-yang.zhong@intel.com> Signed-off-by: Paolo Bonzini --- default-configs/nios2-softmmu.mak | 1 + hw/nios2/Makefile.objs | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/default-configs/nios2-softmmu.mak b/default-configs/nios2-softmmu.mak index 74dc70caaef..ab42d0fc280 100644 --- a/default-configs/nios2-softmmu.mak +++ b/default-configs/nios2-softmmu.mak @@ -4,3 +4,4 @@ CONFIG_NIOS2=y CONFIG_SERIAL=y CONFIG_PTIMER=y CONFIG_ALTERA_TIMER=y +CONFIG_NIOS2_10M50=y diff --git a/hw/nios2/Makefile.objs b/hw/nios2/Makefile.objs index 6b5c4217604..89a419a9f59 100644 --- a/hw/nios2/Makefile.objs +++ b/hw/nios2/Makefile.objs @@ -1 +1,2 @@ -obj-y = boot.o cpu_pic.o 10m50_devboard.o +obj-y = boot.o cpu_pic.o +obj-$(CONFIG_NIOS2_10M50) += 10m50_devboard.o From 3fa86eb366b3996286d8766fba401dade1db031a Mon Sep 17 00:00:00 2001 From: Yang Zhong Date: Sat, 2 Feb 2019 15:24:47 +0800 Subject: [PATCH 62/76] hw/riscv/Makefile.objs: Create CONFIG_* for riscv boards Add the new configs to default-configs/riscv*-sofmmu.mak. Signed-off-by: Yang Zhong Signed-off-by: Paolo Bonzini Reviewed-by: Alistair Francis Reviewed-by: Thomas Huth Message-Id: <20190202072456.6468-19-yang.zhong@intel.com> Signed-off-by: Paolo Bonzini --- default-configs/riscv32-softmmu.mak | 7 +++++++ default-configs/riscv64-softmmu.mak | 7 +++++++ hw/riscv/Makefile.objs | 22 +++++++++++----------- 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/default-configs/riscv32-softmmu.mak b/default-configs/riscv32-softmmu.mak index fbfd1d4e4b5..65337166e19 100644 --- a/default-configs/riscv32-softmmu.mak +++ b/default-configs/riscv32-softmmu.mak @@ -12,3 +12,10 @@ CONFIG_PCI_EXPRESS_GENERIC_BRIDGE=y CONFIG_VGA=y CONFIG_VGA_PCI=y + +CONFIG_SPIKE=y +CONFIG_HART=y +CONFIG_SIFIVE_E=y +CONFIG_SIFIVE=y +CONFIG_SIFIVE_U=y +CONFIG_RISCV_VIRT=y diff --git a/default-configs/riscv64-softmmu.mak b/default-configs/riscv64-softmmu.mak index fbfd1d4e4b5..65337166e19 100644 --- a/default-configs/riscv64-softmmu.mak +++ b/default-configs/riscv64-softmmu.mak @@ -12,3 +12,10 @@ CONFIG_PCI_EXPRESS_GENERIC_BRIDGE=y CONFIG_VGA=y CONFIG_VGA_PCI=y + +CONFIG_SPIKE=y +CONFIG_HART=y +CONFIG_SIFIVE_E=y +CONFIG_SIFIVE=y +CONFIG_SIFIVE_U=y +CONFIG_RISCV_VIRT=y diff --git a/hw/riscv/Makefile.objs b/hw/riscv/Makefile.objs index 1dde01d39dc..79bfb3abf90 100644 --- a/hw/riscv/Makefile.objs +++ b/hw/riscv/Makefile.objs @@ -1,11 +1,11 @@ -obj-y += riscv_htif.o -obj-y += riscv_hart.o -obj-y += sifive_e.o -obj-y += sifive_clint.o -obj-y += sifive_prci.o -obj-y += sifive_plic.o -obj-y += sifive_test.o -obj-y += sifive_u.o -obj-y += sifive_uart.o -obj-y += spike.o -obj-y += virt.o +obj-$(CONFIG_SPIKE) += riscv_htif.o +obj-$(CONFIG_HART) += riscv_hart.o +obj-$(CONFIG_SIFIVE_E) += sifive_e.o +obj-$(CONFIG_SIFIVE) += sifive_clint.o +obj-$(CONFIG_SIFIVE) += sifive_prci.o +obj-$(CONFIG_SIFIVE) += sifive_plic.o +obj-$(CONFIG_SIFIVE) += sifive_test.o +obj-$(CONFIG_SIFIVE_U) += sifive_u.o +obj-$(CONFIG_SIFIVE) += sifive_uart.o +obj-$(CONFIG_SPIKE) += spike.o +obj-$(CONFIG_RISCV_VIRT) += virt.o From 04aa5abc6adcbd02b1eecdc27018c05e1812d0f1 Mon Sep 17 00:00:00 2001 From: Yang Zhong Date: Sat, 2 Feb 2019 15:24:48 +0800 Subject: [PATCH 63/76] hw/sparc64/Makefile.objs: Create CONFIG_* for sparc64 Add the new configs to default-configs/sparc64-sofmmu.mak. Signed-off-by: Yang Zhong Signed-off-by: Paolo Bonzini Reviewed-by: Thomas Huth Message-Id: <20190202072456.6468-20-yang.zhong@intel.com> Signed-off-by: Paolo Bonzini --- default-configs/sparc64-softmmu.mak | 2 ++ hw/sparc64/Makefile.objs | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/default-configs/sparc64-softmmu.mak b/default-configs/sparc64-softmmu.mak index ce63d470460..1fae4888dbe 100644 --- a/default-configs/sparc64-softmmu.mak +++ b/default-configs/sparc64-softmmu.mak @@ -17,3 +17,5 @@ CONFIG_SUNHME=y CONFIG_MC146818RTC=y CONFIG_ISA_TESTDEV=y CONFIG_SUN4V_RTC=y +CONFIG_SUN4U=y +CONFIG_NIAGARA=y diff --git a/hw/sparc64/Makefile.objs b/hw/sparc64/Makefile.objs index 117e0ff27d7..af0525c1a2b 100644 --- a/hw/sparc64/Makefile.objs +++ b/hw/sparc64/Makefile.objs @@ -1,4 +1,4 @@ obj-y += sparc64.o -obj-y += sun4u_iommu.o -obj-y += sun4u.o -obj-y += niagara.o \ No newline at end of file +obj-$(CONFIG_SUN4U) += sun4u_iommu.o +obj-$(CONFIG_SUN4U) += sun4u.o +obj-$(CONFIG_NIAGARA) += niagara.o From 31be0a43b997c552376ab7639f3e0e7acef84984 Mon Sep 17 00:00:00 2001 From: Yang Zhong Date: Sat, 2 Feb 2019 15:24:49 +0800 Subject: [PATCH 64/76] hw/alpha/Makefile.objs: Create CONFIG_* for alpha Add the new configs to default-configs/alpha-sofmmu.mak. Signed-off-by: Yang Zhong Signed-off-by: Paolo Bonzini Reviewed-by: Thomas Huth Reviewed-by: Richard Henderson Message-Id: <20190202072456.6468-21-yang.zhong@intel.com> Signed-off-by: Paolo Bonzini --- default-configs/alpha-softmmu.mak | 1 + hw/alpha/Makefile.objs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/default-configs/alpha-softmmu.mak b/default-configs/alpha-softmmu.mak index 4d654eaa0b6..49cb7ce3511 100644 --- a/default-configs/alpha-softmmu.mak +++ b/default-configs/alpha-softmmu.mak @@ -19,3 +19,4 @@ CONFIG_I8259=y CONFIG_MC146818RTC=y CONFIG_ISA_TESTDEV=y CONFIG_SMC37C669=y +CONFIG_DP264=y diff --git a/hw/alpha/Makefile.objs b/hw/alpha/Makefile.objs index 5c742756f01..62fdf3edec9 100644 --- a/hw/alpha/Makefile.objs +++ b/hw/alpha/Makefile.objs @@ -1 +1 @@ -obj-y += dp264.o pci.o typhoon.o +obj-$(CONFIG_DP264) += dp264.o pci.o typhoon.o From 034c344e30137427c9a61fe57b3163ca50ade441 Mon Sep 17 00:00:00 2001 From: Yang Zhong Date: Sat, 2 Feb 2019 15:24:50 +0800 Subject: [PATCH 65/76] hw/cris/Makefile.objs: Create CONFIG_* for cris Add the new configs to default-configs/cris-sofmmu.mak. Signed-off-by: Yang Zhong Signed-off-by: Paolo Bonzini Reviewed-by: Thomas Huth Message-Id: <20190202072456.6468-22-yang.zhong@intel.com> Signed-off-by: Paolo Bonzini --- default-configs/cris-softmmu.mak | 1 + hw/cris/Makefile.objs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/default-configs/cris-softmmu.mak b/default-configs/cris-softmmu.mak index d970d50158b..a637c4b4bf7 100644 --- a/default-configs/cris-softmmu.mak +++ b/default-configs/cris-softmmu.mak @@ -4,3 +4,4 @@ CONFIG_ETRAXFS=y CONFIG_NAND=y CONFIG_PTIMER=y CONFIG_PFLASH_CFI02=y +CONFIG_AXIS=y diff --git a/hw/cris/Makefile.objs b/hw/cris/Makefile.objs index 7624173f779..a4a27b3a138 100644 --- a/hw/cris/Makefile.objs +++ b/hw/cris/Makefile.objs @@ -1,2 +1,2 @@ obj-y += boot.o -obj-y += axis_dev88.o +obj-$(CONFIG_AXIS) += axis_dev88.o From 714e74621e605486e9854650fed524f1c63f3ec2 Mon Sep 17 00:00:00 2001 From: Yang Zhong Date: Sat, 2 Feb 2019 15:24:51 +0800 Subject: [PATCH 66/76] hw/hppa/Makefile.objs: Create CONFIG_* for hppa Add the new configs to default-configs/hppa-sofmmu.mak. Signed-off-by: Yang Zhong Signed-off-by: Paolo Bonzini Reviewed-by: Richard Henderson Message-Id: <20190202072456.6468-23-yang.zhong@intel.com> Signed-off-by: Paolo Bonzini --- default-configs/hppa-softmmu.mak | 1 + hw/hppa/Makefile.objs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/default-configs/hppa-softmmu.mak b/default-configs/hppa-softmmu.mak index 4badc0521ef..b594a6ddd94 100644 --- a/default-configs/hppa-softmmu.mak +++ b/default-configs/hppa-softmmu.mak @@ -10,3 +10,4 @@ CONFIG_IDE_CMD646=y # CONFIG_IDE_MMIO=y CONFIG_VIRTIO_VGA=y CONFIG_MC146818RTC=y +CONFIG_DINO=y diff --git a/hw/hppa/Makefile.objs b/hw/hppa/Makefile.objs index bef241ed255..67838f50a32 100644 --- a/hw/hppa/Makefile.objs +++ b/hw/hppa/Makefile.objs @@ -1 +1 @@ -obj-y += machine.o pci.o dino.o +obj-$(CONFIG_DINO) += pci.o machine.o dino.o From f0975e8f2098f04a6b3e7480a8d2dc072bb01bf9 Mon Sep 17 00:00:00 2001 From: Yang Zhong Date: Sat, 2 Feb 2019 15:24:52 +0800 Subject: [PATCH 67/76] hw/moxie/Makefile.objs: Conditionally build moxie CONFIG_MOXIE added for moxiesim board. Signed-off-by: Yang Zhong Signed-off-by: Paolo Bonzini Reviewed-by: Thomas Huth Message-Id: <20190202072456.6468-24-yang.zhong@intel.com> Signed-off-by: Paolo Bonzini --- default-configs/moxie-softmmu.mak | 1 + hw/moxie/Makefile.objs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/default-configs/moxie-softmmu.mak b/default-configs/moxie-softmmu.mak index e00d099994c..17ba906dc2f 100644 --- a/default-configs/moxie-softmmu.mak +++ b/default-configs/moxie-softmmu.mak @@ -5,3 +5,4 @@ CONFIG_MC146818RTC=y CONFIG_SERIAL=y CONFIG_SERIAL_ISA=y CONFIG_VGA=y +CONFIG_MOXIESIM=y diff --git a/hw/moxie/Makefile.objs b/hw/moxie/Makefile.objs index bfc90012fd0..ddbf300f548 100644 --- a/hw/moxie/Makefile.objs +++ b/hw/moxie/Makefile.objs @@ -1,2 +1,2 @@ # moxie boards -obj-y += moxiesim.o +obj-$(CONFIG_MOXIESIM) += moxiesim.o From 4575bbb4c88b5187259d4a7c14c154b0fb80e6be Mon Sep 17 00:00:00 2001 From: Yang Zhong Date: Sat, 2 Feb 2019 15:24:53 +0800 Subject: [PATCH 68/76] hw/openrisc/Makefile.objs: Create CONFIG_* for openrisc Add the new configs to default-configs/or1k-sofmmu.mak. Signed-off-by: Yang Zhong Signed-off-by: Paolo Bonzini Reviewed-by: Thomas Huth Message-Id: <20190202072456.6468-25-yang.zhong@intel.com> Signed-off-by: Paolo Bonzini --- default-configs/or1k-softmmu.mak | 1 + hw/openrisc/Makefile.objs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/default-configs/or1k-softmmu.mak b/default-configs/or1k-softmmu.mak index 6f5824fd488..6a0f2ef6cf6 100644 --- a/default-configs/or1k-softmmu.mak +++ b/default-configs/or1k-softmmu.mak @@ -3,3 +3,4 @@ CONFIG_SERIAL=y CONFIG_OPENCORES_ETH=y CONFIG_OMPIC=y +CONFIG_OR1K_SIM=y diff --git a/hw/openrisc/Makefile.objs b/hw/openrisc/Makefile.objs index 61246b149b7..aa04de7f5a6 100644 --- a/hw/openrisc/Makefile.objs +++ b/hw/openrisc/Makefile.objs @@ -1,2 +1,2 @@ obj-y = pic_cpu.o cputimer.o -obj-y += openrisc_sim.o +obj-$(CONFIG_OR1K_SIM) += openrisc_sim.o From 85e4dcf18d92a43cc260de4331714c8e38d0c79d Mon Sep 17 00:00:00 2001 From: Yang Zhong Date: Sat, 2 Feb 2019 15:24:54 +0800 Subject: [PATCH 69/76] hw/tricore/Makefile.objs: Create CONFIG_* for tricore Add the new configs to default-configs/tricore-sofmmu.mak. Signed-off-by: Yang Zhong Signed-off-by: Paolo Bonzini Reviewed-by: Thomas Huth Message-Id: <20190202072456.6468-26-yang.zhong@intel.com> Signed-off-by: Paolo Bonzini --- default-configs/tricore-softmmu.mak | 1 + hw/tricore/Makefile.objs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/default-configs/tricore-softmmu.mak b/default-configs/tricore-softmmu.mak index e69de29bb2d..c397cff38a2 100644 --- a/default-configs/tricore-softmmu.mak +++ b/default-configs/tricore-softmmu.mak @@ -0,0 +1 @@ +CONFIG_TRICORE=y diff --git a/hw/tricore/Makefile.objs b/hw/tricore/Makefile.objs index 435e095cffb..5501f6c1a88 100644 --- a/hw/tricore/Makefile.objs +++ b/hw/tricore/Makefile.objs @@ -1 +1 @@ -obj-y += tricore_testboard.o +obj-$(CONFIG_TRICORE) += tricore_testboard.o From 8e6578831beb3a3b5df5bc240f221efe2409206b Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Sat, 2 Feb 2019 15:24:55 +0800 Subject: [PATCH 70/76] hw/i2c/Makefile.objs: Create new CONFIG_* variables for EEPROM and ACPI controller Create separate variables for these components, they are used in many boards but not all. This allows finer-grain selection of the included code with default-configs/*.mak. Signed-off-by: Paolo Bonzini Reviewed-by: Thomas Huth Message-Id: <20190202072456.6468-27-yang.zhong@intel.com> Signed-off-by: Paolo Bonzini --- default-configs/arm-softmmu.mak | 1 + default-configs/i386-softmmu.mak | 2 ++ default-configs/mips-softmmu-common.mak | 2 ++ default-configs/ppc-softmmu.mak | 1 + hw/i2c/Makefile.objs | 5 +++-- 5 files changed, 9 insertions(+), 2 deletions(-) diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak index 1db36396b1a..d700d093f3c 100644 --- a/default-configs/arm-softmmu.mak +++ b/default-configs/arm-softmmu.mak @@ -151,6 +151,7 @@ CONFIG_ACPI=y CONFIG_ARM_VIRT=y CONFIG_SMBIOS=y CONFIG_ASPEED_SOC=y +CONFIG_SMBUS_EEPROM=y CONFIG_GPIO_KEY=y CONFIG_MSF2=y CONFIG_FW_CFG_DMA=y diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak index 71c9f6fbcba..15b628757ba 100644 --- a/default-configs/i386-softmmu.mak +++ b/default-configs/i386-softmmu.mak @@ -62,6 +62,8 @@ CONFIG_I82801B11=y CONFIG_SMBIOS=y CONFIG_PXB=y CONFIG_ACPI_VMGENID=y +CONFIG_ACPI_SMBUS=y +CONFIG_SMBUS_EEPROM=y CONFIG_FW_CFG_DMA=y CONFIG_I2C=y CONFIG_SEV=$(CONFIG_KVM) diff --git a/default-configs/mips-softmmu-common.mak b/default-configs/mips-softmmu-common.mak index 479fb4d900d..ded74980e1b 100644 --- a/default-configs/mips-softmmu-common.mak +++ b/default-configs/mips-softmmu-common.mak @@ -39,3 +39,5 @@ CONFIG_I2C=y CONFIG_R4K=y CONFIG_MALTA=y CONFIG_MIPSSIM=y +CONFIG_ACPI_SMBUS=y +CONFIG_SMBUS_EEPROM=y diff --git a/default-configs/ppc-softmmu.mak b/default-configs/ppc-softmmu.mak index 7f80f0ccbad..52acb7cf39e 100644 --- a/default-configs/ppc-softmmu.mak +++ b/default-configs/ppc-softmmu.mak @@ -36,6 +36,7 @@ CONFIG_AT24C=y CONFIG_BITBANG_I2C=y CONFIG_M41T80=y CONFIG_VGA_CIRRUS=y +CONFIG_SMBUS_EEPROM=y # For Macs CONFIG_ESCC=y diff --git a/hw/i2c/Makefile.objs b/hw/i2c/Makefile.objs index 82e747e1cd1..cecee486f7b 100644 --- a/hw/i2c/Makefile.objs +++ b/hw/i2c/Makefile.objs @@ -1,8 +1,9 @@ -common-obj-$(CONFIG_I2C) += core.o smbus.o smbus_eeprom.o +common-obj-$(CONFIG_I2C) += core.o smbus.o +common-obj-$(CONFIG_SMBUS_EEPROM) += smbus_eeprom.o common-obj-$(CONFIG_DDC) += i2c-ddc.o common-obj-$(CONFIG_VERSATILE_I2C) += versatile_i2c.o common-obj-$(CONFIG_ACPI_X86) += smbus_ich9.o -common-obj-$(CONFIG_APM) += pm_smbus.o +common-obj-$(CONFIG_ACPI_SMBUS) += pm_smbus.o common-obj-$(CONFIG_BITBANG_I2C) += bitbang_i2c.o common-obj-$(CONFIG_EXYNOS4) += exynos4210_i2c.o common-obj-$(CONFIG_IMX_I2C) += imx_i2c.o From f5ce0a5f5a8d2f8c64001b87e9c27f897b00c58c Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Sat, 2 Feb 2019 15:24:56 +0800 Subject: [PATCH 71/76] hw/vfio/Makefile.objs: Create new CONFIG_* variables for VFIO core and PCI Make hw/vfio configurable and add new CONFIG_VFIO_* to the default-configs/s390x*-softmmu.mak. This allow a finer-grain selection of the various VFIO backends. Signed-off-by: Paolo Bonzini Reviewed-by: Thomas Huth Message-Id: <20190202072456.6468-28-yang.zhong@intel.com> Signed-off-by: Paolo Bonzini --- default-configs/arm-softmmu.mak | 2 ++ default-configs/pci.mak | 2 ++ default-configs/s390x-softmmu.mak | 5 +++-- hw/Makefile.objs | 2 +- hw/vfio/Makefile.objs | 7 +++---- 5 files changed, 11 insertions(+), 7 deletions(-) diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak index d700d093f3c..734ca721e9e 100644 --- a/default-configs/arm-softmmu.mak +++ b/default-configs/arm-softmmu.mak @@ -124,6 +124,8 @@ CONFIG_VERSATILE_PCI=y CONFIG_VERSATILE_I2C=y CONFIG_PCI_EXPRESS_GENERIC_BRIDGE=y +CONFIG_VFIO=$(CONFIG_LINUX) +CONFIG_VFIO_PLATFORM=y CONFIG_VFIO_XGMAC=y CONFIG_VFIO_AMD_XGBE=y diff --git a/default-configs/pci.mak b/default-configs/pci.mak index 83738cbb65e..037636fa336 100644 --- a/default-configs/pci.mak +++ b/default-configs/pci.mak @@ -47,3 +47,5 @@ CONFIG_VGA_PCI=y CONFIG_BOCHS_DISPLAY=y CONFIG_IVSHMEM_DEVICE=$(CONFIG_IVSHMEM) CONFIG_ROCKER=y +CONFIG_VFIO=$(CONFIG_LINUX) +CONFIG_VFIO_PCI=y diff --git a/default-configs/s390x-softmmu.mak b/default-configs/s390x-softmmu.mak index 8bb7e438c87..6f2c6cec18a 100644 --- a/default-configs/s390x-softmmu.mak +++ b/default-configs/s390x-softmmu.mak @@ -5,7 +5,8 @@ CONFIG_SCLPCONSOLE=y CONFIG_TERMINAL3270=y CONFIG_S390_FLIC=y CONFIG_S390_FLIC_KVM=$(CONFIG_KVM) -CONFIG_VFIO_CCW=$(CONFIG_LINUX) CONFIG_WDT_DIAG288=y -CONFIG_VFIO_AP=$(CONFIG_LINUX) CONFIG_S390_CCW_VIRTIO=y +CONFIG_VFIO=$(CONFIG_LINUX) +CONFIG_VFIO_CCW=y +CONFIG_VFIO_AP=y diff --git a/hw/Makefile.objs b/hw/Makefile.objs index 22dd2113636..e2fcd6aafc1 100644 --- a/hw/Makefile.objs +++ b/hw/Makefile.objs @@ -30,7 +30,7 @@ devices-dirs-$(CONFIG_SOFTMMU) += ssi/ devices-dirs-$(CONFIG_SOFTMMU) += timer/ devices-dirs-$(CONFIG_TPM) += tpm/ devices-dirs-$(CONFIG_SOFTMMU) += usb/ -devices-dirs-$(CONFIG_LINUX) += vfio/ +devices-dirs-$(CONFIG_VFIO) += vfio/ devices-dirs-$(CONFIG_SOFTMMU) += virtio/ devices-dirs-$(CONFIG_SOFTMMU) += watchdog/ devices-dirs-$(CONFIG_SOFTMMU) += xen/ diff --git a/hw/vfio/Makefile.objs b/hw/vfio/Makefile.objs index 91805893f73..abad8b818c9 100644 --- a/hw/vfio/Makefile.objs +++ b/hw/vfio/Makefile.objs @@ -1,8 +1,7 @@ -obj-$(CONFIG_SOFTMMU) += common.o -obj-$(CONFIG_PCI) += pci.o pci-quirks.o display.o +obj-y += common.o spapr.o +obj-$(CONFIG_VFIO_PCI) += pci.o pci-quirks.o display.o obj-$(CONFIG_VFIO_CCW) += ccw.o -obj-$(CONFIG_SOFTMMU) += platform.o +obj-$(CONFIG_VFIO_PLATFORM) += platform.o obj-$(CONFIG_VFIO_XGMAC) += calxeda-xgmac.o obj-$(CONFIG_VFIO_AMD_XGBE) += amd-xgbe.o -obj-$(CONFIG_SOFTMMU) += spapr.o obj-$(CONFIG_VFIO_AP) += ap.o From 26dc4a5bf96bb0ee19a0e446fead1546d5b07dac Mon Sep 17 00:00:00 2001 From: Heiher Date: Wed, 23 Jan 2019 15:34:02 +0800 Subject: [PATCH 72/76] i386: hvf: Fix smp boot hangs The machine that with hvf accelerator and smp sometimes boot hangs because all processors are executing instructions at startup, including early I/O emulations. We should just allow the bootstrap processor to initialize the machine and then to wake up slave processors by interrupt. Signed-off-by: Heiher Message-Id: <20190123073402.28465-1-r@hev.cc> Signed-off-by: Paolo Bonzini --- target/i386/hvf/hvf.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c index 689b585027f..42f94473033 100644 --- a/target/i386/hvf/hvf.c +++ b/target/i386/hvf/hvf.c @@ -499,7 +499,6 @@ void hvf_reset_vcpu(CPUState *cpu) { } hv_vm_sync_tsc(0); - cpu->halted = 0; hv_vcpu_invalidate_tlb(cpu->hvf_fd); hv_vcpu_flush(cpu->hvf_fd); } @@ -582,8 +581,6 @@ int hvf_init_vcpu(CPUState *cpu) wvmcs(cpu->hvf_fd, VMCS_TPR_THRESHOLD, 0); - hvf_reset_vcpu(cpu); - x86cpu = X86_CPU(cpu); x86cpu->env.xsave_buf = qemu_memalign(4096, 4096); @@ -659,8 +656,6 @@ int hvf_vcpu_exec(CPUState *cpu) int ret = 0; uint64_t rip = 0; - cpu->halted = 0; - if (hvf_process_events(cpu)) { return EXCP_HLT; } From 473ac56706e3408a5c10835c2c18ea22b96538e8 Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Wed, 12 Dec 2018 10:57:07 +0100 Subject: [PATCH 73/76] pc: Use hotplug_handler_(plug|unplug|unplug_request) Let's avoid manually looking up the hotplug handler class. Use the existing wrappers instead. Signed-off-by: David Hildenbrand Message-Id: <20181212095707.19358-1-david@redhat.com> Signed-off-by: Paolo Bonzini --- hw/i386/pc.c | 30 ++++++++---------------------- 1 file changed, 8 insertions(+), 22 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 7d8f351b1df..3889eccdc32 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -2122,7 +2122,6 @@ static void pc_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev, static void pc_memory_plug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { - HotplugHandlerClass *hhc; Error *local_err = NULL; PCMachineState *pcms = PC_MACHINE(hotplug_dev); bool is_nvdimm = object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM); @@ -2136,8 +2135,7 @@ static void pc_memory_plug(HotplugHandler *hotplug_dev, nvdimm_plug(&pcms->acpi_nvdimm_state); } - hhc = HOTPLUG_HANDLER_GET_CLASS(pcms->acpi_dev); - hhc->plug(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &error_abort); + hotplug_handler_plug(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &error_abort); out: error_propagate(errp, local_err); } @@ -2145,7 +2143,6 @@ static void pc_memory_plug(HotplugHandler *hotplug_dev, static void pc_memory_unplug_request(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { - HotplugHandlerClass *hhc; Error *local_err = NULL; PCMachineState *pcms = PC_MACHINE(hotplug_dev); @@ -2166,9 +2163,8 @@ static void pc_memory_unplug_request(HotplugHandler *hotplug_dev, goto out; } - hhc = HOTPLUG_HANDLER_GET_CLASS(pcms->acpi_dev); - hhc->unplug_request(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err); - + hotplug_handler_unplug_request(HOTPLUG_HANDLER(pcms->acpi_dev), dev, + &local_err); out: error_propagate(errp, local_err); } @@ -2177,12 +2173,9 @@ static void pc_memory_unplug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { PCMachineState *pcms = PC_MACHINE(hotplug_dev); - HotplugHandlerClass *hhc; Error *local_err = NULL; - hhc = HOTPLUG_HANDLER_GET_CLASS(pcms->acpi_dev); - hhc->unplug(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err); - + hotplug_handler_unplug(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err); if (local_err) { goto out; } @@ -2224,14 +2217,12 @@ static void pc_cpu_plug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { CPUArchId *found_cpu; - HotplugHandlerClass *hhc; Error *local_err = NULL; X86CPU *cpu = X86_CPU(dev); PCMachineState *pcms = PC_MACHINE(hotplug_dev); if (pcms->acpi_dev) { - hhc = HOTPLUG_HANDLER_GET_CLASS(pcms->acpi_dev); - hhc->plug(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err); + hotplug_handler_plug(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err); if (local_err) { goto out; } @@ -2255,7 +2246,6 @@ static void pc_cpu_unplug_request_cb(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { int idx = -1; - HotplugHandlerClass *hhc; Error *local_err = NULL; X86CPU *cpu = X86_CPU(dev); PCMachineState *pcms = PC_MACHINE(hotplug_dev); @@ -2272,9 +2262,8 @@ static void pc_cpu_unplug_request_cb(HotplugHandler *hotplug_dev, goto out; } - hhc = HOTPLUG_HANDLER_GET_CLASS(pcms->acpi_dev); - hhc->unplug_request(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err); - + hotplug_handler_unplug_request(HOTPLUG_HANDLER(pcms->acpi_dev), dev, + &local_err); if (local_err) { goto out; } @@ -2288,14 +2277,11 @@ static void pc_cpu_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { CPUArchId *found_cpu; - HotplugHandlerClass *hhc; Error *local_err = NULL; X86CPU *cpu = X86_CPU(dev); PCMachineState *pcms = PC_MACHINE(hotplug_dev); - hhc = HOTPLUG_HANDLER_GET_CLASS(pcms->acpi_dev); - hhc->unplug(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err); - + hotplug_handler_unplug(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err); if (local_err) { goto out; } From 59ee9500022cfdc79c2bcf51a82d02f5e4ec21d1 Mon Sep 17 00:00:00 2001 From: Laurent Vivier Date: Tue, 11 Dec 2018 17:31:04 +0100 Subject: [PATCH 74/76] scsi-disk: Convert from DPRINTF() macro to trace events MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Laurent Vivier Reviewed-by: Philippe Mathieu-Daudé Tested-by: Philippe Mathieu-Daudé Message-Id: <20181211163105.31834-2-lvivier@redhat.com> Signed-off-by: Paolo Bonzini --- hw/scsi/scsi-disk.c | 103 +++++++++++++++++++++---------------------- hw/scsi/trace-events | 29 ++++++++++++ 2 files changed, 79 insertions(+), 53 deletions(-) diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c index e6db6d7c151..d4e83aef0e1 100644 --- a/hw/scsi/scsi-disk.c +++ b/hw/scsi/scsi-disk.c @@ -19,15 +19,6 @@ * the host adapter emulator. */ -//#define DEBUG_SCSI - -#ifdef DEBUG_SCSI -#define DPRINTF(fmt, ...) \ -do { printf("scsi-disk: " fmt , ## __VA_ARGS__); } while (0) -#else -#define DPRINTF(fmt, ...) do {} while(0) -#endif - #include "qemu/osdep.h" #include "qemu/units.h" #include "qapi/error.h" @@ -41,6 +32,7 @@ do { printf("scsi-disk: " fmt , ## __VA_ARGS__); } while (0) #include "hw/block/block.h" #include "sysemu/dma.h" #include "qemu/cutils.h" +#include "trace.h" #ifdef __linux #include @@ -129,8 +121,8 @@ static void scsi_free_request(SCSIRequest *req) /* Helper function for command completion with sense. */ static void scsi_check_condition(SCSIDiskReq *r, SCSISense sense) { - DPRINTF("Command complete tag=0x%x sense=%d/%d/%d\n", - r->req.tag, sense.key, sense.asc, sense.ascq); + trace_scsi_disk_check_condition(r->req.tag, sense.key, sense.asc, + sense.ascq); scsi_req_build_sense(&r->req, sense); scsi_req_complete(&r->req, CHECK_CONDITION); } @@ -318,7 +310,7 @@ static void scsi_read_complete(void * opaque, int ret) } block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct); - DPRINTF("Data ready tag=0x%x len=%zd\n", r->req.tag, r->qiov.size); + trace_scsi_disk_read_complete(r->req.tag, r->qiov.size); n = r->qiov.size / 512; r->sector += n; @@ -389,7 +381,7 @@ static void scsi_read_data(SCSIRequest *req) SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); bool first; - DPRINTF("Read sector_count=%d\n", r->sector_count); + trace_scsi_disk_read_data_count(r->sector_count); if (r->sector_count == 0) { /* This also clears the sense buffer for REQUEST SENSE. */ scsi_req_complete(&r->req, GOOD); @@ -402,7 +394,7 @@ static void scsi_read_data(SCSIRequest *req) /* The request is used as the AIO opaque value, so add a ref. */ scsi_req_ref(&r->req); if (r->req.cmd.mode == SCSI_XFER_TO_DEV) { - DPRINTF("Data transfer direction invalid\n"); + trace_scsi_disk_read_data_invalid(); scsi_read_complete(r, -EINVAL); return; } @@ -503,7 +495,7 @@ static void scsi_write_complete_noio(SCSIDiskReq *r, int ret) return; } else { scsi_init_iovec(r, SCSI_DMA_BUF_SIZE); - DPRINTF("Write complete tag=0x%x more=%zd\n", r->req.tag, r->qiov.size); + trace_scsi_disk_write_complete_noio(r->req.tag, r->qiov.size); scsi_req_data(&r->req, r->qiov.size); } @@ -541,7 +533,7 @@ static void scsi_write_data(SCSIRequest *req) /* The request is used as the AIO opaque value, so add a ref. */ scsi_req_ref(&r->req); if (r->req.cmd.mode != SCSI_XFER_TO_DEV) { - DPRINTF("Data transfer direction invalid\n"); + trace_scsi_disk_write_data_invalid(); scsi_write_complete_noio(r, -EINVAL); return; } @@ -606,8 +598,7 @@ static int scsi_disk_emulate_vpd_page(SCSIRequest *req, uint8_t *outbuf) switch (page_code) { case 0x00: /* Supported page codes, mandatory */ { - DPRINTF("Inquiry EVPD[Supported pages] " - "buffer size %zd\n", req->cmd.xfer); + trace_scsi_disk_emulate_vpd_page_00(req->cmd.xfer); outbuf[buflen++] = 0x00; /* list of supported pages (this page) */ if (s->serial) { outbuf[buflen++] = 0x80; /* unit serial number */ @@ -625,7 +616,7 @@ static int scsi_disk_emulate_vpd_page(SCSIRequest *req, uint8_t *outbuf) int l; if (!s->serial) { - DPRINTF("Inquiry (EVPD[Serial number] not supported\n"); + trace_scsi_disk_emulate_vpd_page_80_not_supported(); return -1; } @@ -634,8 +625,7 @@ static int scsi_disk_emulate_vpd_page(SCSIRequest *req, uint8_t *outbuf) l = 36; } - DPRINTF("Inquiry EVPD[Serial number] " - "buffer size %zd\n", req->cmd.xfer); + trace_scsi_disk_emulate_vpd_page_80(req->cmd.xfer); memcpy(outbuf + buflen, s->serial, l); buflen += l; break; @@ -645,8 +635,7 @@ static int scsi_disk_emulate_vpd_page(SCSIRequest *req, uint8_t *outbuf) { int id_len = s->device_id ? MIN(strlen(s->device_id), 255 - 8) : 0; - DPRINTF("Inquiry EVPD[Device identification] " - "buffer size %zd\n", req->cmd.xfer); + trace_scsi_disk_emulate_vpd_page_83(req->cmd.xfer); if (id_len) { outbuf[buflen++] = 0x2; /* ASCII */ @@ -693,8 +682,7 @@ static int scsi_disk_emulate_vpd_page(SCSIRequest *req, uint8_t *outbuf) SCSIBlockLimits bl = {}; if (s->qdev.type == TYPE_ROM) { - DPRINTF("Inquiry (EVPD[%02X] not supported for CDROM\n", - page_code); + trace_scsi_disk_emulate_vpd_page_b0_not_supported(); return -1; } bl.wsnz = 1; @@ -1241,8 +1229,9 @@ static int scsi_disk_emulate_mode_sense(SCSIDiskReq *r, uint8_t *outbuf) dbd = (r->req.cmd.buf[1] & 0x8) != 0; page = r->req.cmd.buf[2] & 0x3f; page_control = (r->req.cmd.buf[2] & 0xc0) >> 6; - DPRINTF("Mode Sense(%d) (page %d, xfer %zd, page_control %d)\n", - (r->req.cmd.buf[0] == MODE_SENSE) ? 6 : 10, page, r->req.cmd.xfer, page_control); + + trace_scsi_disk_emulate_mode_sense((r->req.cmd.buf[0] == MODE_SENSE) ? 6 : + 10, page, r->req.cmd.xfer, page_control); memset(outbuf, 0, r->req.cmd.xfer); p = outbuf; @@ -1334,7 +1323,7 @@ static int scsi_disk_emulate_read_toc(SCSIRequest *req, uint8_t *outbuf) format = req->cmd.buf[2] & 0xf; start_track = req->cmd.buf[6]; blk_get_geometry(s->qdev.conf.blk, &nb_sectors); - DPRINTF("Read TOC (track %d format %d msf %d)\n", start_track, format, msf >> 1); + trace_scsi_disk_emulate_read_toc(start_track, format, msf >> 1); nb_sectors /= s->qdev.blocksize / 512; switch (format) { case 0: @@ -1393,7 +1382,7 @@ static void scsi_disk_emulate_read_data(SCSIRequest *req) int buflen = r->iov.iov_len; if (buflen) { - DPRINTF("Read buf_len=%d\n", buflen); + trace_scsi_disk_emulate_read_data(buflen); r->iov.iov_len = 0; r->started = true; scsi_req_data(&r->req, buflen); @@ -1812,7 +1801,7 @@ static void scsi_disk_emulate_write_data(SCSIRequest *req) if (r->iov.iov_len) { int buflen = r->iov.iov_len; - DPRINTF("Write buf_len=%d\n", buflen); + trace_scsi_disk_emulate_write_data(buflen); r->iov.iov_len = 0; scsi_req_data(&r->req, buflen); return; @@ -2021,7 +2010,7 @@ static int32_t scsi_disk_emulate_command(SCSIRequest *req, uint8_t *buf) case SERVICE_ACTION_IN_16: /* Service Action In subcommands. */ if ((req->cmd.buf[1] & 31) == SAI_READ_CAPACITY_16) { - DPRINTF("SAI READ CAPACITY(16)\n"); + trace_scsi_disk_emulate_command_SAI_16(); memset(outbuf, 0, req->cmd.xfer); blk_get_geometry(s->qdev.conf.blk, &nb_sectors); if (!nb_sectors) { @@ -2059,7 +2048,7 @@ static int32_t scsi_disk_emulate_command(SCSIRequest *req, uint8_t *buf) /* Protection, exponent and lowest lba field left blank. */ break; } - DPRINTF("Unsupported Service Action In\n"); + trace_scsi_disk_emulate_command_SAI_unsupported(); goto illegal_request; case SYNCHRONIZE_CACHE: /* The request is used as the AIO opaque value, so add a ref. */ @@ -2069,37 +2058,36 @@ static int32_t scsi_disk_emulate_command(SCSIRequest *req, uint8_t *buf) r->req.aiocb = blk_aio_flush(s->qdev.conf.blk, scsi_aio_complete, r); return 0; case SEEK_10: - DPRINTF("Seek(10) (sector %" PRId64 ")\n", r->req.cmd.lba); + trace_scsi_disk_emulate_command_SEEK_10(r->req.cmd.lba); if (r->req.cmd.lba > s->qdev.max_lba) { goto illegal_lba; } break; case MODE_SELECT: - DPRINTF("Mode Select(6) (len %lu)\n", (unsigned long)r->req.cmd.xfer); + trace_scsi_disk_emulate_command_MODE_SELECT(r->req.cmd.xfer); break; case MODE_SELECT_10: - DPRINTF("Mode Select(10) (len %lu)\n", (unsigned long)r->req.cmd.xfer); + trace_scsi_disk_emulate_command_MODE_SELECT_10(r->req.cmd.xfer); break; case UNMAP: - DPRINTF("Unmap (len %lu)\n", (unsigned long)r->req.cmd.xfer); + trace_scsi_disk_emulate_command_UNMAP(r->req.cmd.xfer); break; case VERIFY_10: case VERIFY_12: case VERIFY_16: - DPRINTF("Verify (bytchk %d)\n", (req->cmd.buf[1] >> 1) & 3); + trace_scsi_disk_emulate_command_VERIFY((req->cmd.buf[1] >> 1) & 3); if (req->cmd.buf[1] & 6) { goto illegal_request; } break; case WRITE_SAME_10: case WRITE_SAME_16: - DPRINTF("WRITE SAME %d (len %lu)\n", - req->cmd.buf[0] == WRITE_SAME_10 ? 10 : 16, - (unsigned long)r->req.cmd.xfer); + trace_scsi_disk_emulate_command_WRITE_SAME( + req->cmd.buf[0] == WRITE_SAME_10 ? 10 : 16, r->req.cmd.xfer); break; default: - DPRINTF("Unknown SCSI command (%2.2x=%s)\n", buf[0], - scsi_command_name(buf[0])); + trace_scsi_disk_emulate_command_UNKNOWN(buf[0], + scsi_command_name(buf[0])); scsi_check_condition(r, SENSE_CODE(INVALID_OPCODE)); return 0; } @@ -2152,7 +2140,7 @@ static int32_t scsi_disk_dma_command(SCSIRequest *req, uint8_t *buf) case READ_10: case READ_12: case READ_16: - DPRINTF("Read (sector %" PRId64 ", count %u)\n", r->req.cmd.lba, len); + trace_scsi_disk_dma_command_READ(r->req.cmd.lba, len); /* Protection information is not supported. For SCSI versions 2 and * older (as determined by snooping the guest's INQUIRY commands), * there is no RD/WR/VRPROTECT, so skip this check in these versions. @@ -2177,7 +2165,7 @@ static int32_t scsi_disk_dma_command(SCSIRequest *req, uint8_t *buf) scsi_check_condition(r, SENSE_CODE(WRITE_PROTECTED)); return 0; } - DPRINTF("Write %s(sector %" PRId64 ", count %u)\n", + trace_scsi_disk_dma_command_WRITE( (command & 0xe) == 0xe ? "And Verify " : "", r->req.cmd.lba, len); /* fall through */ @@ -2515,6 +2503,22 @@ static const SCSIReqOps *const scsi_disk_reqops_dispatch[256] = { [WRITE_VERIFY_16] = &scsi_disk_dma_reqops, }; +static void scsi_disk_new_request_dump(uint32_t lun, uint32_t tag, uint8_t *buf) +{ + int i; + int len = scsi_cdb_length(buf); + char *line_buffer, *p; + + line_buffer = g_malloc(len * 5 + 1); + + for (i = 0, p = line_buffer; i < len; i++) { + p += sprintf(p, " 0x%02x", buf[i]); + } + trace_scsi_disk_new_request(lun, tag, line_buffer); + + g_free(line_buffer); +} + static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun, uint8_t *buf, void *hba_private) { @@ -2530,16 +2534,9 @@ static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun, } req = scsi_req_alloc(ops, &s->qdev, tag, lun, hba_private); -#ifdef DEBUG_SCSI - DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", lun, tag, buf[0]); - { - int i; - for (i = 1; i < scsi_cdb_length(buf); i++) { - printf(" 0x%02x", buf[i]); - } - printf("\n"); + if (trace_event_get_state_backends(TRACE_SCSI_DISK_NEW_REQUEST)) { + scsi_disk_new_request_dump(lun, tag, buf); } -#endif return req; } diff --git a/hw/scsi/trace-events b/hw/scsi/trace-events index 2fe8a7c0620..dbd529ee6a6 100644 --- a/hw/scsi/trace-events +++ b/hw/scsi/trace-events @@ -292,3 +292,32 @@ lsi_execute_script_stop(void) "SCRIPTS execution stopped" lsi_awoken(void) "Woken by SIGP" lsi_reg_read(const char *name, int offset, uint8_t ret) "Read reg %s 0x%x = 0x%02x" lsi_reg_write(const char *name, int offset, uint8_t val) "Write reg %s 0x%x = 0x%02x" + +# hw/scsi/scsi-disk.c +scsi_disk_check_condition(uint32_t tag, uint8_t key, uint8_t asc, uint8_t ascq) "Command complete tag=0x%x sense=%d/%d/%d" +scsi_disk_read_complete(uint32_t tag, size_t size) "Data ready tag=0x%x len=%zd" +scsi_disk_read_data_count(uint32_t sector_count) "Read sector_count=%d" +scsi_disk_read_data_invalid(void) "Data transfer direction invalid" +scsi_disk_write_complete_noio(uint32_t tag, size_t size) "Write complete tag=0x%x more=%zd" +scsi_disk_write_data_invalid(void) "Data transfer direction invalid" +scsi_disk_emulate_vpd_page_00(size_t xfer) "Inquiry EVPD[Supported pages] buffer size %zd" +scsi_disk_emulate_vpd_page_80_not_supported(void) "Inquiry (EVPD[Serial number] not supported" +scsi_disk_emulate_vpd_page_80(size_t xfer) "Inquiry EVPD[Serial number] buffer size %zd" +scsi_disk_emulate_vpd_page_83(size_t xfer) "Inquiry EVPD[Device identification] buffer size %zd" +scsi_disk_emulate_vpd_page_b0_not_supported(void) "Inquiry (EVPD[Block limits] not supported for CDROM" +scsi_disk_emulate_mode_sense(int cmd, int page, size_t xfer, int control) "Mode Sense(%d) (page %d, xfer %zd, page_control %d)" +scsi_disk_emulate_read_toc(int start_track, int format, int msf) "Read TOC (track %d format %d msf %d)" +scsi_disk_emulate_read_data(int buflen) "Read buf_len=%d" +scsi_disk_emulate_write_data(int buflen) "Write buf_len=%d" +scsi_disk_emulate_command_SAI_16(void) "SAI READ CAPACITY(16)" +scsi_disk_emulate_command_SAI_unsupported(void) "Unsupported Service Action In" +scsi_disk_emulate_command_SEEK_10(uint64_t lba) "Seek(10) (sector %" PRId64 ")" +scsi_disk_emulate_command_MODE_SELECT(size_t xfer) "Mode Select(6) (len %zd)" +scsi_disk_emulate_command_MODE_SELECT_10(size_t xfer) "Mode Select(10) (len %zd)" +scsi_disk_emulate_command_UNMAP(size_t xfer) "Unmap (len %zd)" +scsi_disk_emulate_command_VERIFY(int bytchk) "Verify (bytchk %d)" +scsi_disk_emulate_command_WRITE_SAME(int cmd, size_t xfer) "WRITE SAME %d (len %zd)" +scsi_disk_emulate_command_UNKNOWN(int cmd, const char *name) "Unknown SCSI command (0x%2.2x=%s)" +scsi_disk_dma_command_READ(uint64_t lba, uint32_t len) "Read (sector %" PRId64 ", count %u)" +scsi_disk_dma_command_WRITE(const char *cmd, uint64_t lba, int len) "Write %s(sector %" PRId64 ", count %u)" +scsi_disk_new_request(uint32_t lun, uint32_t tag, const char *line) "Command: lun=%d tag=0x%x data=%s" From 568534986486e619258c6ff36b4029372624238a Mon Sep 17 00:00:00 2001 From: Laurent Vivier Date: Tue, 11 Dec 2018 17:31:05 +0100 Subject: [PATCH 75/76] scsi-generic: Convert from DPRINTF() macro to trace events MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Laurent Vivier Reviewed-by: Philippe Mathieu-Daudé Tested-by: Philippe Mathieu-Daudé Message-Id: <20181211163105.31834-3-lvivier@redhat.com> Signed-off-by: Paolo Bonzini --- hw/scsi/scsi-generic.c | 56 ++++++++++++++++++++---------------------- hw/scsi/trace-events | 11 +++++++++ 2 files changed, 37 insertions(+), 30 deletions(-) diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c index 42700e88978..d82b462be40 100644 --- a/hw/scsi/scsi-generic.c +++ b/hw/scsi/scsi-generic.c @@ -18,21 +18,10 @@ #include "hw/scsi/scsi.h" #include "hw/scsi/emulation.h" #include "sysemu/block-backend.h" +#include "trace.h" #ifdef __linux__ -//#define DEBUG_SCSI - -#ifdef DEBUG_SCSI -#define DPRINTF(fmt, ...) \ -do { printf("scsi-generic: " fmt , ## __VA_ARGS__); } while (0) -#else -#define DPRINTF(fmt, ...) do {} while(0) -#endif - -#define BADF(fmt, ...) \ -do { fprintf(stderr, "scsi-generic: " fmt , ## __VA_ARGS__); } while (0) - #include #include "scsi/constants.h" @@ -98,8 +87,7 @@ static void scsi_command_complete_noio(SCSIGenericReq *r, int ret) } } - DPRINTF("Command complete 0x%p tag=0x%x status=%d\n", - r, r->req.tag, status); + trace_scsi_generic_command_complete_noio(r, r->req.tag, status); scsi_req_complete(&r->req, status); done: @@ -261,7 +249,7 @@ static void scsi_read_complete(void * opaque, int ret) } len = r->io_header.dxfer_len - r->io_header.resid; - DPRINTF("Data ready tag=0x%x len=%d\n", r->req.tag, len); + trace_scsi_generic_read_complete(r->req.tag, len); r->len = -1; @@ -337,7 +325,7 @@ static void scsi_read_data(SCSIRequest *req) SCSIDevice *s = r->req.dev; int ret; - DPRINTF("scsi_read_data tag=0x%x\n", req->tag); + trace_scsi_generic_read_data(req->tag); /* The request is used as the AIO opaque value, so add a ref. */ scsi_req_ref(&r->req); @@ -358,7 +346,7 @@ static void scsi_write_complete(void * opaque, int ret) SCSIGenericReq *r = (SCSIGenericReq *)opaque; SCSIDevice *s = r->req.dev; - DPRINTF("scsi_write_complete() ret = %d\n", ret); + trace_scsi_generic_write_complete(ret); assert(r->req.aiocb != NULL); r->req.aiocb = NULL; @@ -373,7 +361,7 @@ static void scsi_write_complete(void * opaque, int ret) if (r->req.cmd.buf[0] == MODE_SELECT && r->req.cmd.buf[4] == 12 && s->type == TYPE_TAPE) { s->blocksize = (r->buf[9] << 16) | (r->buf[10] << 8) | r->buf[11]; - DPRINTF("block size %d\n", s->blocksize); + trace_scsi_generic_write_complete_blocksize(s->blocksize); } scsi_command_complete_noio(r, ret); @@ -390,7 +378,7 @@ static void scsi_write_data(SCSIRequest *req) SCSIDevice *s = r->req.dev; int ret; - DPRINTF("scsi_write_data tag=0x%x\n", req->tag); + trace_scsi_generic_write_data(req->tag); if (r->len == 0) { r->len = r->buflen; scsi_req_data(&r->req, r->len); @@ -413,6 +401,21 @@ static uint8_t *scsi_get_buf(SCSIRequest *req) return r->buf; } +static void scsi_generic_command_dump(uint8_t *cmd, int len) +{ + int i; + char *line_buffer, *p; + + line_buffer = g_malloc(len * 5 + 1); + + for (i = 0, p = line_buffer; i < len; i++) { + p += sprintf(p, " 0x%02x", cmd[i]); + } + trace_scsi_generic_send_command(line_buffer); + + g_free(line_buffer); +} + /* Execute a scsi command. Returns the length of the data expected by the command. This will be Positive for data transfers from the device (eg. disk reads), negative for transfers to the device (eg. disk writes), @@ -424,16 +427,9 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd) SCSIDevice *s = r->req.dev; int ret; -#ifdef DEBUG_SCSI - DPRINTF("Command: data=0x%02x", cmd[0]); - { - int i; - for (i = 1; i < r->req.cmd.len; i++) { - printf(" 0x%02x", cmd[i]); - } - printf("\n"); + if (trace_event_get_state_backends(TRACE_SCSI_GENERIC_SEND_COMMAND)) { + scsi_generic_command_dump(cmd, r->req.cmd.len); } -#endif if (r->req.cmd.xfer == 0) { g_free(r->buf); @@ -695,7 +691,7 @@ static void scsi_generic_realize(SCSIDevice *s, Error **errp) /* define device state */ s->type = scsiid.scsi_type; - DPRINTF("device type %d\n", s->type); + trace_scsi_generic_realize_type(s->type); switch (s->type) { case TYPE_TAPE: @@ -718,7 +714,7 @@ static void scsi_generic_realize(SCSIDevice *s, Error **errp) break; } - DPRINTF("block size %d\n", s->blocksize); + trace_scsi_generic_realize_blocksize(s->blocksize); /* Only used by scsi-block, but initialize it nevertheless to be clean. */ s->default_scsi_version = -1; diff --git a/hw/scsi/trace-events b/hw/scsi/trace-events index dbd529ee6a6..29aaa752d18 100644 --- a/hw/scsi/trace-events +++ b/hw/scsi/trace-events @@ -321,3 +321,14 @@ scsi_disk_emulate_command_UNKNOWN(int cmd, const char *name) "Unknown SCSI comma scsi_disk_dma_command_READ(uint64_t lba, uint32_t len) "Read (sector %" PRId64 ", count %u)" scsi_disk_dma_command_WRITE(const char *cmd, uint64_t lba, int len) "Write %s(sector %" PRId64 ", count %u)" scsi_disk_new_request(uint32_t lun, uint32_t tag, const char *line) "Command: lun=%d tag=0x%x data=%s" + +# hw/scsi/scsi-generic.c +scsi_generic_command_complete_noio(void *req, uint32_t tag, int statuc) "Command complete %p tag=0x%x status=%d" +scsi_generic_read_complete(uint32_t tag, int len) "Data ready tag=0x%x len=%d" +scsi_generic_read_data(uint32_t tag) "scsi_read_data tag=0x%x" +scsi_generic_write_complete(int ret) "scsi_write_complete() ret = %d" +scsi_generic_write_complete_blocksize(int blocksize) "block size %d" +scsi_generic_write_data(uint32_t tag) "scsi_write_data tag=0x%x" +scsi_generic_send_command(const char *line) "Command: data=%s" +scsi_generic_realize_type(int type) "device type %d" +scsi_generic_realize_blocksize(int blocksize) "block size %d" From 5ed76a4c63db9295c6c5d67895925810050d4a46 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 4 Feb 2019 16:40:18 +0100 Subject: [PATCH 76/76] queue: fix QTAILQ_FOREACH_REVERSE_SAFE The iteration was stopping as soon as prev_var was set to NULL, and therefore it skipped the first element. Fortunately, or unfortunately, we have only one use of QTAILQ_FOREACH_REVERSE_SAFE. Thus this only showed up as incorrect register preferences on the very first translation block that was compiled. Reported-by: Thomas Huth Reviewed-by: Emilio G. Cota Reviewed-by: Richard Henderson Signed-off-by: Paolo Bonzini --- include/qemu/queue.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/qemu/queue.h b/include/qemu/queue.h index 1f8e2194127..0379bd8fdbb 100644 --- a/include/qemu/queue.h +++ b/include/qemu/queue.h @@ -439,7 +439,7 @@ union { \ #define QTAILQ_FOREACH_REVERSE_SAFE(var, head, field, prev_var) \ for ((var) = QTAILQ_LAST(head); \ - (var) && ((prev_var) = QTAILQ_PREV(var, field)); \ + (var) && ((prev_var) = QTAILQ_PREV(var, field), 1); \ (var) = (prev_var)) /*