Re: [Qemu-devel] [RFC PATCH] MAINTAINERS: Add an entry for hw/core/null-machine.c

2017-01-22 Thread Marcel Apfelbaum

On 01/23/2017 07:54 AM, Thomas Huth wrote:

The "Machine core" section sounds like a good match for this file.

Signed-off-by: Thomas Huth 
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index b5ebfab..5be2033 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -813,6 +813,7 @@ M: Eduardo Habkost 
 M: Marcel Apfelbaum 
 S: Supported
 F: hw/core/machine.c
+F: hw/core/null-machine.c
 F: include/hw/boards.h

 Xtensa Machines



Reviewed-by: Marcel Apfelbaum 

Thanks,
Marcel



Re: [Qemu-devel] qemu-2.8-rc4 is broken

2017-01-22 Thread Pavel Dovgalyuk
> From: Alex Bennée [mailto:alex.ben...@linaro.org]
> Pavel Dovgalyuk  writes:
> 
> >> From: Alex Bennée [mailto:alex.ben...@linaro.org]
> >
> > Sorry, this is another problem which occurs only in icount replay mode:
> > 1. cpu_handle_exception tries to force exception when is cannot occur due to
> >running out all the planned instructions:
> > } else if (replay_has_exception()
> >&& cpu->icount_decr.u16.low + cpu->icount_extra == 0) {
> > /* try to cause an exception pending in the log */
> > cpu_exec_nocache(cpu, 1, tb_find(cpu, NULL, 0), true);
> > *ret = -1;
> > return true;
> >
> > 2. tb_find calls tb_gen_code, which cannot allocate new translation block
> >and calls tb_flush (which only queues the flushing) and cpu_loop_exit
> > 3. cpu_loop_exit returns to infinite loop of cpu_exec and the condition
> > if (cpu_handle_exception(cpu, )) {
> > break;
> > }
> >is checked again causing an infinite loop.
> >
> > TB cache is not flushed because we never execute that break and real work 
> > of tb_flush
> > is made outside this loop.
> 
> I think what we need is a:
> 
> 
>   if (cpu->exit_request)
> break;

Where this exit_request is supposed to be set?

> 
> before the cpu_handle_exception() call to ensure any queued work gets
> processed first. Can you give me you current command line so I can
> reproduce this and check the fix works?

I solved the problem using following patch:

--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -451,6 +451,10 @@ static inline bool cpu_handle_exception(CPUState *cpu, int 
*ret)
 #ifndef CONFIG_USER_ONLY
 } else if (replay_has_exception()
&& cpu->icount_decr.u16.low + cpu->icount_extra == 0) {
+/* Break the execution loop in case of running out of TB cache.
+   This is needed to make flushing of the TB cache, because
+   real flush is queued to be executed outside the cpu loop. */
+cpu->exception_index = EXCP_INTERRUPT;
 /* try to cause an exception pending in the log */
 cpu_exec_nocache(cpu, 1, tb_find(cpu, NULL, 0), true);
 *ret = -1;

Pavel Dovgalyuk




[Qemu-devel] [PATCH v3 3/6] ACPI: Add Virtual Machine Generation ID support

2017-01-22 Thread ben
From: Ben Warren 

This implements the VM Generation ID feature by passing a 128-bit
GUID to the guest via a fw_cfg blob.
Any time the GUID changes, and ACPI notify event is sent to the guest

The user interface is a simple device with one parameter:
 - guid (string, must be "auto" or in UUID format
   ----)

Signed-off-by: Ben Warren 
---
 default-configs/i386-softmmu.mak |   1 +
 default-configs/x86_64-softmmu.mak   |   1 +
 hw/acpi/Makefile.objs|   1 +
 hw/acpi/vmgenid.c| 214 +++
 hw/i386/acpi-build.c |   9 ++
 include/hw/acpi/acpi_dev_interface.h |   1 +
 include/hw/acpi/vmgenid.h|  32 ++
 7 files changed, 259 insertions(+)
 create mode 100644 hw/acpi/vmgenid.c
 create mode 100644 include/hw/acpi/vmgenid.h

diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak
index 0b51360..b2bccf6 100644
--- a/default-configs/i386-softmmu.mak
+++ b/default-configs/i386-softmmu.mak
@@ -56,3 +56,4 @@ CONFIG_IOH3420=y
 CONFIG_I82801B11=y
 CONFIG_SMBIOS=y
 CONFIG_HYPERV_TESTDEV=$(CONFIG_KVM)
+CONFIG_ACPI_VMGENID=y
diff --git a/default-configs/x86_64-softmmu.mak 
b/default-configs/x86_64-softmmu.mak
index 7f89503..c6bd310 100644
--- a/default-configs/x86_64-softmmu.mak
+++ b/default-configs/x86_64-softmmu.mak
@@ -56,3 +56,4 @@ CONFIG_IOH3420=y
 CONFIG_I82801B11=y
 CONFIG_SMBIOS=y
 CONFIG_HYPERV_TESTDEV=$(CONFIG_KVM)
+CONFIG_ACPI_VMGENID=y
diff --git a/hw/acpi/Makefile.objs b/hw/acpi/Makefile.objs
index 834c63b..98cb115 100644
--- a/hw/acpi/Makefile.objs
+++ b/hw/acpi/Makefile.objs
@@ -4,6 +4,7 @@ common-obj-$(CONFIG_ACPI_CPU_HOTPLUG) += cpu_hotplug.o
 common-obj-$(CONFIG_ACPI_MEMORY_HOTPLUG) += memory_hotplug.o
 common-obj-$(CONFIG_ACPI_CPU_HOTPLUG) += cpu.o
 common-obj-$(CONFIG_ACPI_NVDIMM) += nvdimm.o
+common-obj-$(CONFIG_ACPI_VMGENID) += vmgenid.o
 common-obj-$(CONFIG_ACPI) += acpi_interface.o
 common-obj-$(CONFIG_ACPI) += bios-linker-loader.o
 common-obj-$(CONFIG_ACPI) += aml-build.o
diff --git a/hw/acpi/vmgenid.c b/hw/acpi/vmgenid.c
new file mode 100644
index 000..2d831b2
--- /dev/null
+++ b/hw/acpi/vmgenid.c
@@ -0,0 +1,214 @@
+/*
+ *  Virtual Machine Generation ID Device
+ *
+ *  Copyright (C) 2017 Skyport Systems.
+ *
+ *  Authors: Ben Warren 
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qmp-commands.h"
+#include "hw/acpi/acpi.h"
+#include "hw/acpi/aml-build.h"
+#include "hw/acpi/vmgenid.h"
+#include "hw/nvram/fw_cfg.h"
+#include "sysemu/sysemu.h"
+
+Object *find_vmgenid_dev(Error **errp)
+{
+Object *obj = object_resolve_path_type("", VMGENID_DEVICE, NULL);
+if (!obj) {
+error_setg(errp, VMGENID_DEVICE " is not found");
+}
+return obj;
+}
+
+void vmgenid_build_acpi(GArray *table_offsets, GArray *table_data,
+ BIOSLinker *linker)
+{
+Object *obj;
+VmGenIdState *s;
+GArray *guid;
+Aml *ssdt, *dev, *scope, *method, *addr, *if_ctx;
+uint32_t vgia_offset;
+
+obj = find_vmgenid_dev(NULL);
+if (!obj) {
+return;
+}
+s = VMGENID(obj);
+
+acpi_add_table(table_offsets, table_data);
+
+guid = g_array_new(false, true, sizeof(s->guid.data));
+g_array_append_val(guid, s->guid.data);
+
+/* Put this in a separate SSDT table */
+ssdt = init_aml_allocator();
+
+/* Reserve space for header */
+acpi_data_push(ssdt->buf, sizeof(AcpiTableHeader));
+
+/* Storage for the GUID address */
+vgia_offset = table_data->len +
+build_append_named_qword(ssdt->buf, "VGIA");
+scope = aml_scope("\\_SB");
+dev = aml_device("VGEN");
+aml_append(dev, aml_name_decl("_HID", aml_string("QEMUVGID")));
+aml_append(dev, aml_name_decl("_CID", aml_string("VM_Gen_Counter")));
+aml_append(dev, aml_name_decl("_DDN", aml_string("VM_Gen_Counter")));
+
+/* Simple status method to check that address is linked and non-zero */
+method = aml_method("_STA", 0, AML_NOTSERIALIZED);
+addr = aml_local(0);
+aml_append(method, aml_store(aml_int(0xf), addr));
+if_ctx = aml_if(aml_equal(aml_name("VGIA"), aml_int(0)));
+aml_append(if_ctx, aml_store(aml_int(0), addr));
+aml_append(method, if_ctx);
+aml_append(method, aml_return(addr));
+aml_append(dev, method);
+
+/* the ADDR method returns two 32-bit words representing the lower and
+ * upper halves * of the physical address of the fw_cfg blob
+ * (holding the GUID) */
+method = aml_method("ADDR", 0, AML_NOTSERIALIZED);
+
+addr = aml_local(0);
+aml_append(method, aml_store(aml_package(2), addr));
+
+aml_append(method, aml_store(aml_and(aml_name("VGIA"),
+aml_int(0x), NULL), aml_index(addr, aml_int(0;
+aml_append(method, 

[Qemu-devel] [PATCH v3 5/6] qmp/hmp: add set-vm-generation-id commands

2017-01-22 Thread ben
From: Igor Mammedov 

Add set-vm-generation-id command to set Virtual Machine
Generation ID counter.

QMP command example:
{ "execute": "set-vm-generation-id",
  "arguments": {
  "guid": "324e6eaf-d1d1-4bf6-bf41-b9bb6c91fb87"
  }
}

HMP command example:
set-vm-generation-id guid=324e6eaf-d1d1-4bf6-bf41-b9bb6c91fb87

Signed-off-by: Igor Mammedov 
Reviewed-by: Eric Blake 
Signed-off-by: Ben Warren 
---
 hmp-commands.hx  | 13 +
 hmp.c| 12 
 hmp.h|  1 +
 qapi-schema.json | 11 +++
 stubs/vmgenid.c  |  6 ++
 5 files changed, 43 insertions(+)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 8819281..56744aa 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1775,5 +1775,18 @@ ETEXI
 },
 
 STEXI
+@item set-vm-generation-id @var{uuid}
+Set Virtual Machine Generation ID counter to @var{guid}
+ETEXI
+
+{
+.name   = "set-vm-generation-id",
+.args_type  = "guid:s",
+.params = "guid",
+.help   = "Set Virtual Machine Generation ID counter",
+.cmd = hmp_set_vm_generation_id,
+},
+
+STEXI
 @end table
 ETEXI
diff --git a/hmp.c b/hmp.c
index c2280e0..3a4db8b 100644
--- a/hmp.c
+++ b/hmp.c
@@ -2573,3 +2573,15 @@ void hmp_info_vm_generation_id(Monitor *mon, const QDict 
*qdict)
 }
 qapi_free_GuidInfo(info);
 }
+
+void hmp_set_vm_generation_id(Monitor *mon, const QDict *qdict)
+{
+Error *errp = NULL;
+const char *guid = qdict_get_str(qdict, "guid");
+
+qmp_set_vm_generation_id(guid, );
+if (errp) {
+hmp_handle_error(mon, );
+return;
+}
+}
diff --git a/hmp.h b/hmp.h
index 799fd37..e0ac1e8 100644
--- a/hmp.h
+++ b/hmp.h
@@ -138,5 +138,6 @@ void hmp_rocker_of_dpa_groups(Monitor *mon, const QDict 
*qdict);
 void hmp_info_dump(Monitor *mon, const QDict *qdict);
 void hmp_hotpluggable_cpus(Monitor *mon, const QDict *qdict);
 void hmp_info_vm_generation_id(Monitor *mon, const QDict *qdict);
+void hmp_set_vm_generation_id(Monitor *mon, const QDict *qdict);
 
 #endif
diff --git a/qapi-schema.json b/qapi-schema.json
index 0eb3964..eddb5a9 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -6041,3 +6041,14 @@
 # Since 2.9
 ##
 { 'command': 'query-vm-generation-id', 'returns': 'GuidInfo' }
+
+##
+# @set-vm-generation-id:
+#
+# Set Virtual Machine Generation ID
+#
+# @guid: new GUID to set as Virtual Machine Generation ID
+#
+# Since 2.9
+##
+{ 'command': 'set-vm-generation-id', 'data': {'guid': 'str'} }
diff --git a/stubs/vmgenid.c b/stubs/vmgenid.c
index 8c448ac..d25d41b 100644
--- a/stubs/vmgenid.c
+++ b/stubs/vmgenid.c
@@ -6,3 +6,9 @@ GuidInfo *qmp_query_vm_generation_id(Error **errp)
 error_setg(errp, "this command is not currently supported");
 return NULL;
 }
+
+void qmp_set_vm_generation_id(const char *guid, Error **errp)
+{
+error_setg(errp, "this command is not currently supported");
+return;
+}
-- 
2.10.1 (Apple Git-78)




[Qemu-devel] [PATCH v3 2/6] linker-loader: add new 'allocate and return address' cmd

2017-01-22 Thread ben
From: Ben Warren 

This adds a new linker-loader command to instruct the guest to allocate
memory for a fw_cfg file and write the address back into another
writeable fw_cfg file.  Knowing this address, QEMU can then write into
guest memory at runtime.

Signed-off-by: Ben Warren 
---
 hw/acpi/bios-linker-loader.c | 71 ++--
 include/hw/acpi/bios-linker-loader.h |  7 
 2 files changed, 75 insertions(+), 3 deletions(-)

diff --git a/hw/acpi/bios-linker-loader.c b/hw/acpi/bios-linker-loader.c
index d963ebe..1d991ba 100644
--- a/hw/acpi/bios-linker-loader.c
+++ b/hw/acpi/bios-linker-loader.c
@@ -78,6 +78,22 @@ struct BiosLinkerLoaderEntry {
 uint32_t length;
 } cksum;
 
+/*
+ * COMMAND_ALLOCATE_RETURN_ADDR - allocate a table from @alloc_ret_file
+ * subject to @alloc_ret_align alignment (must be power of 2)
+ * and @alloc_ret_zone (can be HIGH or FSEG) requirements.
+ * Additionally, return the address of the allocation in
+ * @addr_file.
+ *
+ * This may be used instead of COMMAND_ALLOCATE
+ */
+struct {
+char alloc_ret_file[BIOS_LINKER_LOADER_FILESZ];
+uint32_t alloc_ret_align;
+uint8_t alloc_ret_zone;
+char alloc_ret_addr_file[BIOS_LINKER_LOADER_FILESZ];
+};
+
 /* padding */
 char pad[124];
 };
@@ -85,9 +101,10 @@ struct BiosLinkerLoaderEntry {
 typedef struct BiosLinkerLoaderEntry BiosLinkerLoaderEntry;
 
 enum {
-BIOS_LINKER_LOADER_COMMAND_ALLOCATE = 0x1,
-BIOS_LINKER_LOADER_COMMAND_ADD_POINTER  = 0x2,
-BIOS_LINKER_LOADER_COMMAND_ADD_CHECKSUM = 0x3,
+BIOS_LINKER_LOADER_COMMAND_ALLOCATE  = 0x1,
+BIOS_LINKER_LOADER_COMMAND_ADD_POINTER   = 0x2,
+BIOS_LINKER_LOADER_COMMAND_ADD_CHECKSUM  = 0x3,
+BIOS_LINKER_LOADER_COMMAND_ALLOCATE_RET_ADDR = 0x4,
 };
 
 enum {
@@ -278,3 +295,51 @@ void bios_linker_loader_add_pointer(BIOSLinker *linker,
 
 g_array_append_vals(linker->cmd_blob, , sizeof entry);
 }
+
+/*
+ * bios_linker_loader_alloc_ret_addr: ask guest to load file into guest memory
+ * and patch the address in another file
+ *
+ * @linker: linker object instance
+ * @data_file: name of the file blob to be loaded
+ * @file_blob: pointer to blob corresponding to @file_name
+ * @alloc_align: required minimal alignment in bytes. Must be a power of 2.
+ * @alloc_fseg: request allocation in FSEG zone (useful for the RSDP ACPI 
table)
+ * @addr_file: destination file that will contain the address.
+ * This must already exist
+ *
+ * Note: this command must precede any other linker command that uses
+ * the data file.
+ */
+void bios_linker_loader_alloc_ret_addr(BIOSLinker *linker,
+  const char *data_file,
+  GArray *file_blob,
+  uint32_t alloc_align,
+  bool alloc_fseg,
+  const char *addr_file)
+{
+BiosLinkerLoaderEntry entry;
+BiosLinkerFileEntry d_file = { g_strdup(data_file), file_blob};
+
+/* Address file is expected to already be loaded */
+const BiosLinkerFileEntry *a_file =
+bios_linker_find_file(linker, addr_file);
+
+assert(!(alloc_align & (alloc_align - 1)));
+assert(a_file);
+
+g_array_append_val(linker->file_list, d_file);
+
+memset(, 0, sizeof entry);
+strncpy(entry.alloc_ret_file, data_file,
+sizeof entry.alloc_ret_file - 1);
+strncpy(entry.alloc_ret_addr_file, addr_file,
+sizeof entry.alloc_ret_addr_file - 1);
+entry.command = cpu_to_le32(BIOS_LINKER_LOADER_COMMAND_ALLOCATE_RET_ADDR);
+entry.alloc.align = cpu_to_le32(alloc_align);
+entry.alloc.zone = alloc_fseg ? BIOS_LINKER_LOADER_ALLOC_ZONE_FSEG :
+BIOS_LINKER_LOADER_ALLOC_ZONE_HIGH;
+
+/* Alloc entries must come first, so prepend them */
+g_array_append_vals(linker->cmd_blob, , sizeof entry);
+}
diff --git a/include/hw/acpi/bios-linker-loader.h 
b/include/hw/acpi/bios-linker-loader.h
index fa1e5d1..69953e6 100644
--- a/include/hw/acpi/bios-linker-loader.h
+++ b/include/hw/acpi/bios-linker-loader.h
@@ -26,5 +26,12 @@ void bios_linker_loader_add_pointer(BIOSLinker *linker,
 const char *src_file,
 uint32_t src_offset);
 
+void bios_linker_loader_alloc_ret_addr(BIOSLinker *linker,
+   const char *data_file,
+   GArray *file_blob,
+   uint32_t alloc_align,
+   bool alloc_fseg,
+   const char *addr_file);
+
 void bios_linker_loader_cleanup(BIOSLinker *linker);
 #endif
-- 
2.10.1 (Apple Git-78)




[Qemu-devel] [PATCH v3 4/6] qmp/hmp: add query-vm-generation-id and 'info vm-generation-id' commands

2017-01-22 Thread ben
From: Igor Mammedov 

Add commands to query Virtual Machine Generation ID counter.

QMP command example:
{ "execute": "query-vm-generation-id" }

HMP command example:
info vm-generation-id

Signed-off-by: Igor Mammedov 
Reviewed-by: Eric Blake 
Signed-off-by: Ben Warren 
---
 hmp-commands-info.hx | 13 +
 hmp.c|  9 +
 hmp.h|  1 +
 qapi-schema.json | 20 
 stubs/Makefile.objs  |  1 +
 stubs/vmgenid.c  |  8 
 6 files changed, 52 insertions(+)
 create mode 100644 stubs/vmgenid.c

diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
index 55d50c4..b0bb052 100644
--- a/hmp-commands-info.hx
+++ b/hmp-commands-info.hx
@@ -802,6 +802,19 @@ Show information about hotpluggable CPUs
 ETEXI
 
 STEXI
+@item info vm-generation-id
+Show Virtual Machine Generation ID
+ETEXI
+
+{
+.name   = "vm-generation-id",
+.args_type  = "",
+.params = "",
+.help   = "Show Virtual Machine Generation ID",
+.cmd = hmp_info_vm_generation_id,
+},
+
+STEXI
 @end table
 ETEXI
 
diff --git a/hmp.c b/hmp.c
index 8522efe..c2280e0 100644
--- a/hmp.c
+++ b/hmp.c
@@ -2564,3 +2564,12 @@ void hmp_hotpluggable_cpus(Monitor *mon, const QDict 
*qdict)
 
 qapi_free_HotpluggableCPUList(saved);
 }
+
+void hmp_info_vm_generation_id(Monitor *mon, const QDict *qdict)
+{
+GuidInfo *info = qmp_query_vm_generation_id(NULL);
+if (info) {
+monitor_printf(mon, "%s\n", info->guid);
+}
+qapi_free_GuidInfo(info);
+}
diff --git a/hmp.h b/hmp.h
index 05daf7c..799fd37 100644
--- a/hmp.h
+++ b/hmp.h
@@ -137,5 +137,6 @@ void hmp_rocker_of_dpa_flows(Monitor *mon, const QDict 
*qdict);
 void hmp_rocker_of_dpa_groups(Monitor *mon, const QDict *qdict);
 void hmp_info_dump(Monitor *mon, const QDict *qdict);
 void hmp_hotpluggable_cpus(Monitor *mon, const QDict *qdict);
+void hmp_info_vm_generation_id(Monitor *mon, const QDict *qdict);
 
 #endif
diff --git a/qapi-schema.json b/qapi-schema.json
index ddc8783..0eb3964 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -6021,3 +6021,23 @@
 #
 ##
 { 'command': 'query-hotpluggable-cpus', 'returns': ['HotpluggableCPU'] }
+
+##
+# @GuidInfo:
+#
+# GUID information.
+#
+# @guid: the globally unique identifier
+#
+# Since: 2.9
+##
+{ 'struct': 'GuidInfo', 'data': {'guid': 'str'} }
+
+##
+# @query-vm-generation-id:
+#
+# Show Virtual Machine Generation ID
+#
+# Since 2.9
+##
+{ 'command': 'query-vm-generation-id', 'returns': 'GuidInfo' }
diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
index 2b5bb74..988d5d7 100644
--- a/stubs/Makefile.objs
+++ b/stubs/Makefile.objs
@@ -50,3 +50,4 @@ stub-obj-y += smbios_type_38.o
 stub-obj-y += ipmi.o
 stub-obj-y += pc_madt_cpu_entry.o
 stub-obj-y += migration-colo.o
+stub-obj-y += vmgenid.o
diff --git a/stubs/vmgenid.c b/stubs/vmgenid.c
new file mode 100644
index 000..8c448ac
--- /dev/null
+++ b/stubs/vmgenid.c
@@ -0,0 +1,8 @@
+#include "qemu/osdep.h"
+#include "qmp-commands.h"
+
+GuidInfo *qmp_query_vm_generation_id(Error **errp)
+{
+error_setg(errp, "this command is not currently supported");
+return NULL;
+}
-- 
2.10.1 (Apple Git-78)




[Qemu-devel] [PATCH v3 6/6] PC: Support dynamic sysbus on pc_i440fx

2017-01-22 Thread ben
From: Ben Warren 

This allows pc_i440fx-based machines to add new devices such as VM Generation ID
directly to the sysbus.

Signed-off-by: Ben Warren 
---
 hw/i386/pc_piix.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 9f102aa..c8ad99c 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -435,6 +435,7 @@ static void pc_i440fx_machine_options(MachineClass *m)
 m->hot_add_cpu = pc_hot_add_cpu;
 m->default_machine_opts = "firmware=bios-256k.bin";
 m->default_display = "std";
+m->has_dynamic_sysbus = true;
 }
 
 static void pc_i440fx_2_9_machine_options(MachineClass *m)
-- 
2.10.1 (Apple Git-78)




[Qemu-devel] [PATCH v3 0/6] Add support for VM Generation ID

2017-01-22 Thread ben
From: Ben Warren 

This patch set adds support for passing a GUID to Windows guests.  It is a
re-implementation of previous patch sets written by Igor Mammedov et al, but
this time passing the GUID data as a fw_cfg blob.

This patch set has dependencies on new guest functionality, in particular the
support for a new linker-loader command and the ability to write back data
to QEMU over a DMA link.  Work is in flight in both SeaBIOS and OVMF to support 
this.

v2->v3:
- Added second writeable fw_cfg for storing the VM Generaiton ID
  address.  This uses a new linker-loader command for instructing the
  guest to write back the allocated address.  A patch for SeaBIOS has been
  submitted 
(https://www.seabios.org/pipermail/seabios/2017-January/011079.html)
  and the resulting binary will need to be pulled into QEMU once accepted.
- Setting VM Generation ID by command line or qmp/hmp now accepts an "auto"
  value, whereby QEMU generates a random GUID.
- Incorporated review comments from v2 mainly around code styling and AML 
syntax
- Changed to use the E05 ACPI event instead of E00
v1->v2:
- Removed "changed" boolean parameter as it is unneeded
- Added ACPI Notify logic
- Style changes to pass checkpatch.pl
- Added support for dynamic sysbus to pc_piix boards

Ben Warren (4):
  ACPI: Add a function for building named qword entries
  linker-loader: add new 'allocate and return address' cmd
  ACPI: Add Virtual Machine Generation ID support
  PC: Support dynamic sysbus on pc_i440fx

Igor Mammedov (2):
  qmp/hmp: add query-vm-generation-id and 'info vm-generation-id'
commands
  qmp/hmp: add set-vm-generation-id commands

 default-configs/i386-softmmu.mak |   1 +
 default-configs/x86_64-softmmu.mak   |   1 +
 hmp-commands-info.hx |  13 +++
 hmp-commands.hx  |  13 +++
 hmp.c|  21 
 hmp.h|   2 +
 hw/acpi/Makefile.objs|   1 +
 hw/acpi/aml-build.c  |  28 +
 hw/acpi/bios-linker-loader.c |  71 +++-
 hw/acpi/vmgenid.c| 214 +++
 hw/i386/acpi-build.c |   9 ++
 hw/i386/pc_piix.c|   1 +
 include/hw/acpi/acpi_dev_interface.h |   1 +
 include/hw/acpi/aml-build.h  |   4 +
 include/hw/acpi/bios-linker-loader.h |   7 ++
 include/hw/acpi/vmgenid.h|  32 ++
 qapi-schema.json |  31 +
 stubs/Makefile.objs  |   1 +
 stubs/vmgenid.c  |  14 +++
 19 files changed, 462 insertions(+), 3 deletions(-)
 create mode 100644 hw/acpi/vmgenid.c
 create mode 100644 include/hw/acpi/vmgenid.h
 create mode 100644 stubs/vmgenid.c

-- 
2.10.1 (Apple Git-78)




[Qemu-devel] [PATCH v3 1/6] ACPI: Add a function for building named qword entries

2017-01-22 Thread ben
From: Ben Warren 

This is initially used to patch a 64-bit address into the VM Generation ID SSDT

Signed-off-by: Ben Warren 
---
 hw/acpi/aml-build.c | 28 
 include/hw/acpi/aml-build.h |  4 
 2 files changed, 32 insertions(+)

diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index b2a1e40..dc4edc2 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -285,6 +285,34 @@ build_append_named_dword(GArray *array, const char 
*name_format, ...)
 return offset;
 }
 
+/*
+ * Build NAME(, 0x) where 0x is encoded as a qword,
+ * and return the offset to 0x for runtime patching.
+ *
+ * Warning: runtime patching is best avoided. Only use this as
+ * a replacement for DataTableRegion (for guests that don't
+ * support it).
+ */
+int
+build_append_named_qword(GArray *array, const char *name_format, ...)
+{
+int offset;
+va_list ap;
+
+build_append_byte(array, 0x08); /* NameOp */
+va_start(ap, name_format);
+build_append_namestringv(array, name_format, ap);
+va_end(ap);
+
+build_append_byte(array, 0x0E); /* QWordPrefix */
+
+offset = array->len;
+build_append_int_noprefix(array, 0x, 8);
+assert(array->len == offset + 8);
+
+return offset;
+}
+
 static GPtrArray *alloc_list;
 
 static Aml *aml_alloc(void)
diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
index 559326c..dbf63cf 100644
--- a/include/hw/acpi/aml-build.h
+++ b/include/hw/acpi/aml-build.h
@@ -385,6 +385,10 @@ int
 build_append_named_dword(GArray *array, const char *name_format, ...)
 GCC_FMT_ATTR(2, 3);
 
+int
+build_append_named_qword(GArray *array, const char *name_format, ...)
+GCC_FMT_ATTR(2, 3);
+
 void build_srat_memory(AcpiSratMemoryAffinity *numamem, uint64_t base,
uint64_t len, int node, MemoryAffinityFlags flags);
 
-- 
2.10.1 (Apple Git-78)




Re: [Qemu-devel] [PATCH RFC v4 19/20] intel_iommu: unmap existing pages before replay

2017-01-22 Thread Peter Xu
On Mon, Jan 23, 2017 at 09:57:23AM +0800, Jason Wang wrote:
> 
> 
> On 2017年01月22日 17:09, Peter Xu wrote:
> >On Sun, Jan 22, 2017 at 04:13:32PM +0800, Jason Wang wrote:
> >>
> >>On 2017年01月20日 21:08, Peter Xu wrote:
> >>>Previous replay works for domain switch only if the original domain does
> >>>not have mapped pages. For example, if we switch domain from A to B, it
> >>>will only work if A has no existing mapping. If there is, then there's
> >>>problem - current replay didn't make sure the old mappings are cleared
> >>>before replaying the new one.
> >>I'm not quite sure this is needed. I thought the only thing we need to do is
> >>stop DMA of device during the moving? Or is there an example that will cause
> >>trouble?
> >I think this patch is essential.
> >
> >Example:
> >
> >- device D1 moved to domain A, domain A has no mapping
> >- map page P1 in domain A, so D1 will have a mapping of page P1
> >- create domain B with mapping P2
> >- move D1 from domain A to domain B
> >
> >Here if we don't unmap existing pages in domain A (P1),
> 
> I thought driver should do this work instead of device, because only driver
> knows whether or not iova is still needed?

Do you mean "device driver" above?

I don't know whether I understood the question above, but the problem
should be there no matter which one is managing iova?

Thanks,

-- peterx



Re: [Qemu-devel] [PATCH] qapi: Remove unwanted commas after #optional keyword

2017-01-22 Thread Markus Armbruster
Stefan Weil  writes:

> We don't want that commas to be part of the generated documentation,
> so remove them.
>
> Signed-off-by: Stefan Weil 
> ---
>
> This is an alternative solution for the issue which is also addressed
> by my previous patch http://patchwork.ozlabs.org/patch/718177/.
>
> It's also possible to apply both patches.

I'll take this one.

Reviewed-by: Markus Armbruster 

Applied to qapi-next, thanks!



Re: [Qemu-devel] [RFC 08/13] pc: add writeonly 'cpu' property to PCMachine

2017-01-22 Thread Bharata B Rao
On Thu, Jan 19, 2017 at 04:04:23PM +0100, Igor Mammedov wrote:
> On Wed, 18 Jan 2017 16:57:13 -0200
> Eduardo Habkost  wrote:
> 
> > On Wed, Jan 18, 2017 at 06:13:24PM +0100, Igor Mammedov wrote:
> > > it will allow generic numa code to set cpu to numa node mapping
> > > in target independent manner in the next patch.
> > > 
> > > Signed-off-by: Igor Mammedov 
> > > ---
> > >  hw/i386/pc.c | 56 
> > > 
> > >  1 file changed, 56 insertions(+)
> > > 
> > > diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> > > index f8ea635..1d33a5e 100644
> > > --- a/hw/i386/pc.c
> > > +++ b/hw/i386/pc.c
> > > @@ -2201,6 +2201,56 @@ static void pc_machine_set_pit(Object *obj, bool 
> > > value, Error **errp)
> > >  pcms->pit = value;
> > >  }
> > >  
> > > +static void pc_machine_set_cpu(Object *obj, Visitor *v, const char *name,
> > > +   void *opaque, Error **errp)
> > > +{
> > > +uint32_t apic_id;
> > > +X86CPUTopoInfo topo;
> > > +CPUArchId *cpu_slot;
> > > +Error *local_err = NULL;
> > > +CpuInstanceProperties *cpu_props = NULL;
> > > +PCMachineState *pcms = PC_MACHINE(obj);
> > > +MachineClass *mc = MACHINE_GET_CLASS(obj);
> > > +
> > > +visit_type_CpuInstanceProperties(v, name, _props, _err);
> > > +if (local_err) {
> > > +goto out;
> > > +}
> > > +
> > > +if (!cpu_props->has_node_id) {
> > > +error_setg(_err, "node-id property is not specified");
> > > +goto out;
> > > +}
> > > +
> > > +/*
> > > + * make sure that possible_cpus is initialized
> > > + * as property setter might be called before machine init is called
> > > + */
> > > +mc->possible_cpu_arch_ids(MACHINE(obj));
> > > +
> > > +topo.pkg_id = cpu_props->socket_id;
> > > +topo.core_id = cpu_props->core_id;
> > > +topo.smt_id = cpu_props->thread_id;
> > > +apic_id = apicid_from_topo_ids(smp_cores, smp_threads, );
> > > +cpu_slot = pc_find_cpu_slot(pcms, apic_id, NULL);  
> > 
> > If we make TYPE_MACHINE provide an API to query CPU slots, e.g.:
> >   CPUArchId *machine_find_cpu_slot(MachineState *m, CpuInstanceProperties 
> > *props)
> so if there is no objections, 
> I'll move possible_cpus to MachineState
> and add to MachineClass above callback so target machine
> would be able to provide arch specific lookup function.
> it should work for both x86 and ARM.

The need for possible_cpus in MachineState for sPAPR isn't immediately
apparent to me. In the context of this new numa "cpu" property, PC target
seems to use possible_cpus to store and later lookup the numa node id for
a given CPU. Wondering if that could be achieved w/o needing possible_cpus
in MachineState ?

Regards,
Bharata.




[Qemu-devel] [RFC PATCH] MAINTAINERS: Add an entry for hw/core/null-machine.c

2017-01-22 Thread Thomas Huth
The "Machine core" section sounds like a good match for this file.

Signed-off-by: Thomas Huth 
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index b5ebfab..5be2033 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -813,6 +813,7 @@ M: Eduardo Habkost 
 M: Marcel Apfelbaum 
 S: Supported
 F: hw/core/machine.c
+F: hw/core/null-machine.c
 F: include/hw/boards.h
 
 Xtensa Machines
-- 
1.8.3.1




Re: [Qemu-devel] [PATCH] Change name of live migration thread

2017-01-22 Thread Amit Shah
On (Sun) 22 Jan 2017 [12:47:51], Pankaj Gupta wrote:
> Change the name of live migration thread from 'migration' 
> to 'qemu_vm_migration' to identify it clearly. 'migration'
> is a generic word and kernel also has  tasks for process
> migration with the name 'migration/cpu#'.

Makes sense.

Reviewed-by: Amit Shah 

Amit



Re: [Qemu-devel] [PATCH 01/21] backup: move from done_bitmap to copy_bitmap

2017-01-22 Thread Jeff Cody
On Fri, Dec 23, 2016 at 05:28:44PM +0300, Vladimir Sementsov-Ogievskiy wrote:
> Use HBitmap copy_bitmap instead of done_bitmap. This is needed to unify
> backup loop for full/incremental modes in future patches.
> 
> We reset bit of the copy_bitmap immediately after checking it in
> backup_do_cow(). It is safe, because all other intersecting requests
> will wait for our request finish anyway.
> 
> The other difference is that in case of error we will have zeroed bit in
> copy_bitmap, when in done_bitmap we have not set bit.
> 
> Signed-off-by: Vladimir Sementsov-Ogievskiy 
> ---
>  block/backup.c | 17 ++---
>  1 file changed, 10 insertions(+), 7 deletions(-)
> 
> diff --git a/block/backup.c b/block/backup.c
> index ea38733..6b27e55 100644
> --- a/block/backup.c
> +++ b/block/backup.c
> @@ -39,11 +39,12 @@ typedef struct BackupBlockJob {
>  BlockdevOnError on_target_error;
>  CoRwlock flush_rwlock;
>  uint64_t sectors_read;
> -unsigned long *done_bitmap;
>  int64_t cluster_size;
>  bool compress;
>  NotifierWithReturn before_write;
>  QLIST_HEAD(, CowRequest) inflight_reqs;
> +
> +HBitmap *copy_bitmap;
>  } BackupBlockJob;
>  
>  /* Size of a cluster in sectors, instead of bytes. */
> @@ -115,10 +116,11 @@ static int coroutine_fn backup_do_cow(BackupBlockJob 
> *job,
>  cow_request_begin(_request, job, start, end);
>  
>  for (; start < end; start++) {
> -if (test_bit(start, job->done_bitmap)) {
> +if (!hbitmap_get(job->copy_bitmap, start)) {
>  trace_backup_do_cow_skip(job, start);
>  continue; /* already copied */
>  }
> +hbitmap_reset(job->copy_bitmap, start, 1);
>  
>  trace_backup_do_cow_process(job, start);
>  
> @@ -141,6 +143,7 @@ static int coroutine_fn backup_do_cow(BackupBlockJob *job,
>  if (error_is_read) {
>  *error_is_read = true;
>  }
> +hbitmap_set(job->copy_bitmap, start, 1);
>  goto out;
>  }
>  
> @@ -157,11 +160,10 @@ static int coroutine_fn backup_do_cow(BackupBlockJob 
> *job,
>  if (error_is_read) {
>  *error_is_read = false;
>  }
> +hbitmap_set(job->copy_bitmap, start, 1);
>  goto out;
>  }
>  
> -set_bit(start, job->done_bitmap);
> -
>  /* Publish progress, guest I/O counts as progress too.  Note that the
>   * offset field is an opaque progress value, it is not a disk offset.
>   */
> @@ -271,7 +273,7 @@ void backup_do_checkpoint(BlockJob *job, Error **errp)
>  }
>  
>  len = DIV_ROUND_UP(backup_job->common.len, backup_job->cluster_size);
> -bitmap_zero(backup_job->done_bitmap, len);
> +hbitmap_set(backup_job->copy_bitmap, 0, len);
>  }
>  
>  void backup_wait_for_overlapping_requests(BlockJob *job, int64_t sector_num,
> @@ -450,7 +452,8 @@ static void coroutine_fn backup_run(void *opaque)
>  start = 0;
>  end = DIV_ROUND_UP(job->common.len, job->cluster_size);
>  
> -job->done_bitmap = bitmap_new(end);
> +job->copy_bitmap = hbitmap_alloc(end, 0);
> +hbitmap_set(job->copy_bitmap, 0, end);
>  
>  job->before_write.notify = backup_before_write_notify;
>  bdrv_add_before_write_notifier(bs, >before_write);
> @@ -524,7 +527,7 @@ static void coroutine_fn backup_run(void *opaque)
>  /* wait until pending backup_do_cow() calls have completed */
>  qemu_co_rwlock_wrlock(>flush_rwlock);
>  qemu_co_rwlock_unlock(>flush_rwlock);
> -g_free(job->done_bitmap);
> +hbitmap_free(job->copy_bitmap);
>  
>  data = g_malloc(sizeof(*data));
>  data->ret = ret;
> -- 
> 1.8.3.1
>

Reviewed-by: Jeff Cody 




Re: [Qemu-devel] [PATCH v4 0/2] block/qapi: refactor and optimize the qmp_query_blockstats()

2017-01-22 Thread Dou Liyang

Hi, Markus

Here is the non-RFC patch.
Any suggestions are welcome. :)

Thanks,
Liyang.

At 01/15/2017 04:01 PM, Dou Liyang wrote:

Change log v3 -> v4:
 1. Develop these into the non-RFC patches.
 2. Fix some comments.
 3. do declarations first.

Change log v2 -> v3:
 1. Remove the unnecessary code for the bdrv_next_node().
 2. Remove the change of the locking rules.
Even if this change can improve the performance, but it may
effect the consistency.

The Qemu uses the qmp_query_blockstats() function to get the
blockstats. As the function has been changed several times, it
becomes more complex and longer.

For the multi-disks guest, if we want to execute I/O operations
and this function at the same time. we can use the dataplane
feature to hold I/O performance does not drop. But, Normally
without this feature, How to reduce the decline in performance?

These patches refactor the qmp_query_blockstats() to make the
code easier to follow, and shorter as follows:

From:

+--+  +-+
 | 1|  | 4.  |
 |next_query_bds|  |bdrv_query_bds_stats +---+
 |  |  | |   |
 +^-+  +-^---+   |
  |  |   |
+-+--+  ++---+   |
| 0. |  | 2. |   |
|qmp_query_blockstats+-->bdrv_query_stats<
||  ||
++  ++---+
 |
   +-v---+
   | 3.  |
   |bdrv_query_blk_stats |
   | |
   +-+

To:

+--+
|  |
   +v---+  |
   +--->  3.|  |
+---+  |   |bdrv_query_bds_stats+--+
| 1.+--+   ||
|   +  ++
|qmp_query_blockstats--+
|   |  |
+---+  |   ++
   |   | 2. |
   +--->|
   |bdrv_query_blk_stats|
   ||
   ++


They also optimize the fuction by reducing its running time.

1. The function running time

the time it takes(ns) in each requests:
the disk numbers | 10| 500
-
before these patches | 19429 | 667722
after these patches  | 18536 | 627945

2. For the performance
used the dd command likes this to test:
dd if=date_1.dat of=date_2.dat conv=fsync oflag=direct bs=1k count=100k.

the I/O performance is degraded(%) during the monitor:
the disk numbers | 10| 500
-
before these patches | 1.3   | 14.2
after these patches  | 1.0   | 11.3

Dou Liyang (2):
  block/qapi: reduce the coupling between the bdrv_query_stats and
bdrv_query_bds_stats
  block/qapi: reduce the execution time of qmp_query_blockstats

 block/qapi.c | 95 ++--
 1 file changed, 41 insertions(+), 54 deletions(-)







Re: [Qemu-devel] [RFC PATCH 04/17] target/ppc/POWER9: Add ISAv3.00 MMU definition

2017-01-22 Thread Suraj Jitindar Singh
On Tue, 2017-01-17 at 11:33 +1100, Suraj Jitindar Singh wrote:
> On Tue, 2017-01-17 at 08:36 +1100, David Gibson wrote:
> > 
> > On Fri, Jan 13, 2017 at 05:28:10PM +1100, Suraj Jitindar Singh
> > wrote:
> > > 
> > > 
> > > POWER9 processors implement the mmu as defined in version 3.00 of
> > > the ISA.
> > > 
> > > Add a definition for this mmu model and set the POWER9 cpu model
> > > to
> > > use
> > > this mmu model.
> > > 
> > > Signed-off-by: Suraj Jitindar Singh 
> > > ---
> > >  target/ppc/cpu-qom.h| 5 -
> > >  target/ppc/mmu_helper.c | 2 ++
> > >  target/ppc/translate_init.c | 3 +--
> > >  3 files changed, 7 insertions(+), 3 deletions(-)
> > > 
> > > diff --git a/target/ppc/cpu-qom.h b/target/ppc/cpu-qom.h
> > > index d46c31a..1577cc8 100644
> > > --- a/target/ppc/cpu-qom.h
> > > +++ b/target/ppc/cpu-qom.h
> > > @@ -86,10 +86,13 @@ enum powerpc_mmu_t {
> > >  POWERPC_MMU_2_07   = POWERPC_MMU_64 | POWERPC_MMU_1TSEG
> > >   | POWERPC_MMU_64K
> > >   | POWERPC_MMU_AMR | 0x0004,
> > > -/* FIXME Add POWERPC_MMU_3_OO defines */
> > >  /* Architecture 2.07 "degraded" (no 1T
> > > segments)   */
> > >  POWERPC_MMU_2_07a  = POWERPC_MMU_64 | POWERPC_MMU_AMR
> > >   | 0x0004,
> > > +/* Architecture 3.00
> > > variant   */
> > > +POWERPC_MMU_3_00   = POWERPC_MMU_64 | POWERPC_MMU_1TSEG
> > > + | POWERPC_MMU_64K
> > > + | POWERPC_MMU_AMR | 0x0005,
> > Hmm.  I guess it works for now, but I'm not really sure that having
> > this include POWERPC_MMU_64 is a great idea.  The name is kind of
> > misleading, but I'm pretty sure a number of places assume that the
> > POWERPC_MMU_64 bitindicates a 64-bit *hash* MMU, which is no longer
> > really the case.
> Good catch, I didn't realise this assumption was made in the code.
> 
> There are some cases where this bit needs to be set for correct
> behaviour but other places where, while it doesn't break anything, it
> leads to incorrect code being called.
> 
> Time for me to investigate :)
Actually, having looked through the code, I think we want this set. As
far as I can tell it doesn't lead to anything we don't want happening.
> > 
> > 
> > > 
> > > 
> > >  };
> > >  
> > >  /***
> > > **
> > > /
> > > diff --git a/target/ppc/mmu_helper.c b/target/ppc/mmu_helper.c
> > > index d09fc0a..2ab4562 100644
> > > --- a/target/ppc/mmu_helper.c
> > > +++ b/target/ppc/mmu_helper.c
> > > @@ -1935,6 +1935,7 @@ void ppc_tlb_invalidate_all(CPUPPCState
> > > *env)
> > >  case POWERPC_MMU_2_06a:
> > >  case POWERPC_MMU_2_07:
> > >  case POWERPC_MMU_2_07a:
> > > +case POWERPC_MMU_3_00:
> > >  #endif /* defined(TARGET_PPC64) */
> > >  env->tlb_need_flush = 0;
> > >  tlb_flush(CPU(cpu), 1);
> > > @@ -1974,6 +1975,7 @@ void ppc_tlb_invalidate_one(CPUPPCState
> > > *env,
> > > target_ulong addr)
> > >  case POWERPC_MMU_2_06a:
> > >  case POWERPC_MMU_2_07:
> > >  case POWERPC_MMU_2_07a:
> > > +case POWERPC_MMU_3_00:
> > >  /* tlbie invalidate TLBs for all segments */
> > >  /* XXX: given the fact that there are too many segments
> > > to
> > > invalidate,
> > >   *  and we still don't have a tlb_flush_mask(env, n,
> > > mask) in QEMU,
> > > diff --git a/target/ppc/translate_init.c
> > > b/target/ppc/translate_init.c
> > > index bfc1f24..2402eef 100644
> > > --- a/target/ppc/translate_init.c
> > > +++ b/target/ppc/translate_init.c
> > > @@ -8838,8 +8838,7 @@ POWERPC_FAMILY(POWER9)(ObjectClass *oc,
> > > void
> > > *data)
> > >  (1ull << MSR_PMM) |
> > >  (1ull << MSR_RI) |
> > >  (1ull << MSR_LE);
> > > -/* Using 2.07 defines until new radix model is added. */
> > > -pcc->mmu_model = POWERPC_MMU_2_07;
> > > +pcc->mmu_model = POWERPC_MMU_3_00;
> > >  #if defined(CONFIG_SOFTMMU)
> > >  pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;
> > >  /* segment page size remain the same */



Re: [Qemu-devel] [RFC PATCH 05/17] target/ppc/POWER9: Adapt LPCR handling for POWER9

2017-01-22 Thread Suraj Jitindar Singh
On Tue, 2017-01-17 at 15:37 +1100, David Gibson wrote:
> On Tue, Jan 17, 2017 at 11:48:31AM +1100, Suraj Jitindar Singh wrote:
> > 
> > On Tue, 2017-01-17 at 08:40 +1100, David Gibson wrote:
> > > 
> > > On Fri, Jan 13, 2017 at 05:28:11PM +1100, Suraj Jitindar Singh
> > > wrote:
> > > > 
> > > > 
> > > > The logical partitioning control register controls a threads
> > > > operation
> > > > based on the partition it is currently executing. Add new
> > > > definitions and
> > > > update the mask used when writing to the LPCR based on the
> > > > POWER9
> > > > spec.
> > > > 
> > > > Signed-off-by: Suraj Jitindar Singh 
> > > > ---
> > > >  target/ppc/cpu.h| 20 +++-
> > > >  target/ppc/mmu-hash64.c |  8 
> > > >  target/ppc/translate_init.c | 24 ++--
> > > >  3 files changed, 45 insertions(+), 7 deletions(-)
> > > > 
> > > > diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
> > > > index afb7ddb..0ab49b3 100644
> > > > --- a/target/ppc/cpu.h
> > > > +++ b/target/ppc/cpu.h
> > > > @@ -379,15 +379,22 @@ struct ppc_slb_t {
> > > >  #define LPCR_ISL  (1ull << (63 - 2))
> > > >  #define LPCR_KBV  (1ull << (63 - 3))
> > > >  #define LPCR_DPFD_SHIFT   (63 - 11)
> > > > -#define LPCR_DPFD (0x3ull << LPCR_DPFD_SHIFT)
> > > > +#define LPCR_DPFD (0x7ull << LPCR_DPFD_SHIFT)
> > > Changing this define effectively changes the valid LPCR mask for
> > > existing POWER8 and POWER7 models, which is not what you want, I
> > > think.
> > I should have explained this better in the commit message, this has
> > always been a 3 bit field (at least in POWER7-9) so the mask has
> > just
> > always been wrong. Afaik fixing this up won't really change
> > anything -
> > it relates to data stream prefetch depth.
> > 
> > I realise this should probably be a separate patch though, or
> > atleast
> > mentioned in the commit message.
> Right, yes.  Please make the bugfix a separate patch with the
> explanation in the commit message.
> 
> > 
> > > 
> > > 
> > > > 
> > > > 
> > > >  #define LPCR_VRMASD_SHIFT (63 - 16)
> > > >  #define LPCR_VRMASD   (0x1full << LPCR_VRMASD_SHIFT)
> > > > +/* P9: Power-saving mode Exit Cause Enable (Upper Section)
> > > > Mask */
> > > > +#define LPCR_PECE_U_SHIFT (63 - 19)
> > > > +#define LPCR_PECE_U_MASK  (0x7ull << LPCR_PECE_U_SHIFT)
> > > > +#define LPCR_HVEE (1ull << (63 - 17)) /* Hypervisor
> > > > Virt
> > > > Exit Enable */
> > > >  #define LPCR_RMLS_SHIFT   (63 - 37)
> > > >  #define LPCR_RMLS (0xfull << LPCR_RMLS_SHIFT)
> > > >  #define LPCR_ILE  (1ull << (63 - 38))
> > > >  #define LPCR_AIL_SHIFT(63 - 40)  /* Alternate
> > > > interrupt
> > > > location */
> > > >  #define LPCR_AIL  (3ull << LPCR_AIL_SHIFT)
> > > > +#define LPCR_UPRT (1ull << (63 - 41)) /* Use Process
> > > > Table
> > > > */
> > > > +#define LPCR_EVIRT(1ull << (63 - 42)) /* Enhanced
> > > > Virtualisation */
> > > >  #define LPCR_ONL  (1ull << (63 - 45))
> > > > +#define LPCR_LD   (1ull << (63 - 46)) /* Large
> > > > Decrementer
> > > > */
> > > >  #define LPCR_P7_PECE0 (1ull << (63 - 49))
> > > >  #define LPCR_P7_PECE1 (1ull << (63 - 50))
> > > >  #define LPCR_P7_PECE2 (1ull << (63 - 51))
> > > > @@ -396,11 +403,22 @@ struct ppc_slb_t {
> > > >  #define LPCR_P8_PECE2 (1ull << (63 - 49))
> > > >  #define LPCR_P8_PECE3 (1ull << (63 - 50))
> > > >  #define LPCR_P8_PECE4 (1ull << (63 - 51))
> > > > +/* P9: Power-saving mode Exit Cause Enable (Lower Section)
> > > > Mask */
> > > > +#define LPCR_PECE_L_SHIFT (63 - 51)
> > > > +#define LPCR_PECE_L_MASK  (0x1full << LPCR_PECE_L_SHIFT)
> > > > +#define LPCR_PDEE (1ull << (63 - 47)) /* Privileged
> > > > Doorbell Exit EN */
> > > > +#define LPCR_HDEE (1ull << (63 - 48)) /* Hyperv
> > > > Doorbell
> > > > Exit Enable */
> > > > +#define LPCR_EEE  (1ull << (63 - 49)) /* External Exit
> > > > Enable*/
> > > > +#define LPCR_DEE  (1ull << (63 - 50)) /* Decrementer
> > > > Exit
> > > > Enable */
> > > > +#define LPCR_OEE  (1ull << (63 - 51)) /* Other Exit
> > > > Enable   */
> > > >  #define LPCR_MER  (1ull << (63 - 52))
> > > > +#define LPCR_GTSE (1ull << (63 - 53)) /* Guest
> > > > Translation
> > > > Shootdown */
> > > >  #define LPCR_TC   (1ull << (63 - 54))
> > > > +#define LPCR_HEIC (1ull << (63 - 59)) /* HV Extern
> > > > Interrupt Control */
> > > >  #define LPCR_LPES0(1ull << (63 - 60))
> > > >  #define LPCR_LPES1(1ull << (63 - 61))
> > > >  #define LPCR_RMI  (1ull << (63 - 62))
> > > > +#define LPCR_HVICE(1ull << (63 - 62)) /* HV
> > > > Virtualisation
> > > > Int Enable */
> > > >  #define LPCR_HDICE(1ull << (63 - 63))
> > > >  
> > > >  #define msr_sf   ((env->msr >> MSR_SF)   & 1)
> > > > diff --git a/target/ppc/mmu-hash64.c 

Re: [Qemu-devel] Towards an ivshmem 2.0?

2017-01-22 Thread Wang, Wei W
On Saturday, January 21, 2017 12:38 AM, Jan Kiszka wrote:
> On 2017-01-20 12:54, Wang, Wei W wrote:
> > On Tuesday, January 17, 2017 5:46 PM, Jan Kiszka wrote:
> >> On 2017-01-17 10:13, Wang, Wei W wrote:
> >>> Hi Jan,
> >>>
> >>> On Monday, January 16, 2017 9:10 PM, Jan Kiszka wrote:
>  On 2017-01-16 13:41, Marc-André Lureau wrote:
> > On Mon, Jan 16, 2017 at 12:37 PM Jan Kiszka
> > > wrote:
> > some of you may know that we are using a shared memory device
> > similar
> >> to
> > ivshmem in the partitioning hypervisor Jailhouse [1].
> >
> > We started as being compatible to the original ivshmem that QEMU
> > implements, but we quickly deviated in some details, and in the 
> > recent
> > months even more. Some of the deviations are related to making the
> > implementation simpler. The new ivshmem takes <500 LoC - Jailhouse
> is
> > aiming at safety critical systems and, therefore, a small code base.
> > Other changes address deficits in the original design, like missing
> > life-cycle management.
> >
> > Now the question is if there is interest in defining a common new
> > revision of this device and maybe also of some protocols used on 
> > top,
> > such as virtual network links. Ideally, this would enable us to 
> > share
> > Linux drivers. We will definitely go for upstreaming at least a 
> > network
> > driver such as [2], a UIO driver and maybe also a serial 
> > port/console.
> >
> >
> > This sounds like duplicating efforts done with virtio and vhost-pci.
> > Have you looked at Wei Wang proposal?
> 
>  I didn't follow it recently, but the original concept was about
>  introducing an IOMMU model to the picture, and that's
>  complexity-wise a no-go for us (we can do this whole thing in less
>  than 500 lines, even virtio itself is more complex). IIUC, the
>  alternative to an IOMMU is mapping the whole frontend VM memory
>  into the backend VM -
> >> that's security/safety-wise an absolute no-go.
> >>>
> >>> Though the virtio based solution might be complex for you, a big
> >>> advantage is
> >> that we have lots of people working to improve virtio. For example,
> >> the upcoming virtio 1.1 has vring improvement, we can easily upgrade
> >> all the virtio based solutions, such as vhost-pci, to take advantage
> >> of this improvement. From the long term perspective, I think this kind of
> complexity is worthwhile.
> >>
> >> We will adopt virtio 1.1 ring formats. That's one reason why there is
> >> also still a bidirectional shared memory region: to host the new
> >> descriptors (while keeping the payload safely in the unidirectional 
> >> regions).
> >
> > The vring example I gave might be confusing, sorry about  that. My point is
> that every part of virtio is getting matured and improved from time to time.
> Personally, having a new device developed and maintained in an active and
> popular model is helpful. Also, as new features being gradually added in the
> future, a simple device could become complex.
> 
> We can't afford becoming more complex, that is the whole point.
> Complexity shall go into the guest, not the hypervisor, when it is really 
> needed.
> 
> >
> > Having a theoretical analysis on the performance:
> > The traditional shared memory mechanism, sharing an intermediate memory,
> requires 2 copies to get the packet transmitted. It's not just one more copy
> compared to the 1-copy solution, I think some more things we may need to take
> into account:
> 
> 1-copy (+potential transfers to userspace, but that's the same for
> everyone) is conceptually possible, definitely under stacks like DPDK.
> However, Linux skbs are currently not prepared for picking up shmem-backed
> packets, we already looked into this. Likely addressable, though.

Not sure how difficult it would be to get that change upstream-ed to the 
kernel, but looking forward to seeing your solutions.
 
> > 1) there are extra ring operation overhead  on both the sending and
> > receiving side to access the shared memory (i.e. IVSHMEM);
> > 2) extra protocol to use the shared memory;
> > 3) the piece of allocated shared memory from the host = C(n,2), where n is 
> > the
> number of VMs. Like for 20 VMs who want to talk to each other, there will be
> 190 pieces of memory allocated from the host.
> 
> Well, only if all VMs need to talk to all others directly. On real setups, 
> you would
> add direct links for heavy traffic and otherwise do software switching. 
> Moreover,
> those links would only have to be backed by physical memory in static setups 
> all
> the time.
> 
> Also, we didn't completely rule out a shmem bus with multiple peers connected.
> That's just looking for a strong use case - and then a robust design, of 
> course.
> 
> >
> > That being said, if people 

Re: [Qemu-devel] [PATCH RFC v4 18/20] intel_iommu: enable vfio devices

2017-01-22 Thread Peter Xu
On Mon, Jan 23, 2017 at 10:01:11AM +0800, Jason Wang wrote:
> 
> 
> On 2017年01月20日 21:08, Peter Xu wrote:
> >This patch is based on Aviv Ben-David ()'s patch
> >upstream:
> >
> >   "IOMMU: enable intel_iommu map and unmap notifiers"
> >   https://lists.gnu.org/archive/html/qemu-devel/2016-11/msg01453.html
> >
> >However I removed/fixed some content, and added my own codes.
> >
> >Instead of translate() every page for iotlb invalidations (which is
> >slower), we walk the pages when needed and notify in a hook function.
> >
> >This patch enables vfio devices for VT-d emulation.
> >
> >Signed-off-by: Peter Xu
> >---
> >  hw/i386/intel_iommu.c | 66 
> > +--
> >  include/hw/i386/intel_iommu.h |  8 ++
> >  2 files changed, 65 insertions(+), 9 deletions(-)
> 
> A good side effect of this patch is that it makes vhost device IOTLB works
> without ATS (though may be slow). We probably need a better title :)

How about I mention it in the commit message at the end? Like:

"And, since we already have vhost DMAR support via device-iotlb, a
 natural benefit that this patch brings is that vt-d enabled vhost can
 live even without ATS capability now. Though more tests are needed."

> 
> And I think we should block notifiers during PSI/DSI/GLOBAL for device with
> ATS enabled.

Again, would that be okay I note this in my todo list? :)

Thanks,

-- peterx



Re: [Qemu-devel] [PATCH RFC v4 15/20] intel_iommu: provide its own replay() callback

2017-01-22 Thread Peter Xu
On Mon, Jan 23, 2017 at 11:12:27AM +0800, Jason Wang wrote:
> 
> 
> On 2017年01月23日 10:54, Peter Xu wrote:
> >+trace_vtd_page_walk_skip_read(iova, iova_next);
> >+skipped_local++;
> >+goto next;
> >+}
> >+
> >+if (vtd_slpte_nonzero_rsvd(slpte, level)) {
> >+trace_vtd_page_walk_skip_reserve(iova, iova_next);
> >+skipped_local++;
> >+goto next;
> >+}
> >+
> >+/* Permissions are stacked with parents' */
> >+read_cur = read && (slpte & VTD_SL_R);
> >+write_cur = write && (slpte & VTD_SL_W);
> >+
> >+/*
> >+ * As long as we have either read/write permission, this is
> >+ * a valid entry. The rule works for both page or page tables.
> >+ */
> >+entry_valid = read_cur | write_cur;
> >+
> >+if (vtd_is_last_slpte(slpte, level)) {
> >+entry.target_as = _space_memory;
> >+entry.iova = iova & subpage_mask;
> >+/*
> >+ * This might be meaningless addr if (!read_cur &&
> >+ * !write_cur), but after all this field will be
> >+ * meaningless in that case, so let's share the code to
> >+ * generate the IOTLBs no matter it's an MAP or UNMAP
> >+ */
> >+entry.translated_addr = vtd_get_slpte_addr(slpte);
> >+entry.addr_mask = ~subpage_mask;
> >+entry.perm = IOMMU_ACCESS_FLAG(read_cur, write_cur);
> >+if (!entry_valid && !notify_unmap) {
> >+trace_vtd_page_walk_skip_perm(iova, iova_next);
> >+skipped_local++;
> >+goto next;
> >+}
> Under which case should we care about unmap here (better with a comment I
> think)?
> >>>When PSIs are for invalidation, rather than newly mapped entries. In
> >>>that case, notify_unmap will be true, and here we need to notify
> >>>IOMMU_NONE to do the cache flush or unmap.
> >>>
> >>>(this page walk is not only for replaying, it is for cache flushing as
> >>>  well)
> >>>
> >>>Do you have suggestion on the comments?
> >>I think then we'd better move this to patch 18 which will use notify_unmap.
> >Do you mean to add some more comment on patch 18?
> >
> 
> I mean move the unmap_nofity and its comment to patch 18 (real user). But if
> you want to keep it in the patch, I'm also fine.

(Since we discussed in IRC for this :)

So I'll keep it for this time. Thanks,

-- peterx



Re: [Qemu-devel] [PATCH RFC v4 18/20] intel_iommu: enable vfio devices

2017-01-22 Thread Peter Xu
On Mon, Jan 23, 2017 at 09:55:39AM +0800, Jason Wang wrote:
> 
> 
> On 2017年01月22日 17:04, Peter Xu wrote:
> >On Sun, Jan 22, 2017 at 04:08:04PM +0800, Jason Wang wrote:
> >
> >[...]
> >
> >>>+static void vtd_iotlb_page_invalidate_notify(IntelIOMMUState *s,
> >>>+   uint16_t domain_id, hwaddr 
> >>>addr,
> >>>+   uint8_t am)
> >>>+{
> >>>+IntelIOMMUNotifierNode *node;
> >>>+VTDContextEntry ce;
> >>>+int ret;
> >>>+
> >>>+QLIST_FOREACH(node, &(s->notifiers_list), next) {
> >>>+VTDAddressSpace *vtd_as = node->vtd_as;
> >>>+ret = vtd_dev_to_context_entry(s, pci_bus_num(vtd_as->bus),
> >>>+   vtd_as->devfn, );
> >>>+if (!ret && domain_id == VTD_CONTEXT_ENTRY_DID(ce.hi)) {
> >>>+vtd_page_walk(, addr, addr + (1 << am) * VTD_PAGE_SIZE,
> >>>+  vtd_page_invalidate_notify_hook,
> >>>+  (void *)_as->iommu, true);
> >>Why not simply trigger the notifier here? (or is this vfio required?)
> >Because we may only want to notify part of the region - we are with
> >mask here, but not exact size.
> >
> >Consider this: guest (with caching mode) maps 12K memory (4K*3 pages),
> >the mask will be extended to 16K in the guest. In that case, we need
> >to explicitly go over the page entry to know that the 4th page should
> >not be notified.
> 
> I see. Then it was required by vfio only, I think we can add a fast path for
> !CM in this case by triggering the notifier directly.

I noted this down (to be further investigated in my todo), but I don't
know whether this can work, due to the fact that I think it is still
legal that guest merge more than one PSIs into one. For example, I
don't know whether below is legal:

- guest invalidate page (0, 4k)
- guest map new page (4k, 8k)
- guest send single PSI of (0, 8k)

In that case, it contains both map/unmap, and looks like it didn't
disobay the spec as well?

> 
> Another possible issue is, consider (with CM) a 16K contiguous iova with the
> last page has already been mapped. In this case, if we want to map first
> three pages, when handling IOTLB invalidation, am would be 16K, then the
> last page will be mapped twice. Can this lead some issue?

I don't know whether guest has special handling of this kind of
request.

Besides, imho to completely solve this problem, we still need that
per-domain tree. Considering that currently the tree is inside vfio, I
see this not a big issue as well. In that case, the last page mapping
request will fail (we might see one error line from QEMU stderr),
however that'll not affect too much since currently vfio allows that
failure to happen (ioctl fail, but that page is still mapped, which is
what we wanted).

(But of course above error message can be used by an in-guest attacker
 as well just like general error_report() issues reported before,
 though again I will appreciate if we can have this series
 functionally work first :)

And, I should be able to emulate this behavior in guest with a tiny C
program to make sure of it, possibly after this series if allowed.

Thanks,

-- peterx



Re: [Qemu-devel] [PATCH RFC v4 15/20] intel_iommu: provide its own replay() callback

2017-01-22 Thread Jason Wang



On 2017年01月23日 10:54, Peter Xu wrote:

+trace_vtd_page_walk_skip_read(iova, iova_next);
+skipped_local++;
+goto next;
+}
+
+if (vtd_slpte_nonzero_rsvd(slpte, level)) {
+trace_vtd_page_walk_skip_reserve(iova, iova_next);
+skipped_local++;
+goto next;
+}
+
+/* Permissions are stacked with parents' */
+read_cur = read && (slpte & VTD_SL_R);
+write_cur = write && (slpte & VTD_SL_W);
+
+/*
+ * As long as we have either read/write permission, this is
+ * a valid entry. The rule works for both page or page tables.
+ */
+entry_valid = read_cur | write_cur;
+
+if (vtd_is_last_slpte(slpte, level)) {
+entry.target_as = _space_memory;
+entry.iova = iova & subpage_mask;
+/*
+ * This might be meaningless addr if (!read_cur &&
+ * !write_cur), but after all this field will be
+ * meaningless in that case, so let's share the code to
+ * generate the IOTLBs no matter it's an MAP or UNMAP
+ */
+entry.translated_addr = vtd_get_slpte_addr(slpte);
+entry.addr_mask = ~subpage_mask;
+entry.perm = IOMMU_ACCESS_FLAG(read_cur, write_cur);
+if (!entry_valid && !notify_unmap) {
+trace_vtd_page_walk_skip_perm(iova, iova_next);
+skipped_local++;
+goto next;
+}

Under which case should we care about unmap here (better with a comment I
think)?

When PSIs are for invalidation, rather than newly mapped entries. In
that case, notify_unmap will be true, and here we need to notify
IOMMU_NONE to do the cache flush or unmap.

(this page walk is not only for replaying, it is for cache flushing as
  well)

Do you have suggestion on the comments?

I think then we'd better move this to patch 18 which will use notify_unmap.

Do you mean to add some more comment on patch 18?



I mean move the unmap_nofity and its comment to patch 18 (real user). 
But if you want to keep it in the patch, I'm also fine.


Thanks



Re: [Qemu-devel] [PATCH RFC v4 15/20] intel_iommu: provide its own replay() callback

2017-01-22 Thread Peter Xu
On Mon, Jan 23, 2017 at 09:48:48AM +0800, Jason Wang wrote:
> 
> 
> On 2017年01月22日 16:51, Peter Xu wrote:
> >On Sun, Jan 22, 2017 at 03:56:10PM +0800, Jason Wang wrote:
> >
> >[...]
> >
> >>>+/**
> >>>+ * vtd_page_walk_level - walk over specific level for IOVA range
> >>>+ *
> >>>+ * @addr: base GPA addr to start the walk
> >>>+ * @start: IOVA range start address
> >>>+ * @end: IOVA range end address (start <= addr < end)
> >>>+ * @hook_fn: hook func to be called when detected page
> >>>+ * @private: private data to be passed into hook func
> >>>+ * @read: whether parent level has read permission
> >>>+ * @write: whether parent level has write permission
> >>>+ * @skipped: accumulated skipped ranges
> >>What's the usage for this parameter? Looks like it was never used in this
> >>series.
> >This was for debugging purpose before, and I kept it in case one day
> >it can be used again, considering that will not affect much on the
> >overall performance.
> 
> I think we usually do not keep debugging codes outside debug macros.

I'll remove it.

> 
> >
> >>>+ * @notify_unmap: whether we should notify invalid entries
> >>>+ */
> >>>+static int vtd_page_walk_level(dma_addr_t addr, uint64_t start,
> >>>+   uint64_t end, vtd_page_walk_hook hook_fn,
> >>>+   void *private, uint32_t level,
> >>>+   bool read, bool write, uint64_t *skipped,
> >>>+   bool notify_unmap)
> >>>+{
> >>>+bool read_cur, write_cur, entry_valid;
> >>>+uint32_t offset;
> >>>+uint64_t slpte;
> >>>+uint64_t subpage_size, subpage_mask;
> >>>+IOMMUTLBEntry entry;
> >>>+uint64_t iova = start;
> >>>+uint64_t iova_next;
> >>>+uint64_t skipped_local = 0;
> >>>+int ret = 0;
> >>>+
> >>>+trace_vtd_page_walk_level(addr, level, start, end);
> >>>+
> >>>+subpage_size = 1ULL << vtd_slpt_level_shift(level);
> >>>+subpage_mask = vtd_slpt_level_page_mask(level);
> >>>+
> >>>+while (iova < end) {
> >>>+iova_next = (iova & subpage_mask) + subpage_size;
> >>>+
> >>>+offset = vtd_iova_level_offset(iova, level);
> >>>+slpte = vtd_get_slpte(addr, offset);
> >>>+
> >>>+/*
> >>>+ * When one of the following case happens, we assume the whole
> >>>+ * range is invalid:
> >>>+ *
> >>>+ * 1. read block failed
> >>Don't get the meaning (and don't see any code relate to this comment).
> >I took above vtd_get_slpte() a "read", so I was trying to mean that we
> >failed to read the SLPTE due to some reason, we assume the range is
> >invalid.
> 
> I see, so we'd better move the comment above of vtd_get_slpte().

Let me remove the whole comment block... I think the codes explained
it clearly even without any comment. (when people see the code check
slpte against -1, it'll think about above function naturally)

> 
> >
> >>>+ * 3. reserved area non-zero
> >>>+ * 2. both read & write flag are not set
> >>Should be 1,2,3? And the above comment is conflict with the code at least
> >>when notify_unmap is true.
> >Yes, okay I don't know why 3 jumped. :(
> >
> >And yes, I should mention that "both read & write flag not set" only
> >suites for page tables here.
> >
> >>>+ */
> >>>+
> >>>+if (slpte == (uint64_t)-1) {
> >>If this is true, vtd_slpte_nonzero_rsvd(slpte) should be true too I think?
> >Yes, but we are doing two checks here:
> >
> >- checking against -1 to make sure slpte read success
> >- checking against nonzero reserved fields to make sure it follows spec
> >
> >Imho we should not skip the first check here, only if one day removing
> >this may really matter (e.g., for performance reason? I cannot think
> >of one yet).
> 
> Ok. (return -1 seems not good, but we can address this in the future).

Thanks.

> 
> >
> >>>+trace_vtd_page_walk_skip_read(iova, iova_next);
> >>>+skipped_local++;
> >>>+goto next;
> >>>+}
> >>>+
> >>>+if (vtd_slpte_nonzero_rsvd(slpte, level)) {
> >>>+trace_vtd_page_walk_skip_reserve(iova, iova_next);
> >>>+skipped_local++;
> >>>+goto next;
> >>>+}
> >>>+
> >>>+/* Permissions are stacked with parents' */
> >>>+read_cur = read && (slpte & VTD_SL_R);
> >>>+write_cur = write && (slpte & VTD_SL_W);
> >>>+
> >>>+/*
> >>>+ * As long as we have either read/write permission, this is
> >>>+ * a valid entry. The rule works for both page or page tables.
> >>>+ */
> >>>+entry_valid = read_cur | write_cur;
> >>>+
> >>>+if (vtd_is_last_slpte(slpte, level)) {
> >>>+entry.target_as = _space_memory;
> >>>+entry.iova = iova & subpage_mask;
> >>>+/*
> >>>+ * This might be meaningless addr if (!read_cur &&
> >>>+ * !write_cur), but after all this field will be
> >>>+ * meaningless in 

[Qemu-devel] [PULL 23/26] target-hppa: Implement shifts and deposits

2017-01-22 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/hppa/translate.c | 309 
 1 file changed, 309 insertions(+)

diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 14fe4bb..093a65e 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -1719,6 +1719,311 @@ static ExitStatus trans_movb(DisasContext *ctx, 
uint32_t insn, bool is_imm)
 return do_cbranch(ctx, disp, n, );
 }
 
+static ExitStatus trans_shrpw_sar(DisasContext *ctx, uint32_t insn,
+ const DisasInsn *di)
+{
+unsigned rt = extract32(insn, 0, 5);
+unsigned c = extract32(insn, 13, 3);
+unsigned r1 = extract32(insn, 16, 5);
+unsigned r2 = extract32(insn, 21, 5);
+TCGv dest;
+
+if (c) {
+nullify_over(ctx);
+}
+
+dest = dest_gpr(ctx, rt);
+if (r1 == 0) {
+tcg_gen_ext32u_tl(dest, load_gpr(ctx, r2));
+tcg_gen_shr_tl(dest, dest, cpu_sar);
+} else if (r1 == r2) {
+TCGv_i32 t32 = tcg_temp_new_i32();
+tcg_gen_trunc_tl_i32(t32, load_gpr(ctx, r2));
+tcg_gen_rotr_i32(t32, t32, cpu_sar);
+tcg_gen_extu_i32_tl(dest, t32);
+tcg_temp_free_i32(t32);
+} else {
+TCGv_i64 t = tcg_temp_new_i64();
+TCGv_i64 s = tcg_temp_new_i64();
+
+tcg_gen_concat_tl_i64(t, load_gpr(ctx, r2), load_gpr(ctx, r1));
+tcg_gen_extu_tl_i64(s, cpu_sar);
+tcg_gen_shr_i64(t, t, s);
+tcg_gen_trunc_i64_tl(dest, t);
+
+tcg_temp_free_i64(t);
+tcg_temp_free_i64(s);
+}
+save_gpr(ctx, rt, dest);
+
+/* Install the new nullification.  */
+cond_free(>null_cond);
+if (c) {
+ctx->null_cond = do_sed_cond(c, dest);
+}
+return nullify_end(ctx, NO_EXIT);
+}
+
+static ExitStatus trans_shrpw_imm(DisasContext *ctx, uint32_t insn,
+  const DisasInsn *di)
+{
+unsigned rt = extract32(insn, 0, 5);
+unsigned cpos = extract32(insn, 5, 5);
+unsigned c = extract32(insn, 13, 3);
+unsigned r1 = extract32(insn, 16, 5);
+unsigned r2 = extract32(insn, 21, 5);
+unsigned sa = 31 - cpos;
+TCGv dest, t2;
+
+if (c) {
+nullify_over(ctx);
+}
+
+dest = dest_gpr(ctx, rt);
+t2 = load_gpr(ctx, r2);
+if (r1 == r2) {
+TCGv_i32 t32 = tcg_temp_new_i32();
+tcg_gen_trunc_tl_i32(t32, t2);
+tcg_gen_rotri_i32(t32, t32, sa);
+tcg_gen_extu_i32_tl(dest, t32);
+tcg_temp_free_i32(t32);
+} else if (r1 == 0) {
+tcg_gen_extract_tl(dest, t2, sa, 32 - sa);
+} else {
+TCGv t0 = tcg_temp_new();
+tcg_gen_extract_tl(t0, t2, sa, 32 - sa);
+tcg_gen_deposit_tl(dest, t0, cpu_gr[r1], 32 - sa, sa);
+tcg_temp_free(t0);
+}
+save_gpr(ctx, rt, dest);
+
+/* Install the new nullification.  */
+cond_free(>null_cond);
+if (c) {
+ctx->null_cond = do_sed_cond(c, dest);
+}
+return nullify_end(ctx, NO_EXIT);
+}
+
+static ExitStatus trans_extrw_sar(DisasContext *ctx, uint32_t insn,
+  const DisasInsn *di)
+{
+unsigned clen = extract32(insn, 0, 5);
+unsigned is_se = extract32(insn, 10, 1);
+unsigned c = extract32(insn, 13, 3);
+unsigned rt = extract32(insn, 16, 5);
+unsigned rr = extract32(insn, 21, 5);
+unsigned len = 32 - clen;
+TCGv dest, src, tmp;
+
+if (c) {
+nullify_over(ctx);
+}
+
+dest = dest_gpr(ctx, rt);
+src = load_gpr(ctx, rr);
+tmp = tcg_temp_new();
+
+/* Recall that SAR is using big-endian bit numbering.  */
+tcg_gen_xori_tl(tmp, cpu_sar, TARGET_LONG_BITS - 1);
+if (is_se) {
+tcg_gen_sar_tl(dest, src, tmp);
+tcg_gen_sextract_tl(dest, dest, 0, len);
+} else {
+tcg_gen_shr_tl(dest, src, tmp);
+tcg_gen_extract_tl(dest, dest, 0, len);
+}
+tcg_temp_free(tmp);
+save_gpr(ctx, rt, dest);
+
+/* Install the new nullification.  */
+cond_free(>null_cond);
+if (c) {
+ctx->null_cond = do_sed_cond(c, dest);
+}
+return nullify_end(ctx, NO_EXIT);
+}
+
+static ExitStatus trans_extrw_imm(DisasContext *ctx, uint32_t insn,
+  const DisasInsn *di)
+{
+unsigned clen = extract32(insn, 0, 5);
+unsigned pos = extract32(insn, 5, 5);
+unsigned is_se = extract32(insn, 10, 1);
+unsigned c = extract32(insn, 13, 3);
+unsigned rt = extract32(insn, 16, 5);
+unsigned rr = extract32(insn, 21, 5);
+unsigned len = 32 - clen;
+unsigned cpos = 31 - pos;
+TCGv dest, src;
+
+if (c) {
+nullify_over(ctx);
+}
+
+dest = dest_gpr(ctx, rt);
+src = load_gpr(ctx, rr);
+if (is_se) {
+tcg_gen_sextract_tl(dest, src, cpos, len);
+} else {
+tcg_gen_extract_tl(dest, src, cpos, len);
+}
+save_gpr(ctx, rt, dest);
+
+/* Install the new nullification.  */
+cond_free(>null_cond);
+if 

[Qemu-devel] [PULL 21/26] target-hppa: Implement branches

2017-01-22 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/hppa/translate.c | 477 
 1 file changed, 477 insertions(+)

diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 2ad651c..1d0976f 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -455,6 +455,14 @@ static target_long low_sextract(uint32_t val, int pos, int 
len)
 return x;
 }
 
+static target_long assemble_12(uint32_t insn)
+{
+target_ulong x = -(target_ulong)(insn & 1);
+x = (x <<  1) | extract32(insn, 2, 1);
+x = (x << 10) | extract32(insn, 3, 10);
+return x;
+}
+
 static target_long assemble_16(uint32_t insn)
 {
 /* Take the name from PA2.0, which produces a 16-bit number
@@ -463,6 +471,15 @@ static target_long assemble_16(uint32_t insn)
 return low_sextract(insn, 0, 14);
 }
 
+static target_long assemble_17(uint32_t insn)
+{
+target_ulong x = -(target_ulong)(insn & 1);
+x = (x <<  5) | extract32(insn, 16, 5);
+x = (x <<  1) | extract32(insn, 2, 1);
+x = (x << 10) | extract32(insn, 3, 10);
+return x << 2;
+}
+
 static target_long assemble_21(uint32_t insn)
 {
 target_ulong x = -(target_ulong)(insn & 1);
@@ -473,6 +490,15 @@ static target_long assemble_21(uint32_t insn)
 return x << 11;
 }
 
+static target_long assemble_22(uint32_t insn)
+{
+target_ulong x = -(target_ulong)(insn & 1);
+x = (x << 10) | extract32(insn, 16, 10);
+x = (x <<  1) | extract32(insn, 2, 1);
+x = (x << 10) | extract32(insn, 3, 10);
+return x << 2;
+}
+
 /* The parisc documentation describes only the general interpretation of
the conditions, without describing their exact implementation.  The
interpretations do not stand up well when considering ADD,C and SUB,B.
@@ -574,6 +600,24 @@ static DisasCond do_log_cond(unsigned cf, TCGv res)
 return do_cond(cf, res, res, res);
 }
 
+/* Similar, but for shift/extract/deposit conditions.  */
+
+static DisasCond do_sed_cond(unsigned orig, TCGv res)
+{
+unsigned c, f;
+
+/* Convert the compressed condition codes to standard.
+   0-2 are the same as logicals (nv,<,<=), while 3 is OD.
+   4-7 are the reverse of 0-3.  */
+c = orig & 3;
+if (c == 3) {
+c = 7;
+}
+f = (orig & 4) / 4;
+
+return do_log_cond(c * 2 + f, res);
+}
+
 /* Similar, but for unit conditions.  */
 
 static DisasCond do_unit_cond(unsigned cf, TCGv res, TCGv in1, TCGv in2)
@@ -897,6 +941,188 @@ static ExitStatus do_unit(DisasContext *ctx, unsigned rt, 
TCGv in1,
 return NO_EXIT;
 }
 
+/* Emit an unconditional branch to a direct target, which may or may not
+   have already had nullification handled.  */
+static ExitStatus do_dbranch(DisasContext *ctx, target_ulong dest,
+ unsigned link, bool is_n)
+{
+if (ctx->null_cond.c == TCG_COND_NEVER && ctx->null_lab == NULL) {
+if (link != 0) {
+copy_iaoq_entry(cpu_gr[link], ctx->iaoq_n, ctx->iaoq_n_var);
+}
+ctx->iaoq_n = dest;
+if (is_n) {
+ctx->null_cond.c = TCG_COND_ALWAYS;
+}
+return NO_EXIT;
+} else {
+nullify_over(ctx);
+
+if (link != 0) {
+copy_iaoq_entry(cpu_gr[link], ctx->iaoq_n, ctx->iaoq_n_var);
+}
+
+if (is_n && use_nullify_skip(ctx)) {
+nullify_set(ctx, 0);
+gen_goto_tb(ctx, 0, dest, dest + 4);
+} else {
+nullify_set(ctx, is_n);
+gen_goto_tb(ctx, 0, ctx->iaoq_b, dest);
+}
+
+nullify_end(ctx, NO_EXIT);
+
+nullify_set(ctx, 0);
+gen_goto_tb(ctx, 1, ctx->iaoq_b, ctx->iaoq_n);
+return EXIT_GOTO_TB;
+}
+}
+
+/* Emit a conditional branch to a direct target.  If the branch itself
+   is nullified, we should have already used nullify_over.  */
+static ExitStatus do_cbranch(DisasContext *ctx, target_long disp, bool is_n,
+ DisasCond *cond)
+{
+target_ulong dest = iaoq_dest(ctx, disp);
+TCGLabel *taken = NULL;
+TCGCond c = cond->c;
+int which = 0;
+bool n;
+
+assert(ctx->null_cond.c == TCG_COND_NEVER);
+
+/* Handle TRUE and NEVER as direct branches.  */
+if (c == TCG_COND_ALWAYS) {
+return do_dbranch(ctx, dest, 0, is_n && disp >= 0);
+}
+if (c == TCG_COND_NEVER) {
+return do_dbranch(ctx, ctx->iaoq_n, 0, is_n && disp < 0);
+}
+
+taken = gen_new_label();
+cond_prep(cond);
+tcg_gen_brcond_tl(c, cond->a0, cond->a1, taken);
+cond_free(cond);
+
+/* Not taken: Condition not satisfied; nullify on backward branches. */
+n = is_n && disp < 0;
+if (n && use_nullify_skip(ctx)) {
+nullify_set(ctx, 0);
+gen_goto_tb(ctx, which++, ctx->iaoq_n, ctx->iaoq_n + 4);
+} else {
+if (!n && ctx->null_lab) {
+gen_set_label(ctx->null_lab);
+ctx->null_lab = NULL;
+}
+nullify_set(ctx, n);
+

[Qemu-devel] [PATCH] util/envlist: Fix 2 bugs in envlist_setenv and envlist_unsetenv

2017-01-22 Thread Hu Chaojian
From: chaojianhu 

In envlist_setenv, if any malloc fails, there will be inconsistency on el_count.

And in envlist_unsetenv, if env is "", the strncmp will be passed, eventually 
wrong envlist_entry (shoud be the first one) will be removed.

Finally, in envlist_parse, to delimit environments with ',' is wrong, since 
value
may contain ','. I suggest delete envlist_parse from the source code.

Reported-by: chaojianhu 
Signed-off-by: chaojianhu 

---
 util/envlist.c | 12 
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/util/envlist.c b/util/envlist.c
index e86857e..5d68a6a 100644
--- a/util/envlist.c
+++ b/util/envlist.c
@@ -157,9 +157,8 @@ envlist_setenv(envlist_t *envlist, const char *env)
QLIST_REMOVE(entry, ev_link);
free((char *)entry->ev_var);
free(entry);
-   } else {
-   envlist->el_count++;
-   }
+envlist->el_count--;
+}
 
if ((entry = malloc(sizeof (*entry))) == NULL)
return (errno);
@@ -168,6 +167,7 @@ envlist_setenv(envlist_t *envlist, const char *env)
return (errno);
}
QLIST_INSERT_HEAD(>el_entries, entry, ev_link);
+envlist->el_count++;
 
return (0);
 }
@@ -185,6 +185,11 @@ envlist_unsetenv(envlist_t *envlist, const char *env)
if ((envlist == NULL) || (env == NULL))
return (EINVAL);
 
+envname_len = strlen(env);
+if (0 == envname_len) {
+return -EINVAL;
+}
+
/* env is not allowed to contain '=' */
if (strchr(env, '=') != NULL)
return (EINVAL);
@@ -193,7 +198,6 @@ envlist_unsetenv(envlist_t *envlist, const char *env)
 * Find out the requested entry and remove
 * it from the list.
 */
-   envname_len = strlen(env);
for (entry = envlist->el_entries.lh_first; entry != NULL;
entry = entry->ev_link.le_next) {
if (strncmp(entry->ev_var, env, envname_len) == 0)
-- 
1.9.1




[Qemu-devel] [PULL 24/26] target-hppa: Implement loads and stores

2017-01-22 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/hppa/helper.h|   3 +
 target/hppa/op_helper.c |  78 ++
 target/hppa/translate.c | 618 
 3 files changed, 699 insertions(+)

diff --git a/target/hppa/helper.h b/target/hppa/helper.h
index ecff17c..88db719 100644
--- a/target/hppa/helper.h
+++ b/target/hppa/helper.h
@@ -2,4 +2,7 @@ DEF_HELPER_2(excp, noreturn, env, int)
 DEF_HELPER_FLAGS_2(tsv, TCG_CALL_NO_WG, void, env, tl)
 DEF_HELPER_FLAGS_2(tcond, TCG_CALL_NO_WG, void, env, tl)
 
+DEF_HELPER_FLAGS_3(stby_b, TCG_CALL_NO_WG, void, env, tl, tl)
+DEF_HELPER_FLAGS_3(stby_e, TCG_CALL_NO_WG, void, env, tl, tl)
+
 DEF_HELPER_FLAGS_1(loaded_fr0, TCG_CALL_NO_RWG, void, env)
diff --git a/target/hppa/op_helper.c b/target/hppa/op_helper.c
index f36ce74..0aa5fb9 100644
--- a/target/hppa/op_helper.c
+++ b/target/hppa/op_helper.c
@@ -21,6 +21,7 @@
 #include "cpu.h"
 #include "exec/exec-all.h"
 #include "exec/helper-proto.h"
+#include "exec/cpu_ldst.h"
 
 void QEMU_NORETURN HELPER(excp)(CPUHPPAState *env, int excp)
 {
@@ -54,6 +55,83 @@ void HELPER(tcond)(CPUHPPAState *env, target_ulong cond)
 }
 }
 
+static void atomic_store_3(CPUHPPAState *env, target_ulong addr, uint32_t val,
+   uint32_t mask, uintptr_t ra)
+{
+uint32_t old, new, cmp;
+
+#ifdef CONFIG_USER_ONLY
+uint32_t *haddr = g2h(addr - 1);
+old = *haddr;
+while (1) {
+new = (old & ~mask) | (val & mask);
+cmp = atomic_cmpxchg(haddr, old, new);
+if (cmp == old) {
+return;
+}
+old = cmp;
+}
+#else
+#error "Not implemented."
+#endif
+}
+
+void HELPER(stby_b)(CPUHPPAState *env, target_ulong addr, target_ulong val)
+{
+uintptr_t ra = GETPC();
+
+switch (addr & 3) {
+case 3:
+cpu_stb_data_ra(env, addr, val, ra);
+break;
+case 2:
+cpu_stw_data_ra(env, addr, val, ra);
+break;
+case 1:
+/* The 3 byte store must appear atomic.  */
+if (parallel_cpus) {
+atomic_store_3(env, addr, val, 0x00ffu, ra);
+} else {
+cpu_stb_data_ra(env, addr, val >> 16, ra);
+cpu_stw_data_ra(env, addr + 1, val, ra);
+}
+break;
+default:
+cpu_stl_data_ra(env, addr, val, ra);
+break;
+}
+}
+
+void HELPER(stby_e)(CPUHPPAState *env, target_ulong addr, target_ulong val)
+{
+uintptr_t ra = GETPC();
+
+switch (addr & 3) {
+case 3:
+/* The 3 byte store must appear atomic.  */
+if (parallel_cpus) {
+atomic_store_3(env, addr - 3, val, 0xff00u, ra);
+} else {
+cpu_stw_data_ra(env, addr - 3, val >> 16, ra);
+cpu_stb_data_ra(env, addr - 1, val >> 8, ra);
+}
+break;
+case 2:
+cpu_stw_data_ra(env, addr - 2, val >> 16, ra);
+break;
+case 1:
+cpu_stb_data_ra(env, addr - 1, val >> 24, ra);
+break;
+default:
+/* Nothing is stored, but protection is checked and the
+   cacheline is marked dirty.  */
+#ifndef CONFIG_USER_ONLY
+probe_write(env, addr, cpu_mmu_index(env, 0), ra);
+#endif
+break;
+}
+}
+
 void HELPER(loaded_fr0)(CPUHPPAState *env)
 {
 uint32_t shadow = env->fr[0] >> 32;
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 093a65e..1973777 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -278,6 +278,45 @@ static void save_gpr(DisasContext *ctx, unsigned reg, TCGv 
t)
 }
 }
 
+#ifdef HOST_WORDS_BIGENDIAN
+# define HI_OFS  0
+# define LO_OFS  4
+#else
+# define HI_OFS  4
+# define LO_OFS  0
+#endif
+
+static TCGv_i32 load_frw_i32(unsigned rt)
+{
+TCGv_i32 ret = tcg_temp_new_i32();
+tcg_gen_ld_i32(ret, cpu_env,
+   offsetof(CPUHPPAState, fr[rt & 31])
+   + (rt & 32 ? LO_OFS : HI_OFS));
+return ret;
+}
+
+static void save_frw_i32(unsigned rt, TCGv_i32 val)
+{
+tcg_gen_st_i32(val, cpu_env,
+   offsetof(CPUHPPAState, fr[rt & 31])
+   + (rt & 32 ? LO_OFS : HI_OFS));
+}
+
+#undef HI_OFS
+#undef LO_OFS
+
+static TCGv_i64 load_frd(unsigned rt)
+{
+TCGv_i64 ret = tcg_temp_new_i64();
+tcg_gen_ld_i64(ret, cpu_env, offsetof(CPUHPPAState, fr[rt]));
+return ret;
+}
+
+static void save_frd(unsigned rt, TCGv_i64 val)
+{
+tcg_gen_st_i64(val, cpu_env, offsetof(CPUHPPAState, fr[rt]));
+}
+
 /* Skip over the implementation of an insn that has been nullified.
Use this when the insn is too complex for a conditional move.  */
 static void nullify_over(DisasContext *ctx)
@@ -471,6 +510,16 @@ static target_long assemble_16(uint32_t insn)
 return low_sextract(insn, 0, 14);
 }
 
+static target_long assemble_16a(uint32_t insn)
+{
+/* Take the name from PA2.0, which produces a 14-bit shifted number
+   only with wide mode; otherwise a 12-bit shifted number.  Since we
+   don't implement 

[Qemu-devel] [PULL 18/26] target-hppa: Add framework and enable compilation

2017-01-22 Thread Richard Henderson
This is just about the minimum required to enable compilation
without actually executing any instructions.  This contains the
HPPACPU structure and the required callbacks, the gdbstub, the
basic translation loop, and a translate_one function that always
results in an illegal instruction.

Signed-off-by: Richard Henderson 
---
 MAINTAINERS |   6 +
 configure   |   6 +-
 default-configs/hppa-linux-user.mak |   1 +
 target/hppa/Makefile.objs   |   1 +
 target/hppa/cpu-qom.h   |  52 +
 target/hppa/cpu.c   | 164 ++
 target/hppa/cpu.h   | 144 
 target/hppa/gdbstub.c   | 111 ++
 target/hppa/helper.c| 137 
 target/hppa/helper.h|   3 +
 target/hppa/op_helper.c |  65 ++
 target/hppa/translate.c | 429 
 12 files changed, 1116 insertions(+), 3 deletions(-)
 create mode 100644 default-configs/hppa-linux-user.mak
 create mode 100644 target/hppa/Makefile.objs
 create mode 100644 target/hppa/cpu-qom.h
 create mode 100644 target/hppa/cpu.c
 create mode 100644 target/hppa/cpu.h
 create mode 100644 target/hppa/gdbstub.c
 create mode 100644 target/hppa/helper.c
 create mode 100644 target/hppa/helper.h
 create mode 100644 target/hppa/op_helper.c
 create mode 100644 target/hppa/translate.c

diff --git a/MAINTAINERS b/MAINTAINERS
index b5ebfab..44c42fb 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -132,6 +132,12 @@ F: include/hw/cris/
 F: tests/tcg/cris/
 F: disas/cris.c
 
+HPPA (PA-RISC)
+M: Richard Henderson 
+S: Maintained
+F: target/hppa/
+F: disas/hppa.c
+
 LM32
 M: Michael Walle 
 S: Maintained
diff --git a/configure b/configure
index 494c9cc..90f01e8 100755
--- a/configure
+++ b/configure
@@ -510,8 +510,6 @@ elif check_define __arm__ ; then
   cpu="arm"
 elif check_define __aarch64__ ; then
   cpu="aarch64"
-elif check_define __hppa__ ; then
-  cpu="hppa"
 else
   cpu=$(uname -m)
 fi
@@ -5847,7 +5845,7 @@ target_name=$(echo $target | cut -d '-' -f 1)
 target_bigendian="no"
 
 case "$target_name" in
-  
armeb|lm32|m68k|microblaze|mips|mipsn32|mips64|moxie|or32|ppc|ppcemb|ppc64|ppc64abi32|s390x|sh4eb|sparc|sparc64|sparc32plus|xtensaeb)
+  
armeb|hppa|lm32|m68k|microblaze|mips|mipsn32|mips64|moxie|or32|ppc|ppcemb|ppc64|ppc64abi32|s390x|sh4eb|sparc|sparc64|sparc32plus|xtensaeb)
   target_bigendian=yes
   ;;
 esac
@@ -5910,6 +5908,8 @@ case "$target_name" in
   ;;
   cris)
   ;;
+  hppa)
+  ;;
   lm32)
   ;;
   m68k)
diff --git a/default-configs/hppa-linux-user.mak 
b/default-configs/hppa-linux-user.mak
new file mode 100644
index 000..7963939
--- /dev/null
+++ b/default-configs/hppa-linux-user.mak
@@ -0,0 +1 @@
+# Default configuration for hppa-linux-user
diff --git a/target/hppa/Makefile.objs b/target/hppa/Makefile.objs
new file mode 100644
index 000..263446f
--- /dev/null
+++ b/target/hppa/Makefile.objs
@@ -0,0 +1 @@
+obj-y += translate.o helper.o cpu.o op_helper.o gdbstub.o
diff --git a/target/hppa/cpu-qom.h b/target/hppa/cpu-qom.h
new file mode 100644
index 000..9084e47
--- /dev/null
+++ b/target/hppa/cpu-qom.h
@@ -0,0 +1,52 @@
+/*
+ * QEMU HPPA CPU
+ *
+ * Copyright (c) 2016 Richard Henderson 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * 
+ */
+#ifndef QEMU_HPPA_CPU_QOM_H
+#define QEMU_HPPA_CPU_QOM_H
+
+#include "qom/cpu.h"
+
+#define TYPE_HPPA_CPU "hppa-cpu"
+
+#define HPPA_CPU_CLASS(klass) \
+OBJECT_CLASS_CHECK(HPPACPUClass, (klass), TYPE_HPPA_CPU)
+#define HPPA_CPU(obj) \
+OBJECT_CHECK(HPPACPU, (obj), TYPE_HPPA_CPU)
+#define HPPA_CPU_GET_CLASS(obj) \
+OBJECT_GET_CLASS(HPPACPUClass, (obj), TYPE_HPPA_CPU)
+
+/**
+ * HPPACPUClass:
+ * @parent_realize: The parent class' realize handler.
+ * @parent_reset: The parent class' reset handler.
+ *
+ * An HPPA CPU model.
+ */
+typedef struct HPPACPUClass {
+/*< private >*/
+CPUClass parent_class;
+/*< public >*/
+
+DeviceRealize parent_realize;
+void (*parent_reset)(CPUState *cpu);
+} HPPACPUClass;
+
+typedef struct HPPACPU HPPACPU;
+
+#endif
diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c
new file mode 100644
index 000..1d791d0
--- /dev/null
+++ b/target/hppa/cpu.c

[Qemu-devel] [PULL 26/26] target-hppa: Implement floating-point insns

2017-01-22 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/hppa/helper.h|  55 
 target/hppa/op_helper.c | 394 ++
 target/hppa/translate.c | 728 
 3 files changed, 1177 insertions(+)

diff --git a/target/hppa/helper.h b/target/hppa/helper.h
index d51cf6d..789f07f 100644
--- a/target/hppa/helper.h
+++ b/target/hppa/helper.h
@@ -9,3 +9,58 @@ DEF_HELPER_FLAGS_1(probe_r, TCG_CALL_NO_RWG_SE, tl, tl)
 DEF_HELPER_FLAGS_1(probe_w, TCG_CALL_NO_RWG_SE, tl, tl)
 
 DEF_HELPER_FLAGS_1(loaded_fr0, TCG_CALL_NO_RWG, void, env)
+
+DEF_HELPER_FLAGS_2(fsqrt_s, TCG_CALL_NO_RWG, f32, env, f32)
+DEF_HELPER_FLAGS_2(frnd_s, TCG_CALL_NO_RWG, f32, env, f32)
+DEF_HELPER_FLAGS_3(fadd_s, TCG_CALL_NO_RWG, f32, env, f32, f32)
+DEF_HELPER_FLAGS_3(fsub_s, TCG_CALL_NO_RWG, f32, env, f32, f32)
+DEF_HELPER_FLAGS_3(fmpy_s, TCG_CALL_NO_RWG, f32, env, f32, f32)
+DEF_HELPER_FLAGS_3(fdiv_s, TCG_CALL_NO_RWG, f32, env, f32, f32)
+
+DEF_HELPER_FLAGS_2(fsqrt_d, TCG_CALL_NO_RWG, f64, env, f64)
+DEF_HELPER_FLAGS_2(frnd_d, TCG_CALL_NO_RWG, f64, env, f64)
+DEF_HELPER_FLAGS_3(fadd_d, TCG_CALL_NO_RWG, f64, env, f64, f64)
+DEF_HELPER_FLAGS_3(fsub_d, TCG_CALL_NO_RWG, f64, env, f64, f64)
+DEF_HELPER_FLAGS_3(fmpy_d, TCG_CALL_NO_RWG, f64, env, f64, f64)
+DEF_HELPER_FLAGS_3(fdiv_d, TCG_CALL_NO_RWG, f64, env, f64, f64)
+
+DEF_HELPER_FLAGS_2(fcnv_s_d, TCG_CALL_NO_RWG, f64, env, f32)
+DEF_HELPER_FLAGS_2(fcnv_d_s, TCG_CALL_NO_RWG, f32, env, f64)
+
+DEF_HELPER_FLAGS_2(fcnv_w_s, TCG_CALL_NO_RWG, f32, env, s32)
+DEF_HELPER_FLAGS_2(fcnv_dw_s, TCG_CALL_NO_RWG, f32, env, s64)
+DEF_HELPER_FLAGS_2(fcnv_w_d, TCG_CALL_NO_RWG, f64, env, s32)
+DEF_HELPER_FLAGS_2(fcnv_dw_d, TCG_CALL_NO_RWG, f64, env, s64)
+
+DEF_HELPER_FLAGS_2(fcnv_s_w, TCG_CALL_NO_RWG, s32, env, f32)
+DEF_HELPER_FLAGS_2(fcnv_d_w, TCG_CALL_NO_RWG, s32, env, f64)
+DEF_HELPER_FLAGS_2(fcnv_s_dw, TCG_CALL_NO_RWG, s64, env, f32)
+DEF_HELPER_FLAGS_2(fcnv_d_dw, TCG_CALL_NO_RWG, s64, env, f64)
+
+DEF_HELPER_FLAGS_2(fcnv_t_s_w, TCG_CALL_NO_RWG, s32, env, f32)
+DEF_HELPER_FLAGS_2(fcnv_t_d_w, TCG_CALL_NO_RWG, s32, env, f64)
+DEF_HELPER_FLAGS_2(fcnv_t_s_dw, TCG_CALL_NO_RWG, s64, env, f32)
+DEF_HELPER_FLAGS_2(fcnv_t_d_dw, TCG_CALL_NO_RWG, s64, env, f64)
+
+DEF_HELPER_FLAGS_2(fcnv_uw_s, TCG_CALL_NO_RWG, f32, env, i32)
+DEF_HELPER_FLAGS_2(fcnv_udw_s, TCG_CALL_NO_RWG, f32, env, i64)
+DEF_HELPER_FLAGS_2(fcnv_uw_d, TCG_CALL_NO_RWG, f64, env, i32)
+DEF_HELPER_FLAGS_2(fcnv_udw_d, TCG_CALL_NO_RWG, f64, env, i64)
+
+DEF_HELPER_FLAGS_2(fcnv_s_uw, TCG_CALL_NO_RWG, i32, env, f32)
+DEF_HELPER_FLAGS_2(fcnv_d_uw, TCG_CALL_NO_RWG, i32, env, f64)
+DEF_HELPER_FLAGS_2(fcnv_s_udw, TCG_CALL_NO_RWG, i64, env, f32)
+DEF_HELPER_FLAGS_2(fcnv_d_udw, TCG_CALL_NO_RWG, i64, env, f64)
+
+DEF_HELPER_FLAGS_2(fcnv_t_s_uw, TCG_CALL_NO_RWG, i32, env, f32)
+DEF_HELPER_FLAGS_2(fcnv_t_d_uw, TCG_CALL_NO_RWG, i32, env, f64)
+DEF_HELPER_FLAGS_2(fcnv_t_s_udw, TCG_CALL_NO_RWG, i64, env, f32)
+DEF_HELPER_FLAGS_2(fcnv_t_d_udw, TCG_CALL_NO_RWG, i64, env, f64)
+
+DEF_HELPER_FLAGS_5(fcmp_s, TCG_CALL_NO_RWG, void, env, f32, f32, i32, i32)
+DEF_HELPER_FLAGS_5(fcmp_d, TCG_CALL_NO_RWG, void, env, f64, f64, i32, i32)
+
+DEF_HELPER_FLAGS_4(fmpyfadd_s, TCG_CALL_NO_RWG, i32, env, i32, i32, i32)
+DEF_HELPER_FLAGS_4(fmpynfadd_s, TCG_CALL_NO_RWG, i32, env, i32, i32, i32)
+DEF_HELPER_FLAGS_4(fmpyfadd_d, TCG_CALL_NO_RWG, i64, env, i64, i64, i64)
+DEF_HELPER_FLAGS_4(fmpynfadd_d, TCG_CALL_NO_RWG, i64, env, i64, i64, i64)
diff --git a/target/hppa/op_helper.c b/target/hppa/op_helper.c
index 670e600..c05c0d5 100644
--- a/target/hppa/op_helper.c
+++ b/target/hppa/op_helper.c
@@ -174,3 +174,397 @@ void cpu_hppa_loaded_fr0(CPUHPPAState *env)
 {
 helper_loaded_fr0(env);
 }
+
+#define CONVERT_BIT(X, SRC, DST)\
+((SRC) > (DST)  \
+ ? (X) / ((SRC) / (DST)) & (DST)\
+ : ((X) & (SRC)) * ((DST) / (SRC)))
+
+static void update_fr0_op(CPUHPPAState *env, uintptr_t ra)
+{
+uint32_t soft_exp = get_float_exception_flags(>fp_status);
+uint32_t hard_exp = 0;
+uint32_t shadow = env->fr0_shadow;
+
+if (likely(soft_exp == 0)) {
+env->fr[0] = (uint64_t)shadow << 32;
+return;
+}
+set_float_exception_flags(0, >fp_status);
+
+hard_exp |= CONVERT_BIT(soft_exp, float_flag_inexact,   1u << 0);
+hard_exp |= CONVERT_BIT(soft_exp, float_flag_underflow, 1u << 1);
+hard_exp |= CONVERT_BIT(soft_exp, float_flag_overflow,  1u << 2);
+hard_exp |= CONVERT_BIT(soft_exp, float_flag_divbyzero, 1u << 3);
+hard_exp |= CONVERT_BIT(soft_exp, float_flag_invalid,   1u << 4);
+shadow |= hard_exp << (32 - 5);
+env->fr0_shadow = shadow;
+env->fr[0] = (uint64_t)shadow << 32;
+
+if (hard_exp & shadow) {
+dynexcp(env, EXCP_SIGFPE, ra);
+}
+}
+
+float32 HELPER(fsqrt_s)(CPUHPPAState *env, float32 arg)
+{
+float32 ret = float32_sqrt(arg, >fp_status);
+update_fr0_op(env, GETPC());
+return ret;
+}
+
+float32 

[Qemu-devel] [PULL 11/26] linux-user: Add HPPA target_syscall.h

2017-01-22 Thread Richard Henderson
Which is primarily a re-definition of errno numbers.

Signed-off-by: Richard Henderson 
---
 linux-user/hppa/target_syscall.h | 237 +++
 1 file changed, 237 insertions(+)
 create mode 100644 linux-user/hppa/target_syscall.h

diff --git a/linux-user/hppa/target_syscall.h b/linux-user/hppa/target_syscall.h
new file mode 100644
index 000..ac18a9c
--- /dev/null
+++ b/linux-user/hppa/target_syscall.h
@@ -0,0 +1,237 @@
+#ifndef HPPA_TARGET_SYSCALL_H
+#define HPPA_TARGET_SYSCALL_H
+
+struct target_pt_regs {
+target_ulong gr[32];
+uint64_t fr[32];
+target_ulong sr[8];
+target_ulong iasq[2];
+target_ulong iaoq[2];
+target_ulong cr27;
+target_ulong __pad0;
+target_ulong orig_r28;
+target_ulong ksp;
+target_ulong kpc;
+target_ulong sar;
+target_ulong iir;
+target_ulong isr;
+target_ulong ior;
+target_ulong ipsw;
+};
+
+#define UNAME_MACHINE "hppa"
+#define UNAME_MINIMUM_RELEASE "2.6.32"
+#define TARGET_CLONE_BACKWARDS
+#define TARGET_MINSIGSTKSZ   2048
+#define TARGET_MLOCKALL_MCL_CURRENT 1
+#define TARGET_MLOCKALL_MCL_FUTURE  2
+
+#undef  TARGET_ENOMSG
+#define TARGET_ENOMSG  35
+#undef  TARGET_EIDRM
+#define TARGET_EIDRM   36
+#undef  TARGET_ECHRNG
+#define TARGET_ECHRNG  37
+#undef  TARGET_EL2NSYNC
+#define TARGET_EL2NSYNC38
+#undef  TARGET_EL3HLT
+#define TARGET_EL3HLT  39
+#undef  TARGET_EL3RST
+#define TARGET_EL3RST  40
+#undef  TARGET_ELNRNG
+#define TARGET_ELNRNG  41
+#undef  TARGET_EUNATCH
+#define TARGET_EUNATCH 42
+#undef  TARGET_ENOCSI
+#define TARGET_ENOCSI  43
+#undef  TARGET_EL2HLT
+#define TARGET_EL2HLT  44
+#undef  TARGET_EDEADLK
+#define TARGET_EDEADLK 45
+#undef  TARGET_ENOLCK
+#define TARGET_ENOLCK  46
+#undef  TARGET_EILSEQ
+#define TARGET_EILSEQ  47
+
+#undef  TARGET_ENONET
+#define TARGET_ENONET  50
+#undef  TARGET_ENODATA
+#define TARGET_ENODATA 51
+#undef  TARGET_ETIME
+#define TARGET_ETIME   52
+#undef  TARGET_ENOSR
+#define TARGET_ENOSR   53
+#undef  TARGET_ENOSTR
+#define TARGET_ENOSTR  54
+#undef  TARGET_ENOPKG
+#define TARGET_ENOPKG  55
+
+#undef  TARGET_ENOLINK
+#define TARGET_ENOLINK 57
+#undef  TARGET_EADV
+#define TARGET_EADV58
+#undef  TARGET_ESRMNT
+#define TARGET_ESRMNT  59
+#undef  TARGET_ECOMM
+#define TARGET_ECOMM   60
+#undef  TARGET_EPROTO
+#define TARGET_EPROTO  61
+
+#undef  TARGET_EMULTIHOP
+#define TARGET_EMULTIHOP   64
+
+#undef  TARGET_EDOTDOT
+#define TARGET_EDOTDOT 66
+#undef  TARGET_EBADMSG
+#define TARGET_EBADMSG 67
+#undef  TARGET_EUSERS
+#define TARGET_EUSERS  68
+#undef  TARGET_EDQUOT
+#define TARGET_EDQUOT  69
+#undef  TARGET_ESTALE
+#define TARGET_ESTALE  70
+#undef  TARGET_EREMOTE
+#define TARGET_EREMOTE 71
+#undef  TARGET_EOVERFLOW
+#define TARGET_EOVERFLOW   72
+
+#undef  TARGET_EBADE
+#define TARGET_EBADE   160
+#undef  TARGET_EBADR
+#define TARGET_EBADR   161
+#undef  TARGET_EXFULL
+#define TARGET_EXFULL  162
+#undef  TARGET_ENOANO
+#define TARGET_ENOANO  163
+#undef  TARGET_EBADRQC
+#define TARGET_EBADRQC 164
+#undef  TARGET_EBADSLT
+#define TARGET_EBADSLT 165
+#undef  TARGET_EBFONT
+#define TARGET_EBFONT  166
+#undef  TARGET_ENOTUNIQ
+#define TARGET_ENOTUNIQ167
+#undef  TARGET_EBADFD
+#define TARGET_EBADFD  168
+#undef  TARGET_EREMCHG
+#define TARGET_EREMCHG 169
+#undef  TARGET_ELIBACC
+#define TARGET_ELIBACC 170
+#undef  TARGET_ELIBBAD
+#define TARGET_ELIBBAD 171
+#undef  TARGET_ELIBSCN
+#define TARGET_ELIBSCN 172
+#undef  TARGET_ELIBMAX
+#define TARGET_ELIBMAX 173
+#undef  TARGET_ELIBEXEC
+#define TARGET_ELIBEXEC174
+#undef  TARGET_ERESTART
+#define TARGET_ERESTART175
+#undef  TARGET_ESTRPIPE
+#define TARGET_ESTRPIPE176
+#undef  TARGET_EUCLEAN
+#define TARGET_EUCLEAN 177
+#undef  TARGET_ENOTNAM
+#define TARGET_ENOTNAM 178
+#undef  TARGET_ENAVAIL
+#define TARGET_ENAVAIL 179
+#undef  TARGET_EISNAM
+#define TARGET_EISNAM  180
+#undef  TARGET_EREMOTEIO
+#define TARGET_EREMOTEIO   181
+#undef  TARGET_ENOMEDIUM
+#define TARGET_ENOMEDIUM   182
+#undef  TARGET_EMEDIUMTYPE
+#define TARGET_EMEDIUMTYPE 183
+#undef  TARGET_ENOKEY
+#define TARGET_ENOKEY  184
+#undef  TARGET_EKEYEXPIRED
+#define TARGET_EKEYEXPIRED 185
+#undef  TARGET_EKEYREVOKED
+#define TARGET_EKEYREVOKED 186
+#undef  TARGET_EKEYREJECTED
+#define TARGET_EKEYREJECTED187
+
+/* Never used in linux.  */
+/* #define TARGET_ENOSYM  215 */
+#undef  TARGET_ENOTSOCK
+#define TARGET_ENOTSOCK216
+#undef  TARGET_EDESTADDRREQ
+#define TARGET_EDESTADDRREQ217
+#undef  TARGET_EMSGSIZE
+#define TARGET_EMSGSIZE218

[Qemu-devel] [PULL 20/26] target-hppa: Implement basic arithmetic

2017-01-22 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/hppa/helper.h|   2 +
 target/hppa/op_helper.c |  23 ++
 target/hppa/translate.c | 882 
 3 files changed, 907 insertions(+)

diff --git a/target/hppa/helper.h b/target/hppa/helper.h
index 9c94dac..ecff17c 100644
--- a/target/hppa/helper.h
+++ b/target/hppa/helper.h
@@ -1,3 +1,5 @@
 DEF_HELPER_2(excp, noreturn, env, int)
+DEF_HELPER_FLAGS_2(tsv, TCG_CALL_NO_WG, void, env, tl)
+DEF_HELPER_FLAGS_2(tcond, TCG_CALL_NO_WG, void, env, tl)
 
 DEF_HELPER_FLAGS_1(loaded_fr0, TCG_CALL_NO_RWG, void, env)
diff --git a/target/hppa/op_helper.c b/target/hppa/op_helper.c
index 4dd0119..f36ce74 100644
--- a/target/hppa/op_helper.c
+++ b/target/hppa/op_helper.c
@@ -31,6 +31,29 @@ void QEMU_NORETURN HELPER(excp)(CPUHPPAState *env, int excp)
 cpu_loop_exit(cs);
 }
 
+static void QEMU_NORETURN dynexcp(CPUHPPAState *env, int excp, uintptr_t ra)
+{
+HPPACPU *cpu = hppa_env_get_cpu(env);
+CPUState *cs = CPU(cpu);
+
+cs->exception_index = excp;
+cpu_loop_exit_restore(cs, ra);
+}
+
+void HELPER(tsv)(CPUHPPAState *env, target_ulong cond)
+{
+if (unlikely((target_long)cond < 0)) {
+dynexcp(env, EXCP_SIGFPE, GETPC());
+}
+}
+
+void HELPER(tcond)(CPUHPPAState *env, target_ulong cond)
+{
+if (unlikely(cond)) {
+dynexcp(env, EXCP_SIGFPE, GETPC());
+}
+}
+
 void HELPER(loaded_fr0)(CPUHPPAState *env)
 {
 uint32_t shadow = env->fr[0] >> 32;
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 22dfb73..2ad651c 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -83,6 +83,9 @@ typedef struct DisasInsn {
 uint32_t insn, mask;
 ExitStatus (*trans)(DisasContext *ctx, uint32_t insn,
 const struct DisasInsn *f);
+union {
+void (*f_ttt)(TCGv, TCGv, TCGv);
+};
 } DisasInsn;
 
 /* global register indexes */
@@ -443,6 +446,870 @@ static void gen_goto_tb(DisasContext *ctx, int which,
 }
 }
 
+/* PA has a habit of taking the LSB of a field and using that as the sign,
+   with the rest of the field becoming the least significant bits.  */
+static target_long low_sextract(uint32_t val, int pos, int len)
+{
+target_ulong x = -(target_ulong)extract32(val, pos, 1);
+x = (x << (len - 1)) | extract32(val, pos + 1, len - 1);
+return x;
+}
+
+static target_long assemble_16(uint32_t insn)
+{
+/* Take the name from PA2.0, which produces a 16-bit number
+   only with wide mode; otherwise a 14-bit number.  Since we don't
+   implement wide mode, this is always the 14-bit number.  */
+return low_sextract(insn, 0, 14);
+}
+
+static target_long assemble_21(uint32_t insn)
+{
+target_ulong x = -(target_ulong)(insn & 1);
+x = (x << 11) | extract32(insn, 1, 11);
+x = (x <<  2) | extract32(insn, 14, 2);
+x = (x <<  5) | extract32(insn, 16, 5);
+x = (x <<  2) | extract32(insn, 12, 2);
+return x << 11;
+}
+
+/* The parisc documentation describes only the general interpretation of
+   the conditions, without describing their exact implementation.  The
+   interpretations do not stand up well when considering ADD,C and SUB,B.
+   However, considering the Addition, Subtraction and Logical conditions
+   as a whole it would appear that these relations are similar to what
+   a traditional NZCV set of flags would produce.  */
+
+static DisasCond do_cond(unsigned cf, TCGv res, TCGv cb_msb, TCGv sv)
+{
+DisasCond cond;
+TCGv tmp;
+
+switch (cf >> 1) {
+case 0: /* Never / TR */
+cond = cond_make_f();
+break;
+case 1: /* = / <>(Z / !Z) */
+cond = cond_make_0(TCG_COND_EQ, res);
+break;
+case 2: /* < / >=(N / !N) */
+cond = cond_make_0(TCG_COND_LT, res);
+break;
+case 3: /* <= / >(N | Z / !N & !Z) */
+cond = cond_make_0(TCG_COND_LE, res);
+break;
+case 4: /* NUV / UV  (!C / C) */
+cond = cond_make_0(TCG_COND_EQ, cb_msb);
+break;
+case 5: /* ZNV / VNZ (!C | Z / C & !Z) */
+tmp = tcg_temp_new();
+tcg_gen_neg_tl(tmp, cb_msb);
+tcg_gen_and_tl(tmp, tmp, res);
+cond = cond_make_0(TCG_COND_EQ, tmp);
+tcg_temp_free(tmp);
+break;
+case 6: /* SV / NSV  (V / !V) */
+cond = cond_make_0(TCG_COND_LT, sv);
+break;
+case 7: /* OD / EV */
+tmp = tcg_temp_new();
+tcg_gen_andi_tl(tmp, res, 1);
+cond = cond_make_0(TCG_COND_NE, tmp);
+tcg_temp_free(tmp);
+break;
+default:
+g_assert_not_reached();
+}
+if (cf & 1) {
+cond.c = tcg_invert_cond(cond.c);
+}
+
+return cond;
+}
+
+/* Similar, but for the special case of subtraction without borrow, we
+   can use the inputs directly.  This can allow other computation to be
+   deleted as unused.  */
+
+static DisasCond do_sub_cond(unsigned cf, TCGv res, TCGv in1, TCGv 

[Qemu-devel] [PULL 22/26] target-hppa: Implement linux-user gateway page

2017-01-22 Thread Richard Henderson
For linux, page 0 is mapped as an execute-only gateway.  A gateway
page is a special bit in the page table that allows a B,GATE insn
within that page to raise processor permissions.  This is how system
calls are implemented for HPPA.

Rather than actually map anything here, or handle permissions at all,
implement the semantics of the actual linux syscall entry points.

Signed-off-by: Richard Henderson 
---
 target/hppa/translate.c | 85 ++---
 1 file changed, 81 insertions(+), 4 deletions(-)

diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 1d0976f..14fe4bb 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -1123,6 +1123,64 @@ static ExitStatus do_ibranch(DisasContext *ctx, TCGv 
dest,
 return NO_EXIT;
 }
 
+/* On Linux, page zero is normally marked execute only + gateway.
+   Therefore normal read or write is supposed to fail, but specific
+   offsets have kernel code mapped to raise permissions to implement
+   system calls.  Handling this via an explicit check here, rather
+   in than the "be disp(sr2,r0)" instruction that probably sent us
+   here, is the easiest way to handle the branch delay slot on the
+   aforementioned BE.  */
+static ExitStatus do_page_zero(DisasContext *ctx)
+{
+/* If by some means we get here with PSW[N]=1, that implies that
+   the B,GATE instruction would be skipped, and we'd fault on the
+   next insn within the privilaged page.  */
+switch (ctx->null_cond.c) {
+case TCG_COND_NEVER:
+break;
+case TCG_COND_ALWAYS:
+tcg_gen_movi_tl(cpu_psw_n, 0);
+goto do_sigill;
+default:
+/* Since this is always the first (and only) insn within the
+   TB, we should know the state of PSW[N] from TB->FLAGS.  */
+g_assert_not_reached();
+}
+
+/* Check that we didn't arrive here via some means that allowed
+   non-sequential instruction execution.  Normally the PSW[B] bit
+   detects this by disallowing the B,GATE instruction to execute
+   under such conditions.  */
+if (ctx->iaoq_b != ctx->iaoq_f + 4) {
+goto do_sigill;
+}
+
+switch (ctx->iaoq_f) {
+case 0x00: /* Null pointer call */
+gen_excp_1(EXCP_SIGSEGV);
+return EXIT_NORETURN;
+
+case 0xb0: /* LWS */
+gen_excp_1(EXCP_SYSCALL_LWS);
+return EXIT_NORETURN;
+
+case 0xe0: /* SET_THREAD_POINTER */
+tcg_gen_mov_tl(cpu_cr27, cpu_gr[26]);
+tcg_gen_mov_tl(cpu_iaoq_f, cpu_gr[31]);
+tcg_gen_addi_tl(cpu_iaoq_b, cpu_iaoq_f, 4);
+return EXIT_IAQ_N_UPDATED;
+
+case 0x100: /* SYSCALL */
+gen_excp_1(EXCP_SYSCALL);
+return EXIT_NORETURN;
+
+default:
+do_sigill:
+gen_excp_1(EXCP_SIGILL);
+return EXIT_NORETURN;
+}
+}
+
 static ExitStatus trans_nop(DisasContext *ctx, uint32_t insn,
 const DisasInsn *di)
 {
@@ -1884,7 +1942,10 @@ void gen_intermediate_code(CPUHPPAState *env, struct 
TranslationBlock *tb)
 gen_io_start();
 }
 
-{
+if (ctx.iaoq_f < TARGET_PAGE_SIZE) {
+ret = do_page_zero();
+assert(ret != NO_EXIT);
+} else {
 /* Always fetch the insn, even if nullified, so that we check
the page permissions for execute.  */
 uint32_t insn = cpu_ldl_code(env, ctx.iaoq_f);
@@ -1986,9 +2047,25 @@ void gen_intermediate_code(CPUHPPAState *env, struct 
TranslationBlock *tb)
 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
 && qemu_log_in_addr_range(tb->pc)) {
 qemu_log_lock();
-qemu_log("IN: %s\n", lookup_symbol(tb->pc));
-log_target_disas(cs, tb->pc, tb->size, 1);
-qemu_log("\n");
+switch (tb->pc) {
+case 0x00:
+qemu_log("IN:\n0x:  (null)\n\n");
+break;
+case 0xb0:
+qemu_log("IN:\n0x00b0:  light-weight-syscall\n\n");
+break;
+case 0xe0:
+qemu_log("IN:\n0x00e0:  set-thread-pointer-syscall\n\n");
+break;
+case 0x100:
+qemu_log("IN:\n0x0100:  syscall\n\n");
+break;
+default:
+qemu_log("IN: %s\n", lookup_symbol(tb->pc));
+log_target_disas(cs, tb->pc, tb->size, 1);
+qemu_log("\n");
+break;
+}
 qemu_log_unlock();
 }
 #endif
-- 
2.9.3




[Qemu-devel] [PULL 25/26] target-hppa: Implement system and memory-management insns

2017-01-22 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 target/hppa/helper.h|   3 +
 target/hppa/op_helper.c |  10 +++
 target/hppa/translate.c | 206 
 3 files changed, 219 insertions(+)

diff --git a/target/hppa/helper.h b/target/hppa/helper.h
index 88db719..d51cf6d 100644
--- a/target/hppa/helper.h
+++ b/target/hppa/helper.h
@@ -5,4 +5,7 @@ DEF_HELPER_FLAGS_2(tcond, TCG_CALL_NO_WG, void, env, tl)
 DEF_HELPER_FLAGS_3(stby_b, TCG_CALL_NO_WG, void, env, tl, tl)
 DEF_HELPER_FLAGS_3(stby_e, TCG_CALL_NO_WG, void, env, tl, tl)
 
+DEF_HELPER_FLAGS_1(probe_r, TCG_CALL_NO_RWG_SE, tl, tl)
+DEF_HELPER_FLAGS_1(probe_w, TCG_CALL_NO_RWG_SE, tl, tl)
+
 DEF_HELPER_FLAGS_1(loaded_fr0, TCG_CALL_NO_RWG, void, env)
diff --git a/target/hppa/op_helper.c b/target/hppa/op_helper.c
index 0aa5fb9..670e600 100644
--- a/target/hppa/op_helper.c
+++ b/target/hppa/op_helper.c
@@ -132,6 +132,16 @@ void HELPER(stby_e)(CPUHPPAState *env, target_ulong addr, 
target_ulong val)
 }
 }
 
+target_ulong HELPER(probe_r)(target_ulong addr)
+{
+return page_check_range(addr, 1, PAGE_READ);
+}
+
+target_ulong HELPER(probe_w)(target_ulong addr)
+{
+return page_check_range(addr, 1, PAGE_WRITE);
+}
+
 void HELPER(loaded_fr0)(CPUHPPAState *env)
 {
 uint32_t shadow = env->fr[0] >> 32;
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 1973777..cfdb9ee 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -1465,6 +1465,208 @@ static ExitStatus trans_nop(DisasContext *ctx, uint32_t 
insn,
 return NO_EXIT;
 }
 
+static ExitStatus trans_break(DisasContext *ctx, uint32_t insn,
+  const DisasInsn *di)
+{
+nullify_over(ctx);
+return nullify_end(ctx, gen_excp(ctx, EXCP_DEBUG));
+}
+
+static ExitStatus trans_sync(DisasContext *ctx, uint32_t insn,
+ const DisasInsn *di)
+{
+/* No point in nullifying the memory barrier.  */
+tcg_gen_mb(TCG_BAR_SC | TCG_MO_ALL);
+
+cond_free(>null_cond);
+return NO_EXIT;
+}
+
+static ExitStatus trans_mfia(DisasContext *ctx, uint32_t insn,
+ const DisasInsn *di)
+{
+unsigned rt = extract32(insn, 0, 5);
+TCGv tmp = dest_gpr(ctx, rt);
+tcg_gen_movi_tl(tmp, ctx->iaoq_f);
+save_gpr(ctx, rt, tmp);
+
+cond_free(>null_cond);
+return NO_EXIT;
+}
+
+static ExitStatus trans_mfsp(DisasContext *ctx, uint32_t insn,
+ const DisasInsn *di)
+{
+unsigned rt = extract32(insn, 0, 5);
+TCGv tmp = dest_gpr(ctx, rt);
+
+/* ??? We don't implement space registers.  */
+tcg_gen_movi_tl(tmp, 0);
+save_gpr(ctx, rt, tmp);
+
+cond_free(>null_cond);
+return NO_EXIT;
+}
+
+static ExitStatus trans_mfctl(DisasContext *ctx, uint32_t insn,
+  const DisasInsn *di)
+{
+unsigned rt = extract32(insn, 0, 5);
+unsigned ctl = extract32(insn, 21, 5);
+TCGv tmp;
+
+switch (ctl) {
+case 11: /* SAR */
+#ifdef TARGET_HPPA64
+if (extract32(insn, 14, 1) == 0) {
+/* MFSAR without ,W masks low 5 bits.  */
+tmp = dest_gpr(ctx, rt);
+tcg_gen_andi_tl(tmp, cpu_sar, 31);
+save_gpr(ctx, rt, tmp);
+break;
+}
+#endif
+save_gpr(ctx, rt, cpu_sar);
+break;
+case 16: /* Interval Timer */
+tmp = dest_gpr(ctx, rt);
+tcg_gen_movi_tl(tmp, 0); /* FIXME */
+save_gpr(ctx, rt, tmp);
+break;
+case 26:
+save_gpr(ctx, rt, cpu_cr26);
+break;
+case 27:
+save_gpr(ctx, rt, cpu_cr27);
+break;
+default:
+/* All other control registers are privileged.  */
+return gen_illegal(ctx);
+}
+
+cond_free(>null_cond);
+return NO_EXIT;
+}
+
+static ExitStatus trans_mtctl(DisasContext *ctx, uint32_t insn,
+  const DisasInsn *di)
+{
+unsigned rin = extract32(insn, 16, 5);
+unsigned ctl = extract32(insn, 21, 5);
+TCGv tmp;
+
+if (ctl == 11) { /* SAR */
+tmp = tcg_temp_new();
+tcg_gen_andi_tl(tmp, load_gpr(ctx, rin), TARGET_LONG_BITS - 1);
+save_or_nullify(ctx, cpu_sar, tmp);
+tcg_temp_free(tmp);
+} else {
+/* All other control registers are privileged or read-only.  */
+return gen_illegal(ctx);
+}
+
+cond_free(>null_cond);
+return NO_EXIT;
+}
+
+static ExitStatus trans_mtsarcm(DisasContext *ctx, uint32_t insn,
+const DisasInsn *di)
+{
+unsigned rin = extract32(insn, 16, 5);
+TCGv tmp = tcg_temp_new();
+
+tcg_gen_not_tl(tmp, load_gpr(ctx, rin));
+tcg_gen_andi_tl(tmp, tmp, TARGET_LONG_BITS - 1);
+save_or_nullify(ctx, cpu_sar, tmp);
+tcg_temp_free(tmp);
+
+cond_free(>null_cond);
+return NO_EXIT;
+}
+
+static ExitStatus trans_ldsid(DisasContext *ctx, uint32_t insn,
+  const DisasInsn *di)
+{
+

[Qemu-devel] [PULL 19/26] target-hppa: Add nullification framework

2017-01-22 Thread Richard Henderson
The HPPA cpu has a unique form of predicated execution in which
almost any instruction can set the PSW[N] (or "nullify") bit,
which suppresses execution (and even decoding) of the following
instruction.  Execution of a nullified insn clears the PSW[N] bit.

This adds a generic framework for branching over nullified insns,
or for sufficiently simple insns, transforming the writeback of
the result to a conditional move.  In the process, we want to be
able to represent PSW[N] as a TCG condition, which implies management
of the related tcg temps.

Signed-off-by: Richard Henderson 
---
 target/hppa/translate.c | 228 +++-
 1 file changed, 224 insertions(+), 4 deletions(-)

diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 8d61853..22dfb73 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -151,6 +151,78 @@ void hppa_translate_init(void)
 }
 }
 
+static DisasCond cond_make_f(void)
+{
+DisasCond r = { .c = TCG_COND_NEVER };
+TCGV_UNUSED(r.a0);
+TCGV_UNUSED(r.a1);
+return r;
+}
+
+static DisasCond cond_make_n(void)
+{
+DisasCond r = { .c = TCG_COND_NE, .a0_is_n = true, .a1_is_0 = true };
+r.a0 = cpu_psw_n;
+TCGV_UNUSED(r.a1);
+return r;
+}
+
+static DisasCond cond_make_0(TCGCond c, TCGv a0)
+{
+DisasCond r = { .c = c, .a1_is_0 = true };
+
+assert (c != TCG_COND_NEVER && c != TCG_COND_ALWAYS);
+r.a0 = tcg_temp_new();
+tcg_gen_mov_tl(r.a0, a0);
+TCGV_UNUSED(r.a1);
+
+return r;
+}
+
+static DisasCond cond_make(TCGCond c, TCGv a0, TCGv a1)
+{
+DisasCond r = { .c = c };
+
+assert (c != TCG_COND_NEVER && c != TCG_COND_ALWAYS);
+r.a0 = tcg_temp_new();
+tcg_gen_mov_tl(r.a0, a0);
+r.a1 = tcg_temp_new();
+tcg_gen_mov_tl(r.a1, a1);
+
+return r;
+}
+
+static void cond_prep(DisasCond *cond)
+{
+if (cond->a1_is_0) {
+cond->a1_is_0 = false;
+cond->a1 = tcg_const_tl(0);
+}
+}
+
+static void cond_free(DisasCond *cond)
+{
+switch (cond->c) {
+default:
+if (!cond->a0_is_n) {
+tcg_temp_free(cond->a0);
+}
+if (!cond->a1_is_0) {
+tcg_temp_free(cond->a1);
+}
+cond->a0_is_n = false;
+cond->a1_is_0 = false;
+TCGV_UNUSED(cond->a0);
+TCGV_UNUSED(cond->a1);
+/* fallthru */
+case TCG_COND_ALWAYS:
+cond->c = TCG_COND_NEVER;
+break;
+case TCG_COND_NEVER:
+break;
+}
+}
+
 static TCGv get_temp(DisasContext *ctx)
 {
 unsigned i = ctx->ntemps++;
@@ -178,13 +250,125 @@ static TCGv load_gpr(DisasContext *ctx, unsigned reg)
 
 static TCGv dest_gpr(DisasContext *ctx, unsigned reg)
 {
-if (reg == 0) {
+if (reg == 0 || ctx->null_cond.c != TCG_COND_NEVER) {
 return get_temp(ctx);
 } else {
 return cpu_gr[reg];
 }
 }
 
+static void save_or_nullify(DisasContext *ctx, TCGv dest, TCGv t)
+{
+if (ctx->null_cond.c != TCG_COND_NEVER) {
+cond_prep(>null_cond);
+tcg_gen_movcond_tl(ctx->null_cond.c, dest, ctx->null_cond.a0,
+   ctx->null_cond.a1, dest, t);
+} else {
+tcg_gen_mov_tl(dest, t);
+}
+}
+
+static void save_gpr(DisasContext *ctx, unsigned reg, TCGv t)
+{
+if (reg != 0) {
+save_or_nullify(ctx, cpu_gr[reg], t);
+}
+}
+
+/* Skip over the implementation of an insn that has been nullified.
+   Use this when the insn is too complex for a conditional move.  */
+static void nullify_over(DisasContext *ctx)
+{
+if (ctx->null_cond.c != TCG_COND_NEVER) {
+/* The always condition should have been handled in the main loop.  */
+assert(ctx->null_cond.c != TCG_COND_ALWAYS);
+
+ctx->null_lab = gen_new_label();
+cond_prep(>null_cond);
+
+/* If we're using PSW[N], copy it to a temp because... */
+if (ctx->null_cond.a0_is_n) {
+ctx->null_cond.a0_is_n = false;
+ctx->null_cond.a0 = tcg_temp_new();
+tcg_gen_mov_tl(ctx->null_cond.a0, cpu_psw_n);
+}
+/* ... we clear it before branching over the implementation,
+   so that (1) it's clear after nullifying this insn and
+   (2) if this insn nullifies the next, PSW[N] is valid.  */
+if (ctx->psw_n_nonzero) {
+ctx->psw_n_nonzero = false;
+tcg_gen_movi_tl(cpu_psw_n, 0);
+}
+
+tcg_gen_brcond_tl(ctx->null_cond.c, ctx->null_cond.a0,
+  ctx->null_cond.a1, ctx->null_lab);
+cond_free(>null_cond);
+}
+}
+
+/* Save the current nullification state to PSW[N].  */
+static void nullify_save(DisasContext *ctx)
+{
+if (ctx->null_cond.c == TCG_COND_NEVER) {
+if (ctx->psw_n_nonzero) {
+tcg_gen_movi_tl(cpu_psw_n, 0);
+}
+return;
+}
+if (!ctx->null_cond.a0_is_n) {
+cond_prep(>null_cond);
+tcg_gen_setcond_tl(ctx->null_cond.c, cpu_psw_n,

[Qemu-devel] [PULL 10/26] linux-user: Add HPPA termbits.h

2017-01-22 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/hppa/termbits.h | 219 +
 1 file changed, 219 insertions(+)
 create mode 100644 linux-user/hppa/termbits.h

diff --git a/linux-user/hppa/termbits.h b/linux-user/hppa/termbits.h
new file mode 100644
index 000..e9633ef
--- /dev/null
+++ b/linux-user/hppa/termbits.h
@@ -0,0 +1,219 @@
+/* from asm/termbits.h */
+
+#define TARGET_NCCS 19
+
+struct target_termios {
+unsigned int c_iflag;   /* input mode flags */
+unsigned int c_oflag;   /* output mode flags */
+unsigned int c_cflag;   /* control mode flags */
+unsigned int c_lflag;   /* local mode flags */
+unsigned char c_line;/* line discipline */
+unsigned char c_cc[TARGET_NCCS];/* control characters */
+};
+
+/* c_iflag bits */
+#define TARGET_IGNBRK  001
+#define TARGET_BRKINT  002
+#define TARGET_IGNPAR  004
+#define TARGET_PARMRK  010
+#define TARGET_INPCK   020
+#define TARGET_ISTRIP  040
+#define TARGET_INLCR   100
+#define TARGET_IGNCR   200
+#define TARGET_ICRNL   400
+#define TARGET_IUCLC   0001000
+#define TARGET_IXON0002000
+#define TARGET_IXANY   0004000
+#define TARGET_IXOFF   001
+#define TARGET_IMAXBEL 004
+#define TARGET_IUTF8   010
+
+/* c_oflag bits */
+#define TARGET_OPOST   001
+#define TARGET_OLCUC   002
+#define TARGET_ONLCR   004
+#define TARGET_OCRNL   010
+#define TARGET_ONOCR   020
+#define TARGET_ONLRET  040
+#define TARGET_OFILL   100
+#define TARGET_OFDEL   200
+#define TARGET_NLDLY   400
+#define   TARGET_NL0   000
+#define   TARGET_NL1   400
+#define TARGET_CRDLY   0003000
+#define   TARGET_CR0   000
+#define   TARGET_CR1   0001000
+#define   TARGET_CR2   0002000
+#define   TARGET_CR3   0003000
+#define TARGET_TABDLY  0014000
+#define   TARGET_TAB0  000
+#define   TARGET_TAB1  0004000
+#define   TARGET_TAB2  001
+#define   TARGET_TAB3  0014000
+#define   TARGET_XTABS 0014000
+#define TARGET_BSDLY   002
+#define   TARGET_BS0   000
+#define   TARGET_BS1   002
+#define TARGET_VTDLY   004
+#define   TARGET_VT0   000
+#define   TARGET_VT1   004
+#define TARGET_FFDLY   010
+#define   TARGET_FF0   000
+#define   TARGET_FF1   010
+
+/* c_cflag bit meaning */
+#define TARGET_CBAUD   0010017
+#define  TARGET_B0 000 /* hang up */
+#define  TARGET_B50001
+#define  TARGET_B75002
+#define  TARGET_B110   003
+#define  TARGET_B134   004
+#define  TARGET_B150   005
+#define  TARGET_B200   006
+#define  TARGET_B300   007
+#define  TARGET_B600   010
+#define  TARGET_B1200  011
+#define  TARGET_B1800  012
+#define  TARGET_B2400  013
+#define  TARGET_B4800  014
+#define  TARGET_B9600  015
+#define  TARGET_B19200 016
+#define  TARGET_B38400 017
+#define TARGET_EXTA B19200
+#define TARGET_EXTB B38400
+#define TARGET_CSIZE   060
+#define   TARGET_CS5   000
+#define   TARGET_CS6   020
+#define   TARGET_CS7   040
+#define   TARGET_CS8   060
+#define TARGET_CSTOPB  100
+#define TARGET_CREAD   200
+#define TARGET_PARENB  400
+#define TARGET_PARODD  0001000
+#define TARGET_HUPCL   0002000
+#define TARGET_CLOCAL  0004000
+#define TARGET_CBAUDEX 001
+#define  TARGET_B57600  0010001
+#define  TARGET_B115200 0010002
+#define  TARGET_B230400 0010003
+#define  TARGET_B460800 0010004
+#define TARGET_CIBAUD00200360  /* input baud rate (not used) */
+#define TARGET_CMSPAR0100  /* mark or space (stick) parity */
+#define TARGET_CRTSCTS   0200  /* flow control */
+
+/* c_lflag bits */
+#define TARGET_ISIG001
+#define TARGET_ICANON  002
+#define TARGET_XCASE   004
+#define TARGET_ECHO010
+#define TARGET_ECHOE   020
+#define TARGET_ECHOK   040
+#define TARGET_ECHONL  100
+#define TARGET_NOFLSH  200
+#define TARGET_TOSTOP  400
+#define TARGET_ECHOCTL 0001000
+#define TARGET_ECHOPRT 0002000
+#define TARGET_ECHOKE  0004000
+#define TARGET_FLUSHO  001
+#define TARGET_PENDIN  004
+#define TARGET_IEXTEN  010
+
+/* c_cc character offsets */
+#define TARGET_VINTR0
+#define TARGET_VQUIT1
+#define TARGET_VERASE   2
+#define TARGET_VKILL3
+#define TARGET_VEOF 4
+#define TARGET_VTIME5
+#define TARGET_VMIN 6
+#define TARGET_VSWTC7
+#define TARGET_VSTART   8
+#define TARGET_VSTOP9
+#define TARGET_VSUSP10
+#define TARGET_VEOL 11
+#define TARGET_VREPRINT 12
+#define TARGET_VDISCARD 13
+#define TARGET_VWERASE  14
+#define TARGET_VLNEXT   15
+#define TARGET_VEOL216
+
+/* ioctls */
+
+#define TARGET_TCGETS   TARGET_IOR('T', 16, struct target_termios)
+#define TARGET_TCSETS   TARGET_IOW('T', 17, struct target_termios)
+#define TARGET_TCSETSW  TARGET_IOW('T', 18, 

[Qemu-devel] [PULL 15/26] linux-user: Add HPPA signal handling

2017-01-22 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/signal.c | 191 +++-
 1 file changed, 190 insertions(+), 1 deletion(-)

diff --git a/linux-user/signal.c b/linux-user/signal.c
index c750053..0a5bb4e 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -5888,6 +5888,195 @@ long do_rt_sigreturn(CPUTLGState *env)
 return -TARGET_QEMU_ESIGRETURN;
 }
 
+#elif defined(TARGET_HPPA)
+
+struct target_sigcontext {
+abi_ulong sc_flags;
+abi_ulong sc_gr[32];
+uint64_t sc_fr[32];
+abi_ulong sc_iasq[2];
+abi_ulong sc_iaoq[2];
+abi_ulong sc_sar;
+};
+
+struct target_ucontext {
+abi_uint tuc_flags;
+abi_ulong tuc_link;
+target_stack_t tuc_stack;
+abi_uint pad[1];
+struct target_sigcontext tuc_mcontext;
+target_sigset_t tuc_sigmask;
+};
+
+struct target_rt_sigframe {
+abi_uint tramp[9];
+target_siginfo_t info;
+struct target_ucontext uc;
+/* hidden location of upper halves of pa2.0 64-bit gregs */
+};
+
+static void setup_sigcontext(struct target_sigcontext *sc, CPUArchState *env)
+{
+int flags = 0;
+int i;
+
+/* ??? if on_sig_stack, flags |= 1 (PARISC_SC_FLAG_ONSTACK).  */
+
+if (env->iaoq_f < TARGET_PAGE_SIZE) {
+/* In the gateway page, executing a syscall.  */
+flags |= 2; /* PARISC_SC_FLAG_IN_SYSCALL */
+__put_user(env->gr[31], >sc_iaoq[0]);
+__put_user(env->gr[31] + 4, >sc_iaoq[1]);
+} else {
+__put_user(env->iaoq_f, >sc_iaoq[0]);
+__put_user(env->iaoq_b, >sc_iaoq[1]);
+}
+__put_user(0, >sc_iasq[0]);
+__put_user(0, >sc_iasq[1]);
+__put_user(flags, >sc_flags);
+
+__put_user(cpu_hppa_get_psw(env), >sc_gr[0]);
+for (i = 1; i < 32; ++i) {
+__put_user(env->gr[i], >sc_gr[i]);
+}
+
+__put_user((uint64_t)env->fr0_shadow << 32, >sc_fr[0]);
+for (i = 1; i < 32; ++i) {
+__put_user(env->fr[i], >sc_fr[i]);
+}
+
+__put_user(env->sar, >sc_sar);
+}
+
+static void restore_sigcontext(CPUArchState *env, struct target_sigcontext *sc)
+{
+target_ulong psw;
+int i;
+
+__get_user(psw, >sc_gr[0]);
+cpu_hppa_put_psw(env, psw);
+
+for (i = 1; i < 32; ++i) {
+__get_user(env->gr[i], >sc_gr[i]);
+}
+for (i = 0; i < 32; ++i) {
+__get_user(env->fr[i], >sc_fr[i]);
+}
+cpu_hppa_loaded_fr0(env);
+
+__get_user(env->iaoq_f, >sc_iaoq[0]);
+__get_user(env->iaoq_b, >sc_iaoq[1]);
+__get_user(env->sar, >sc_sar);
+}
+
+/* No, this doesn't look right, but it's copied straight from the kernel.  */
+#define PARISC_RT_SIGFRAME_SIZE32 \
+((sizeof(struct target_rt_sigframe) + 48 + 64) & -64)
+
+static void setup_rt_frame(int sig, struct target_sigaction *ka,
+   target_siginfo_t *info,
+   target_sigset_t *set, CPUArchState *env)
+{
+abi_ulong frame_addr, sp, haddr;
+struct target_rt_sigframe *frame;
+int i;
+
+sp = env->gr[30];
+if (ka->sa_flags & TARGET_SA_ONSTACK) {
+if (sas_ss_flags(sp) == 0) {
+sp = (target_sigaltstack_used.ss_sp + 0x7f) & ~0x3f;
+}
+}
+frame_addr = QEMU_ALIGN_UP(sp, 64);
+sp = frame_addr + PARISC_RT_SIGFRAME_SIZE32;
+
+trace_user_setup_rt_frame(env, frame_addr);
+
+if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
+goto give_sigsegv;
+}
+
+tswap_siginfo(>info, info);
+frame->uc.tuc_flags = 0;
+frame->uc.tuc_link = 0;
+
+__put_user(target_sigaltstack_used.ss_sp, >uc.tuc_stack.ss_sp);
+__put_user(sas_ss_flags(get_sp_from_cpustate(env)),
+   >uc.tuc_stack.ss_flags);
+__put_user(target_sigaltstack_used.ss_size,
+   >uc.tuc_stack.ss_size);
+
+for (i = 0; i < TARGET_NSIG_WORDS; i++) {
+__put_user(set->sig[i], >uc.tuc_sigmask.sig[i]);
+}
+
+setup_sigcontext(>uc.tuc_mcontext, env);
+
+__put_user(0x3419, frame->tramp + 0); /* ldi 0,%r25 */
+__put_user(0x3414015a, frame->tramp + 1); /* ldi __NR_rt_sigreturn,%r20 */
+__put_user(0xe4008200, frame->tramp + 2); /* be,l 0x100(%sr2,%r0) */
+__put_user(0x08000240, frame->tramp + 3); /* nop */
+
+unlock_user_struct(frame, frame_addr, 1);
+
+env->gr[2] = h2g(frame->tramp);
+env->gr[30] = sp;
+env->gr[26] = sig;
+env->gr[25] = h2g(>info);
+env->gr[24] = h2g(>uc);
+
+haddr = ka->_sa_handler;
+if (haddr & 2) {
+/* Function descriptor.  */
+target_ulong *fdesc, dest;
+
+haddr &= -4;
+if (!lock_user_struct(VERIFY_READ, fdesc, haddr, 1)) {
+goto give_sigsegv;
+}
+__get_user(dest, fdesc);
+__get_user(env->gr[19], fdesc + 1);
+unlock_user_struct(fdesc, haddr, 1);
+haddr = dest;
+}
+env->iaoq_f = haddr;
+env->iaoq_b = haddr + 4;;
+return;
+
+ give_sigsegv:
+force_sigsegv(sig);
+}
+
+long do_rt_sigreturn(CPUArchState *env)
+{
+

[Qemu-devel] [PULL 01/26] Revert "Remove remainders of HPPA backend"

2017-01-22 Thread Richard Henderson
This reverts commit d41f3c3cc7a5fb9de144cc4022da14a9ff010671.

Signed-off-by: Richard Henderson 
---
 configure |5 +
 disas.c   |2 +
 disas/Makefile.objs   |1 +
 disas/hppa.c  | 2832 +
 linux-user/syscall_defs.h |4 +-
 5 files changed, 2842 insertions(+), 2 deletions(-)
 create mode 100644 disas/hppa.c

diff --git a/configure b/configure
index 17d52cd..494c9cc 100755
--- a/configure
+++ b/configure
@@ -510,6 +510,8 @@ elif check_define __arm__ ; then
   cpu="arm"
 elif check_define __aarch64__ ; then
   cpu="aarch64"
+elif check_define __hppa__ ; then
+  cpu="hppa"
 else
   cpu=$(uname -m)
 fi
@@ -6107,6 +6109,9 @@ for i in $ARCH $TARGET_BASE_ARCH ; do
   cris)
 disas_config "CRIS"
   ;;
+  hppa)
+disas_config "HPPA"
+  ;;
   i386|x86_64|x32)
 disas_config "I386"
   ;;
diff --git a/disas.c b/disas.c
index 67f116a..05a7a12 100644
--- a/disas.c
+++ b/disas.c
@@ -310,6 +310,8 @@ void disas(FILE *out, void *code, unsigned long size)
 print_insn = print_insn_m68k;
 #elif defined(__s390__)
 print_insn = print_insn_s390;
+#elif defined(__hppa__)
+print_insn = print_insn_hppa;
 #elif defined(__ia64__)
 print_insn = print_insn_ia64;
 #endif
diff --git a/disas/Makefile.objs b/disas/Makefile.objs
index 09bc992..abeba84 100644
--- a/disas/Makefile.objs
+++ b/disas/Makefile.objs
@@ -9,6 +9,7 @@ libvixldir = $(SRC_PATH)/disas/libvixl
 # versions do not.
 arm-a64.o-cflags := -I$(libvixldir) -Wno-sign-compare
 common-obj-$(CONFIG_CRIS_DIS) += cris.o
+common-obj-$(CONFIG_HPPA_DIS) += hppa.o
 common-obj-$(CONFIG_I386_DIS) += i386.o
 common-obj-$(CONFIG_IA64_DIS) += ia64.o
 common-obj-$(CONFIG_M68K_DIS) += m68k.o
diff --git a/disas/hppa.c b/disas/hppa.c
new file mode 100644
index 000..43facdc
--- /dev/null
+++ b/disas/hppa.c
@@ -0,0 +1,2832 @@
+/* Disassembler for the PA-RISC. Somewhat derived from sparc-pinsn.c.
+   Copyright 1989, 1990, 1992, 1993, 1994, 1995, 1998, 1999, 2000, 2001, 2003,
+   2005 Free Software Foundation, Inc.
+
+   Contributed by the Center for Software Science at the
+   University of Utah (pa-gdb-b...@cs.utah.edu).
+
+   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 . */
+
+#include "qemu/osdep.h"
+#include "disas/bfd.h"
+
+/* HP PA-RISC SOM object file format:  definitions internal to BFD.
+   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000,
+   2003 Free Software Foundation, Inc.
+
+   Contributed by the Center for Software Science at the
+   University of Utah (pa-gdb-b...@cs.utah.edu).
+
+   This file is part of BFD, the Binary File Descriptor library.
+
+   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 .  */
+
+#ifndef _LIBHPPA_H
+#define _LIBHPPA_H
+
+#define BYTES_IN_WORD 4
+#define PA_PAGESIZE 0x1000
+
+/* The PA instruction set variants.  */
+enum pa_arch {pa10 = 10, pa11 = 11, pa20 = 20, pa20w = 25};
+
+/* HP PA-RISC relocation types */
+
+enum hppa_reloc_field_selector_type
+  {
+R_HPPA_FSEL = 0x0,
+R_HPPA_LSSEL = 0x1,
+R_HPPA_RSSEL = 0x2,
+R_HPPA_LSEL = 0x3,
+R_HPPA_RSEL = 0x4,
+R_HPPA_LDSEL = 0x5,
+R_HPPA_RDSEL = 0x6,
+R_HPPA_LRSEL = 0x7,
+R_HPPA_RRSEL = 0x8,
+R_HPPA_NSEL  = 0x9,
+R_HPPA_NLSEL  = 0xa,
+R_HPPA_NLRSEL  = 0xb,
+R_HPPA_PSEL = 0xc,
+R_HPPA_LPSEL = 0xd,
+R_HPPA_RPSEL = 0xe,
+R_HPPA_TSEL = 0xf,
+R_HPPA_LTSEL = 0x10,
+R_HPPA_RTSEL = 0x11,
+R_HPPA_LTPSEL = 0x12,
+R_HPPA_RTPSEL = 0x13
+  };
+
+/* /usr/include/reloc.h defines these to constants.  We want to use
+   them in enums, so #undef them before we start using them.  We might
+   be able to fix this another way by simply managing not to include
+   /usr/include/reloc.h, but currently GDB picks 

[Qemu-devel] [PULL 14/26] linux-user: Add HPPA target_signal.h and target_cpu.h

2017-01-22 Thread Richard Henderson
The cpu.h structure that these manipulate hasn't been defined
yet, but we haven't enabled compilation yet either.

Signed-off-by: Richard Henderson 
---
 linux-user/hppa/target_cpu.h| 35 +++
 linux-user/hppa/target_signal.h | 29 +
 2 files changed, 64 insertions(+)
 create mode 100644 linux-user/hppa/target_cpu.h
 create mode 100644 linux-user/hppa/target_signal.h

diff --git a/linux-user/hppa/target_cpu.h b/linux-user/hppa/target_cpu.h
new file mode 100644
index 000..1a5ceca
--- /dev/null
+++ b/linux-user/hppa/target_cpu.h
@@ -0,0 +1,35 @@
+/*
+ * HPPA specific CPU ABI and functions for linux-user
+ *
+ *  Copyright (c) 2016  Richard Henderson
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see .
+ */
+#ifndef ALPHA_TARGET_CPU_H
+#define ALPHA_TARGET_CPU_H
+
+static inline void cpu_clone_regs(CPUHPPAState *env, target_ulong newsp)
+{
+if (newsp) {
+env->gr[30] = newsp;
+}
+env->gr[28] = 0;
+}
+
+static inline void cpu_set_tls(CPUHPPAState *env, target_ulong newtls)
+{
+env->cr27 = newtls;
+}
+
+#endif
diff --git a/linux-user/hppa/target_signal.h b/linux-user/hppa/target_signal.h
new file mode 100644
index 000..e115890
--- /dev/null
+++ b/linux-user/hppa/target_signal.h
@@ -0,0 +1,29 @@
+#ifndef HPPA_TARGET_SIGNAL_H
+#define HPPA_TARGET_SIGNAL_H
+
+#include "cpu.h"
+
+/* this struct defines a stack used during syscall handling */
+
+typedef struct target_sigaltstack {
+abi_ulong ss_sp;
+int32_t ss_flags;
+abi_ulong ss_size;
+} target_stack_t;
+
+
+/*
+ * sigaltstack controls
+ */
+#define TARGET_SS_ONSTACK  1
+#define TARGET_SS_DISABLE  2
+
+#define TARGET_MINSIGSTKSZ 2048
+#define TARGET_SIGSTKSZ8192
+
+static inline abi_ulong get_sp_from_cpustate(CPUHPPAState *state)
+{
+return state->gr[30];
+}
+
+#endif /* HPPA_TARGET_SIGNAL_H */
-- 
2.9.3




[Qemu-devel] [PULL 09/26] linux-user: Add HPPA syscall numbers

2017-01-22 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/hppa/syscall_nr.h | 353 +++
 1 file changed, 353 insertions(+)
 create mode 100644 linux-user/hppa/syscall_nr.h

diff --git a/linux-user/hppa/syscall_nr.h b/linux-user/hppa/syscall_nr.h
new file mode 100644
index 000..0f396fa
--- /dev/null
+++ b/linux-user/hppa/syscall_nr.h
@@ -0,0 +1,353 @@
+/*
+ * This file contains the system call numbers.
+ */
+
+#define TARGET_NR_restart_syscall 0
+#define TARGET_NR_exit1
+#define TARGET_NR_fork2
+#define TARGET_NR_read3
+#define TARGET_NR_write   4
+#define TARGET_NR_open5
+#define TARGET_NR_close   6
+#define TARGET_NR_waitpid 7
+#define TARGET_NR_creat   8
+#define TARGET_NR_link9
+#define TARGET_NR_unlink 10
+#define TARGET_NR_execve 11
+#define TARGET_NR_chdir  12
+#define TARGET_NR_time   13
+#define TARGET_NR_mknod  14
+#define TARGET_NR_chmod  15
+#define TARGET_NR_lchown 16
+#define TARGET_NR_socket 17
+#define TARGET_NR_stat   18
+#define TARGET_NR_lseek  19
+#define TARGET_NR_getpid 20
+#define TARGET_NR_mount  21
+#define TARGET_NR_bind   22
+#define TARGET_NR_setuid 23
+#define TARGET_NR_getuid 24
+#define TARGET_NR_stime  25
+#define TARGET_NR_ptrace 26
+#define TARGET_NR_alarm  27
+#define TARGET_NR_fstat  28
+#define TARGET_NR_pause  29
+#define TARGET_NR_utime  30
+#define TARGET_NR_connect31
+#define TARGET_NR_listen 32
+#define TARGET_NR_access 33
+#define TARGET_NR_nice   34
+#define TARGET_NR_accept 35
+#define TARGET_NR_sync   36
+#define TARGET_NR_kill   37
+#define TARGET_NR_rename 38
+#define TARGET_NR_mkdir  39
+#define TARGET_NR_rmdir  40
+#define TARGET_NR_dup41
+#define TARGET_NR_pipe   42
+#define TARGET_NR_times  43
+#define TARGET_NR_getsockname44
+#define TARGET_NR_brk45
+#define TARGET_NR_setgid 46
+#define TARGET_NR_getgid 47
+#define TARGET_NR_signal 48
+#define TARGET_NR_geteuid49
+#define TARGET_NR_getegid50
+#define TARGET_NR_acct   51
+#define TARGET_NR_umount252
+#define TARGET_NR_getpeername53
+#define TARGET_NR_ioctl  54
+#define TARGET_NR_fcntl  55
+#define TARGET_NR_socketpair 56
+#define TARGET_NR_setpgid57
+#define TARGET_NR_send   58
+#define TARGET_NR_uname  59
+#define TARGET_NR_umask  60
+#define TARGET_NR_chroot 61
+#define TARGET_NR_ustat  62
+#define TARGET_NR_dup2   63
+#define TARGET_NR_getppid64
+#define TARGET_NR_getpgrp65
+#define TARGET_NR_setsid 66
+#define TARGET_NR_pivot_root 67
+#define TARGET_NR_sgetmask   68
+#define TARGET_NR_ssetmask   69
+#define TARGET_NR_setreuid   70
+#define TARGET_NR_setregid   71
+#define TARGET_NR_mincore72
+#define TARGET_NR_sigpending 73
+#define TARGET_NR_sethostname74
+#define TARGET_NR_setrlimit  75
+#define TARGET_NR_getrlimit  76
+#define TARGET_NR_getrusage  77
+#define TARGET_NR_gettimeofday   78
+#define TARGET_NR_settimeofday   79
+#define TARGET_NR_getgroups  80
+#define TARGET_NR_setgroups  81
+#define TARGET_NR_sendto 82
+#define TARGET_NR_symlink83
+#define TARGET_NR_lstat  84
+#define TARGET_NR_readlink   85
+#define TARGET_NR_uselib 86
+#define TARGET_NR_swapon 87
+#define TARGET_NR_reboot 88
+#define TARGET_NR_mmap2  89
+#define TARGET_NR_mmap   90
+#define TARGET_NR_munmap 91
+#define TARGET_NR_truncate   92
+#define TARGET_NR_ftruncate  93
+#define TARGET_NR_fchmod 94
+#define TARGET_NR_fchown 95
+#define TARGET_NR_getpriority96
+#define TARGET_NR_setpriority97
+#define TARGET_NR_recv   98
+#define TARGET_NR_statfs 99
+#define TARGET_NR_fstatfs   100
+#define TARGET_NR_stat64101
+#define TARGET_NR_socketcall102
+#define TARGET_NR_syslog103
+#define TARGET_NR_setitimer 104
+#define TARGET_NR_getitimer 105
+#define TARGET_NR_capget106
+#define TARGET_NR_capset107
+#define TARGET_NR_pread64   108
+#define TARGET_NR_pwrite64  109
+#define TARGET_NR_getcwd110
+#define TARGET_NR_vhangup   111
+#define TARGET_NR_fstat64   112
+#define TARGET_NR_vfork 113
+#define TARGET_NR_wait4 114
+#define TARGET_NR_swapoff   115
+#define TARGET_NR_sysinfo   116
+#define TARGET_NR_shutdown  117
+#define TARGET_NR_fsync 118
+#define TARGET_NR_madvise   119
+#define TARGET_NR_clone 120
+#define TARGET_NR_setdomainname 121
+#define 

[Qemu-devel] [PULL 16/26] linux-user: Add HPPA startup and main loop

2017-01-22 Thread Richard Henderson
Including support for the atomic memory op syscalls.

Signed-off-by: Richard Henderson 
---
 linux-user/elfload.c |  24 +++
 linux-user/main.c| 172 +++
 2 files changed, 196 insertions(+)

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 5cea39d..51794bb 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -1215,6 +1215,30 @@ static inline void init_thread(struct target_pt_regs 
*regs,
 
 #endif /* TARGET_TILEGX */
 
+#ifdef TARGET_HPPA
+
+#define ELF_START_MMAP  0x8000
+#define ELF_CLASS   ELFCLASS32
+#define ELF_ARCHEM_PARISC
+#define ELF_PLATFORM"PARISC"
+#define STACK_GROWS_DOWN 0
+#define STACK_ALIGNMENT  64
+
+static inline void init_thread(struct target_pt_regs *regs,
+   struct image_info *infop)
+{
+regs->iaoq[0] = infop->entry;
+regs->iaoq[1] = infop->entry + 4;
+regs->gr[23] = 0;
+regs->gr[24] = infop->arg_start;
+regs->gr[25] = (infop->arg_end - infop->arg_start) / sizeof(abi_ulong);
+/* The top-of-stack contains a linkage buffer.  */
+regs->gr[30] = infop->start_stack + 64;
+regs->gr[31] = infop->entry;
+}
+
+#endif /* TARGET_HPPA */
+
 #ifndef ELF_PLATFORM
 #define ELF_PLATFORM (NULL)
 #endif
diff --git a/linux-user/main.c b/linux-user/main.c
index aae29bd..db4eb68 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -3512,6 +3512,169 @@ void cpu_loop(CPUTLGState *env)
 
 #endif
 
+#ifdef TARGET_HPPA
+
+static abi_ulong hppa_lws(CPUHPPAState *env)
+{
+uint32_t which = env->gr[20];
+abi_ulong addr = env->gr[26];
+abi_ulong old = env->gr[25];
+abi_ulong new = env->gr[24];
+abi_ulong size, ret;
+
+switch (which) {
+default:
+return -TARGET_ENOSYS;
+
+case 0: /* elf32 atomic 32bit cmpxchg */
+if ((addr & 3) || !access_ok(VERIFY_WRITE, addr, 4)) {
+return -TARGET_EFAULT;
+}
+old = tswap32(old);
+new = tswap32(new);
+ret = atomic_cmpxchg((uint32_t *)g2h(addr), old, new);
+ret = tswap32(ret);
+break;
+
+case 2: /* elf32 atomic "new" cmpxchg */
+size = env->gr[23];
+if (size >= 4) {
+return -TARGET_ENOSYS;
+}
+if (((addr | old | new) & ((1 << size) - 1))
+|| !access_ok(VERIFY_WRITE, addr, 1 << size)
+|| !access_ok(VERIFY_READ, old, 1 << size)
+|| !access_ok(VERIFY_READ, new, 1 << size)) {
+return -TARGET_EFAULT;
+}
+/* Note that below we use host-endian loads so that the cmpxchg
+   can be host-endian as well.  */
+switch (size) {
+case 0:
+old = *(uint8_t *)g2h(old);
+new = *(uint8_t *)g2h(new);
+ret = atomic_cmpxchg((uint8_t *)g2h(addr), old, new);
+ret = ret != old;
+break;
+case 1:
+old = *(uint16_t *)g2h(old);
+new = *(uint16_t *)g2h(new);
+ret = atomic_cmpxchg((uint16_t *)g2h(addr), old, new);
+ret = ret != old;
+break;
+case 2:
+old = *(uint32_t *)g2h(old);
+new = *(uint32_t *)g2h(new);
+ret = atomic_cmpxchg((uint32_t *)g2h(addr), old, new);
+ret = ret != old;
+break;
+case 3:
+{
+uint64_t o64, n64, r64;
+o64 = *(uint64_t *)g2h(old);
+n64 = *(uint64_t *)g2h(new);
+#ifdef CONFIG_ATOMIC64
+r64 = atomic_cmpxchg__nocheck((uint64_t *)g2h(addr), o64, n64);
+ret = r64 != o64;
+#else
+start_exclusive();
+r64 = *(uint64_t *)g2h(addr);
+ret = 1;
+if (r64 == o64) {
+*(uint64_t *)g2h(addr) = n64;
+ret = 0;
+}
+end_exclusive();
+#endif
+}
+break;
+}
+break;
+}
+
+env->gr[28] = ret;
+return 0;
+}
+
+void cpu_loop(CPUHPPAState *env)
+{
+CPUState *cs = CPU(hppa_env_get_cpu(env));
+target_siginfo_t info;
+abi_ulong ret;
+int trapnr;
+
+while (1) {
+cpu_exec_start(cs);
+trapnr = cpu_exec(cs);
+cpu_exec_end(cs);
+process_queued_cpu_work(cs);
+
+switch (trapnr) {
+case EXCP_SYSCALL:
+ret = do_syscall(env, env->gr[20],
+ env->gr[26], env->gr[25],
+ env->gr[24], env->gr[23],
+ env->gr[22], env->gr[21], 0, 0);
+switch (ret) {
+default:
+env->gr[28] = ret;
+/* We arrived here by faking the gateway page.  Return.  */
+env->iaoq_f = env->gr[31];
+env->iaoq_b = env->gr[31] + 4;
+break;
+case -TARGET_ERESTARTSYS:
+case 

[Qemu-devel] [PULL 13/26] linux-user: Add HPPA target_structs.h

2017-01-22 Thread Richard Henderson
Signed-off-by: Richard Henderson 
---
 linux-user/hppa/target_structs.h | 54 
 1 file changed, 54 insertions(+)
 create mode 100644 linux-user/hppa/target_structs.h

diff --git a/linux-user/hppa/target_structs.h b/linux-user/hppa/target_structs.h
new file mode 100644
index 000..b560b18
--- /dev/null
+++ b/linux-user/hppa/target_structs.h
@@ -0,0 +1,54 @@
+/*
+ * HPPA specific structures for linux-user
+ *
+ * Copyright (c) 2016  Richard Henderson
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see .
+ */
+#ifndef HPPA_TARGET_STRUCTS_H
+#define HPPA_TARGET_STRUCTS_H
+
+struct target_ipc_perm {
+abi_int __key;  /* Key.  */
+abi_uint uid;   /* Owner's user ID.  */
+abi_uint gid;   /* Owner's group ID.  */
+abi_uint cuid;  /* Creator's user ID.  */
+abi_uint cgid;  /* Creator's group ID.  */
+abi_ushort __pad1;
+abi_ushort mode;/* Read/write permission.  */
+abi_ushort __pad2;
+abi_ushort __seq;   /* Sequence number.  */
+abi_uint __pad3;
+uint64_t __unused1;
+uint64_t __unused2;
+};
+
+struct target_shmid_ds {
+struct target_ipc_perm shm_perm;/* operation permission struct */
+abi_uint __pad1;
+abi_ulong shm_atime;/* time of last shmat() */
+abi_uint __pad2;
+abi_ulong shm_dtime;/* time of last shmdt() */
+abi_uint __pad3;
+abi_ulong shm_ctime;/* time of last change by shmctl() */
+abi_uint __pad4;
+abi_long shm_segsz; /* size of segment in bytes */
+abi_int shm_cpid;   /* pid of creator */
+abi_int shm_lpid;   /* pid of last shmop */
+abi_ulong shm_nattch;   /* number of current attaches */
+abi_ulong __unused1;
+abi_ulong __unused2;
+};
+
+#endif
-- 
2.9.3




[Qemu-devel] [PULL 06/26] linux-user: Handle more IPV6 sockopts

2017-01-22 Thread Richard Henderson
All of the ones added have an "int" parameter that
needs no more adjustment to pass on to the host.

Signed-off-by: Richard Henderson 
---
 linux-user/syscall.c | 29 +++--
 1 file changed, 27 insertions(+), 2 deletions(-)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 11a311f..0b2b283 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -2811,10 +2811,35 @@ static abi_long do_setsockopt(int sockfd, int level, 
int optname,
 break;
 case SOL_IPV6:
 switch (optname) {
-case IPV6_MTU_DISCOVER:
-case IPV6_MTU:
 case IPV6_V6ONLY:
 case IPV6_RECVPKTINFO:
+case IPV6_2292PKTINFO:
+case IPV6_RECVHOPLIMIT:
+case IPV6_2292HOPLIMIT:
+case IPV6_RECVRTHDR:
+case IPV6_2292RTHDR:
+case IPV6_RECVHOPOPTS:
+case IPV6_2292HOPOPTS:
+case IPV6_RECVDSTOPTS:
+case IPV6_2292DSTOPTS:
+case IPV6_TCLASS:
+case IPV6_RECVTCLASS:
+case IPV6_RECVPATHMTU:
+case IPV6_TRANSPARENT:
+case IPV6_RECVORIGDSTADDR:
+case IPV6_UNICAST_HOPS:
+case IPV6_MULTICAST_HOPS:
+case IPV6_MULTICAST_LOOP:
+case IPV6_UNICAST_IF:
+case IPV6_MULTICAST_IF:
+case IPV6_ROUTER_ALERT:
+case IPV6_MTU_DISCOVER:
+case IPV6_MTU:
+case IPV6_RECVERR:
+case IPV6_ADDR_PREFERENCES:
+case IPV6_MINHOPCOUNT:
+case IPV6_DONTFRAG:
+case IPV6_AUTOFLOWLABEL:
 val = 0;
 if (optlen < sizeof(uint32_t)) {
 return -TARGET_EINVAL;
-- 
2.9.3




[Qemu-devel] [PULL 05/26] linux-user: Handle ERFKILL and EHWPOISON

2017-01-22 Thread Richard Henderson
With definitions for generic, alpha and mips taken from 4.9-rc2.

Signed-off-by: Richard Henderson 
---
 linux-user/alpha/target_syscall.h  | 2 ++
 linux-user/errno_defs.h| 3 +++
 linux-user/mips/target_syscall.h   | 5 +
 linux-user/mips64/target_syscall.h | 5 +
 linux-user/syscall.c   | 6 ++
 5 files changed, 21 insertions(+)

diff --git a/linux-user/alpha/target_syscall.h 
b/linux-user/alpha/target_syscall.h
index b580fc5..3426cc5 100644
--- a/linux-user/alpha/target_syscall.h
+++ b/linux-user/alpha/target_syscall.h
@@ -235,6 +235,8 @@ struct target_pt_regs {
 #define TARGET_ENOTRECOVERABLE 137
 #undef TARGET_ERFKILL
 #define TARGET_ERFKILL 138
+#undef TARGET_EHWPOISON
+#define TARGET_EHWPOISON139
 
 // For sys_osf_getsysinfo
 #define TARGET_GSI_UACPROC 8
diff --git a/linux-user/errno_defs.h b/linux-user/errno_defs.h
index 65522c4..55fbebd 100644
--- a/linux-user/errno_defs.h
+++ b/linux-user/errno_defs.h
@@ -140,6 +140,9 @@
 #define TARGET_EOWNERDEAD  130 /* Owner died */
 #define TARGET_ENOTRECOVERABLE 131 /* State not recoverable */
 
+#define TARGET_ERFKILL 132 /* Operation not possible due to 
RF-kill */
+#define TARGET_EHWPOISON   133 /* Memory page has hardware error */
+
 /* QEMU internal, not visible to the guest. This is returned when a
  * system call should be restarted, to tell the main loop that it
  * should wind the guest PC backwards so it will re-execute the syscall
diff --git a/linux-user/mips/target_syscall.h b/linux-user/mips/target_syscall.h
index 0b64b73..2fca1c6 100644
--- a/linux-user/mips/target_syscall.h
+++ b/linux-user/mips/target_syscall.h
@@ -221,6 +221,11 @@ struct target_pt_regs {
 #undef TARGET_ENOTRECOVERABLE
 #define TARGET_ENOTRECOVERABLE 166 /* State not recoverable */
 
+#undef TARGET_ERFKILL
+#define TARGET_ERFKILL 167
+#undef TARGET_EHWPOISON
+#define TARGET_EHWPOISON   168
+
 #undef TARGET_EDQUOT
 #define TARGET_EDQUOT  1133/* Quota exceeded */
 
diff --git a/linux-user/mips64/target_syscall.h 
b/linux-user/mips64/target_syscall.h
index 6692917..078437d 100644
--- a/linux-user/mips64/target_syscall.h
+++ b/linux-user/mips64/target_syscall.h
@@ -218,6 +218,11 @@ struct target_pt_regs {
 #undef TARGET_ENOTRECOVERABLE
 #define TARGET_ENOTRECOVERABLE 166 /* State not recoverable */
 
+#undef TARGET_ERFKILL
+#define TARGET_ERFKILL 167
+#undef TARGET_EHWPOISON
+#define TARGET_EHWPOISON   168
+
 #undef TARGET_EDQUOT
 #define TARGET_EDQUOT  1133/* Quota exceeded */
 
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index acb004f..11a311f 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -798,6 +798,12 @@ static uint16_t 
host_to_target_errno_table[ERRNO_TABLE_SIZE] = {
 #ifdef ENOMSG
 [ENOMSG]= TARGET_ENOMSG,
 #endif
+#ifdef ERKFILL
+[ERFKILL]   = TARGET_ERFKILL,
+#endif
+#ifdef EHWPOISON
+[EHWPOISON] = TARGET_EHWPOISON,
+#endif
 };
 
 static inline int host_to_target_errno(int err)
-- 
2.9.3




[Qemu-devel] [PULL 17/26] target-hppa: Add softfloat specializations

2017-01-22 Thread Richard Henderson
Like the original MIPS, HPPA has the MSB of an SNaN set.
However, it has different rules for silencing an SNaN:
(1) msb is cleared and (2) msb-1 must be set if the fraction
is now zero, and (implementation defined) may be set always.
I haven't checked real hardware but chose the set always
alternative because it's easy and within spec.

Signed-off-by: Richard Henderson 
---
 fpu/softfloat-specialize.h | 20 +++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h
index f5aed72..f05c865 100644
--- a/fpu/softfloat-specialize.h
+++ b/fpu/softfloat-specialize.h
@@ -116,6 +116,8 @@ float32 float32_default_nan(float_status *status)
 #elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA) || \
   defined(TARGET_XTENSA) || defined(TARGET_S390X) || 
defined(TARGET_TRICORE)
 return const_float32(0x7FC0);
+#elif defined(TARGET_HPPA)
+return const_float32(0x7FA0);
 #else
 if (status->snan_bit_is_one) {
 return const_float32(0x7FBF);
@@ -139,6 +141,8 @@ float64 float64_default_nan(float_status *status)
 #elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA) || \
   defined(TARGET_S390X)
 return const_float64(LIT64(0x7FF8));
+#elif defined(TARGET_HPPA)
+return const_float64(LIT64(0x7FF4));
 #else
 if (status->snan_bit_is_one) {
 return const_float64(LIT64(0x7FF7));
@@ -361,7 +365,14 @@ float32 float32_maybe_silence_nan(float32 a_, float_status 
*status)
 {
 if (float32_is_signaling_nan(a_, status)) {
 if (status->snan_bit_is_one) {
+#ifdef TARGET_HPPA
+uint32_t a = float32_val(a_);
+a &= ~0x0040;
+a |=  0x0020;
+return make_float32(a);
+#else
 return float32_default_nan(status);
+#endif
 } else {
 uint32_t a = float32_val(a_);
 a |= (1 << 22);
@@ -449,7 +460,7 @@ static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag 
bIsQNaN, flag bIsSNaN,
 return 1;
 }
 }
-#elif defined(TARGET_MIPS)
+#elif defined(TARGET_MIPS) || defined(TARGET_HPPA)
 static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
 flag aIsLargerSignificand)
 {
@@ -794,7 +805,14 @@ float64 float64_maybe_silence_nan(float64 a_, float_status 
*status)
 {
 if (float64_is_signaling_nan(a_, status)) {
 if (status->snan_bit_is_one) {
+#ifdef TARGET_HPPA
+uint64_t a = float64_val(a_);
+a &= ~0x0008ULL;
+a |=  0x0004ULL;
+return make_float64(a);
+#else
 return float64_default_nan(status);
+#endif
 } else {
 uint64_t a = float64_val(a_);
 a |= LIT64(0x0008);
-- 
2.9.3




[Qemu-devel] [PULL 08/26] linux-user: Add HPPA socket.h definitions

2017-01-22 Thread Richard Henderson
Split this out into a "cpu/sockbits.h" file now,
like we ought to do for all of the other targets.

Signed-off-by: Richard Henderson 
---
 linux-user/hppa/sockbits.h | 97 ++
 linux-user/socket.h|  2 +
 2 files changed, 99 insertions(+)
 create mode 100644 linux-user/hppa/sockbits.h

diff --git a/linux-user/hppa/sockbits.h b/linux-user/hppa/sockbits.h
new file mode 100644
index 000..5044619
--- /dev/null
+++ b/linux-user/hppa/sockbits.h
@@ -0,0 +1,97 @@
+#define TARGET_SOL_SOCKET  0x
+
+#define TARGET_SO_DEBUG0x0001
+#define TARGET_SO_REUSEADDR0x0004
+#define TARGET_SO_KEEPALIVE0x0008
+#define TARGET_SO_DONTROUTE0x0010
+#define TARGET_SO_BROADCAST0x0020
+#define TARGET_SO_LINGER   0x0080
+#define TARGET_SO_OOBINLINE0x0100
+#define TARGET_SO_REUSEPORT0x0200
+#define TARGET_SO_SNDBUF   0x1001
+#define TARGET_SO_RCVBUF   0x1002
+#define TARGET_SO_SNDBUFFORCE  0x100a
+#define TARGET_SO_RCVBUFFORCE  0x100b
+#define TARGET_SO_SNDLOWAT 0x1003
+#define TARGET_SO_RCVLOWAT 0x1004
+#define TARGET_SO_SNDTIMEO 0x1005
+#define TARGET_SO_RCVTIMEO 0x1006
+#define TARGET_SO_ERROR0x1007
+#define TARGET_SO_TYPE 0x1008
+#define TARGET_SO_PROTOCOL 0x1028
+#define TARGET_SO_DOMAIN   0x1029
+#define TARGET_SO_PEERNAME 0x2000
+#define TARGET_SO_NO_CHECK 0x400b
+#define TARGET_SO_PRIORITY 0x400c
+#define TARGET_SO_BSDCOMPAT0x400e
+#define TARGET_SO_PASSCRED 0x4010
+#define TARGET_SO_PEERCRED 0x4011
+#define TARGET_SO_TIMESTAMP0x4012
+#define TARGET_SCM_TIMESTAMP   TARGET_SO_TIMESTAMP
+#define TARGET_SO_TIMESTAMPNS  0x4013
+#define TARGET_SCM_TIMESTAMPNS TARGET_SO_TIMESTAMPNS
+
+#define TARGET_SO_SECURITY_AUTHENTICATION  0x4016
+#define TARGET_SO_SECURITY_ENCRYPTION_TRANSPORT0x4017
+#define TARGET_SO_SECURITY_ENCRYPTION_NETWORK  0x4018
+
+#define TARGET_SO_BINDTODEVICE 0x4019
+#define TARGET_SO_ATTACH_FILTER0x401a
+#define TARGET_SO_DETACH_FILTER0x401b
+#define TARGET_SO_GET_FILTER   TARGET_SO_ATTACH_FILTER
+#define TARGET_SO_ACCEPTCONN   0x401c
+#define TARGET_SO_PEERSEC  0x401d
+#define TARGET_SO_PASSSEC  0x401e
+#define TARGET_SO_MARK 0x401f
+#define TARGET_SO_TIMESTAMPING 0x4020
+#define TARGET_SCM_TIMESTAMPINGTARGET_SO_TIMESTAMPING
+#define TARGET_SO_RXQ_OVFL 0x4021
+#define TARGET_SO_WIFI_STATUS  0x4022
+#define TARGET_SCM_WIFI_STATUS TARGET_SO_WIFI_STATUS
+#define TARGET_SO_PEEK_OFF 0x4023
+#define TARGET_SO_NOFCS0x4024
+#define TARGET_SO_LOCK_FILTER  0x4025
+#define TARGET_SO_SELECT_ERR_QUEUE 0x4026
+#define TARGET_SO_BUSY_POLL0x4027
+#define TARGET_SO_MAX_PACING_RATE  0x4028
+#define TARGET_SO_BPF_EXTENSIONS   0x4029
+#define TARGET_SO_INCOMING_CPU 0x402A
+#define TARGET_SO_ATTACH_BPF   0x402B
+#define TARGET_SO_DETACH_BPF   TARGET_SO_DETACH_FILTER
+
+#define TARGET_SO_ATTACH_REUSEPORT_CBPF0x402C
+#define TARGET_SO_ATTACH_REUSEPORT_EBPF0x402D
+
+#define TARGET_SO_CNX_ADVICE   0x402E
+
+/** sock_type - Socket types - default values
+ *
+ *
+ * @SOCK_STREAM - stream (connection) socket
+ * @SOCK_DGRAM - datagram (conn.less) socket
+ * @SOCK_RAW - raw socket
+ * @SOCK_RDM - reliably-delivered message
+ * @SOCK_SEQPACKET - sequential packet socket
+ * @SOCK_DCCP - Datagram Congestion Control Protocol socket
+ * @SOCK_PACKET - linux specific way of getting packets at the dev level.
+ *For writing rarp and other similar things on the user
+ *level.
+ * @SOCK_CLOEXEC - sets the close-on-exec (FD_CLOEXEC) flag.
+ * @SOCK_NONBLOCK - sets the O_NONBLOCK file status flag.
+ */
+enum sock_type {
+   TARGET_SOCK_STREAM  = 1,
+   TARGET_SOCK_DGRAM   = 2,
+   TARGET_SOCK_RAW = 3,
+   TARGET_SOCK_RDM = 4,
+   TARGET_SOCK_SEQPACKET   = 5,
+   TARGET_SOCK_DCCP= 6,
+   TARGET_SOCK_PACKET  = 10,
+   TARGET_SOCK_CLOEXEC = 01000,
+   TARGET_SOCK_NONBLOCK= 0x4000,
+};
+
+#define TARGET_SOCK_MAX (TARGET_SOCK_PACKET + 1)
+#define TARGET_SOCK_TYPE_MASK0xf  /* Covers up to TARGET_SOCK_MAX-1. */
+
+#define ARCH_HAS_SOCKET_TYPES 1
diff --git a/linux-user/socket.h b/linux-user/socket.h
index 4dacae6..7051cd2 100644
--- a/linux-user/socket.h
+++ b/linux-user/socket.h
@@ -205,6 +205,8 @@
 
 #define TARGET_SOCK_MAX (TARGET_SOCK_PACKET + 1)
 #define TARGET_SOCK_TYPE_MASK0xf  /* Covers up to TARGET_SOCK_MAX-1. */
+#elif defined(TARGET_HPPA)
+#include 
 #else
 
 #if defined(TARGET_SPARC)
-- 
2.9.3




[Qemu-devel] [PULL 04/26] linux-user: Add SIOCGPGRP, SIOCGSTAMP, SIOCGSTAMPNS

2017-01-22 Thread Richard Henderson
From: Helge Deller 

Mirror syscall_defs.h for the element type of struct timeval
and struct timespec, even though that's not 100% accurate for
each guest.

Signed-off-by: Helge Deller 
[rth: Changed the MK_ARRAY types as per above; added ioctl.h entries.]
Signed-off-by: Richard Henderson 
---
 linux-user/ioctls.h| 3 +++
 linux-user/syscall_defs.h  | 4 
 linux-user/syscall_types.h | 6 ++
 3 files changed, 13 insertions(+)

diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h
index eaf6fe6..2f6e85b 100644
--- a/linux-user/ioctls.h
+++ b/linux-user/ioctls.h
@@ -164,6 +164,9 @@
   IOCTL(SIOCSRARP, IOC_W, MK_PTR(MK_STRUCT(STRUCT_arpreq)))
   IOCTL(SIOCGRARP, IOC_R, MK_PTR(MK_STRUCT(STRUCT_arpreq)))
   IOCTL(SIOCGIWNAME, IOC_W | IOC_R, MK_PTR(MK_STRUCT(STRUCT_char_ifreq)))
+  IOCTL(SIOCGPGRP, IOC_R, MK_PTR(TYPE_INT)) /* pid_t */
+  IOCTL(SIOCGSTAMP, IOC_R, MK_PTR(MK_STRUCT(STRUCT_timeval)))
+  IOCTL(SIOCGSTAMPNS, IOC_R, MK_PTR(MK_STRUCT(STRUCT_timespec)))
 
   IOCTL(CDROMPAUSE, 0, TYPE_NULL)
   IOCTL(CDROMSTART, 0, TYPE_NULL)
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index 7607df8..55ae367 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -930,9 +930,13 @@ struct target_pollfd {
 
 #if defined(TARGET_ALPHA) || defined(TARGET_MIPS) || defined(TARGET_SH4)
 #define TARGET_SIOCATMARK  TARGET_IOR('s', 7, int)
+#define TARGET_SIOCGPGRP   TARGET_IOR('s', 9, pid_t)
 #else
 #define TARGET_SIOCATMARK  0x8905
+#define TARGET_SIOCGPGRP   0x8904
 #endif
+#define TARGET_SIOCGSTAMP  0x8906  /* Get stamp (timeval) */
+#define TARGET_SIOCGSTAMPNS0x8907  /* Get stamp (timespec) */
 
 /* Networking ioctls */
 #define TARGET_SIOCADDRT   0x890B  /* add routing table entry */
diff --git a/linux-user/syscall_types.h b/linux-user/syscall_types.h
index af79fbf..2b8c0c6 100644
--- a/linux-user/syscall_types.h
+++ b/linux-user/syscall_types.h
@@ -14,6 +14,12 @@ STRUCT(serial_icounter_struct,
 STRUCT(sockaddr,
TYPE_SHORT, MK_ARRAY(TYPE_CHAR, 14))
 
+STRUCT(timeval,
+   MK_ARRAY(TYPE_LONG, 2))
+
+STRUCT(timespec,
+   MK_ARRAY(TYPE_LONG, 2))
+
 STRUCT(rtentry,
TYPE_ULONG, MK_STRUCT(STRUCT_sockaddr), MK_STRUCT(STRUCT_sockaddr), 
MK_STRUCT(STRUCT_sockaddr),
TYPE_SHORT, TYPE_SHORT, TYPE_ULONG, TYPE_PTRVOID, TYPE_SHORT, 
TYPE_PTRVOID,
-- 
2.9.3




[Qemu-devel] [PULL 02/26] linux-user: Support stack-grows-up in elfload.c

2017-01-22 Thread Richard Henderson
HPPA is a (the) stack-grows-up target, and supporting that requires
rearranging how we compute addresses while laying out the initial
program stack.  In addition, hppa32 requires 64-byte stack alignment
so parameterize that as well.

Signed-off-by: Richard Henderson 
---
 linux-user/elfload.c | 235 +--
 linux-user/main.c|  13 +--
 linux-user/qemu.h|   3 +
 3 files changed, 180 insertions(+), 71 deletions(-)

diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 547053c..5cea39d 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -1231,6 +1231,14 @@ static inline void init_thread(struct target_pt_regs 
*regs,
 #define ELF_HWCAP 0
 #endif
 
+#ifndef STACK_GROWS_DOWN
+#define STACK_GROWS_DOWN 1
+#endif
+
+#ifndef STACK_ALIGNMENT
+#define STACK_ALIGNMENT 16
+#endif
+
 #ifdef TARGET_ABI32
 #undef ELF_CLASS
 #define ELF_CLASS ELFCLASS32
@@ -1374,45 +1382,78 @@ static abi_ulong copy_elf_strings(int argc, char 
**argv, char *scratch,
   abi_ulong p, abi_ulong stack_limit)
 {
 char *tmp;
-int len, offset;
+int len, i;
 abi_ulong top = p;
 
 if (!p) {
 return 0;   /* bullet-proofing */
 }
 
-offset = ((p - 1) % TARGET_PAGE_SIZE) + 1;
+if (STACK_GROWS_DOWN) {
+int offset = ((p - 1) % TARGET_PAGE_SIZE) + 1;
+for (i = argc - 1; i >= 0; --i) {
+tmp = argv[i];
+if (!tmp) {
+fprintf(stderr, "VFS: argc is wrong");
+exit(-1);
+}
+len = strlen(tmp) + 1;
+tmp += len;
 
-while (argc-- > 0) {
-tmp = argv[argc];
-if (!tmp) {
-fprintf(stderr, "VFS: argc is wrong");
-exit(-1);
+if (len > (p - stack_limit)) {
+return 0;
+}
+while (len) {
+int bytes_to_copy = (len > offset) ? offset : len;
+tmp -= bytes_to_copy;
+p -= bytes_to_copy;
+offset -= bytes_to_copy;
+len -= bytes_to_copy;
+
+memcpy_fromfs(scratch + offset, tmp, bytes_to_copy);
+
+if (offset == 0) {
+memcpy_to_target(p, scratch, top - p);
+top = p;
+offset = TARGET_PAGE_SIZE;
+}
+}
 }
-len = strlen(tmp) + 1;
-tmp += len;
-
-if (len > (p - stack_limit)) {
-return 0;
+if (p != top) {
+memcpy_to_target(p, scratch + offset, top - p);
 }
-while (len) {
-int bytes_to_copy = (len > offset) ? offset : len;
-tmp -= bytes_to_copy;
-p -= bytes_to_copy;
-offset -= bytes_to_copy;
-len -= bytes_to_copy;
-
-memcpy_fromfs(scratch + offset, tmp, bytes_to_copy);
-
-if (offset == 0) {
-memcpy_to_target(p, scratch, top - p);
-top = p;
-offset = TARGET_PAGE_SIZE;
+} else {
+int remaining = TARGET_PAGE_SIZE - (p % TARGET_PAGE_SIZE);
+for (i = 0; i < argc; ++i) {
+tmp = argv[i];
+if (!tmp) {
+fprintf(stderr, "VFS: argc is wrong");
+exit(-1);
+}
+len = strlen(tmp) + 1;
+if (len > (stack_limit - p)) {
+return 0;
+}
+while (len) {
+int bytes_to_copy = (len > remaining) ? remaining : len;
+
+memcpy_fromfs(scratch + (p - top), tmp, bytes_to_copy);
+
+tmp += bytes_to_copy;
+remaining -= bytes_to_copy;
+p += bytes_to_copy;
+len -= bytes_to_copy;
+
+if (remaining == 0) {
+memcpy_to_target(top, scratch, p - top);
+top = p;
+remaining = TARGET_PAGE_SIZE;
+}
 }
 }
-}
-if (offset) {
-memcpy_to_target(p, scratch + offset, top - p);
+if (p != top) {
+memcpy_to_target(top, scratch, p - top);
+}
 }
 
 return p;
@@ -1447,11 +1488,15 @@ static abi_ulong setup_arg_pages(struct linux_binprm 
*bprm,
 }
 
 /* We reserve one extra page at the top of the stack as guard.  */
-target_mprotect(error, guard, PROT_NONE);
-
-info->stack_limit = error + guard;
-
-return info->stack_limit + size - sizeof(void *);
+if (STACK_GROWS_DOWN) {
+target_mprotect(error, guard, PROT_NONE);
+info->stack_limit = error + guard;
+return info->stack_limit + size - sizeof(void *);
+} else {
+target_mprotect(error + size, guard, PROT_NONE);
+info->stack_limit = error + size;
+return error;
+}
 }
 
 /* Map and zero the bss.  We need to explicitly zero any fractional pages
@@ -1529,7 +1574,7 

[Qemu-devel] [PULL 00/26] New hppa-linux target support

2017-01-22 Thread Richard Henderson
This is a linux-user only port, emulating a 32-bit only version of a
pa-2.0 cpu.  This is good enough to do well with both the gcc and glibc
testsuites.  Helge Deller has provided invaluable assistance testing 
with a more complete debian chroot.

What's missing:
  * Space registers.  Since Linux sets them all equal (for a flat
address space) and uses them like address-space identifiers,
we can simply set them all to 0 and ignore them.

  * Architecture subsets.  There's no markup for running a pure pa1.0
or pa1.1 cpu.  I happily accept everything up to pa2.0 at the moment.

  * Wide mode.  While I have pa2.0 instructions, I don't support running
in 64-bit mode.  Since neither the linux kernel nor glibc support a
64-bit userland, it would be a lot more work than just adding the insns.

  * Multimedia instructions.  These are tied to wide mode, so...

When squashing the patches down from my development tree, I wanted to
preserve Helge's contributions, so the linux-user part is more patches
than I would normally have preserved.


r~



The following changes since commit d1c82f7cc34443841095f490345f86c9d8baca34:

  Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20170120-v2' into 
staging (2017-01-20 15:53:58 +)

are available in the git repository at:

  git://github.com/rth7680/qemu.git tags/pull-hppa-20170122

for you to fetch changes up to 0ce588d6c60c338c0856b0dac78d19fc7e698477:

  target-hppa: Implement floating-point insns (2017-01-22 18:14:12 -0800)


hppa-linux target support


Helge Deller (3):
  linux-user: Handle TIOCSTART and TIOCSTOP
  linux-user: Add SIOCGPGRP, SIOCGSTAMP, SIOCGSTAMPNS
  linux-user: Add some hppa ioctls

Richard Henderson (23):
  Revert "Remove remainders of HPPA backend"
  linux-user: Support stack-grows-up in elfload.c
  linux-user: Handle ERFKILL and EHWPOISON
  linux-user: Handle more IPV6 sockopts
  linux-user: Add HPPA socket.h definitions
  linux-user: Add HPPA syscall numbers
  linux-user: Add HPPA termbits.h
  linux-user: Add HPPA target_syscall.h
  linux-user: Add HPPA definitions to syscall_defs.h
  linux-user: Add HPPA target_structs.h
  linux-user: Add HPPA target_signal.h and target_cpu.h
  linux-user: Add HPPA signal handling
  linux-user: Add HPPA startup and main loop
  target-hppa: Add softfloat specializations
  target-hppa: Add framework and enable compilation
  target-hppa: Add nullification framework
  target-hppa: Implement basic arithmetic
  target-hppa: Implement branches
  target-hppa: Implement linux-user gateway page
  target-hppa: Implement shifts and deposits
  target-hppa: Implement loads and stores
  target-hppa: Implement system and memory-management insns
  target-hppa: Implement floating-point insns

 MAINTAINERS |6 +
 configure   |7 +-
 default-configs/hppa-linux-user.mak |1 +
 disas.c |2 +
 disas/Makefile.objs |1 +
 disas/hppa.c| 2832 +
 fpu/softfloat-specialize.h  |   20 +-
 linux-user/alpha/target_syscall.h   |2 +
 linux-user/elfload.c|  259 ++-
 linux-user/errno_defs.h |3 +
 linux-user/hppa/sockbits.h  |   97 +
 linux-user/hppa/syscall_nr.h|  353 
 linux-user/hppa/target_cpu.h|   35 +
 linux-user/hppa/target_signal.h |   29 +
 linux-user/hppa/target_structs.h|   54 +
 linux-user/hppa/target_syscall.h|  237 +++
 linux-user/hppa/termbits.h  |  219 ++
 linux-user/ioctls.h |8 +
 linux-user/main.c   |  185 +-
 linux-user/mips/target_syscall.h|5 +
 linux-user/mips64/target_syscall.h  |5 +
 linux-user/qemu.h   |3 +
 linux-user/signal.c |  191 +-
 linux-user/socket.h |2 +
 linux-user/syscall.c|   41 +-
 linux-user/syscall_defs.h   |  154 +-
 linux-user/syscall_types.h  |6 +
 target/hppa/Makefile.objs   |1 +
 target/hppa/cpu-qom.h   |   52 +
 target/hppa/cpu.c   |  164 ++
 target/hppa/cpu.h   |  144 ++
 target/hppa/gdbstub.c   |  111 +
 target/hppa/helper.c|  137 ++
 target/hppa/helper.h|   66 +
 target/hppa/op_helper.c |  570 +
 target/hppa/translate.c | 3946 +++
 36 files changed, 9869 insertions(+), 79 deletions(-)
 create mode 100644 default-configs/hppa-linux-user.mak
 create mode 100644 disas/hppa.c
 create mode 100644 linux-user/hppa/sockbits.h
 create mode 100644 linux-user/hppa/syscall_nr.h
 create mode 100644 linux

[Qemu-devel] [PULL 03/26] linux-user: Handle TIOCSTART and TIOCSTOP

2017-01-22 Thread Richard Henderson
From: Helge Deller 

Some architectures (ppc, alpha, sparc, parisc, sh and xtensa) define the
BSD TIOCSTART and TIOCSTOP ioctls in their kernel headers to provide
compatibility to other operating systems.

Those ioctls are not implemented in Linux, nevertheless, bash will use
this ioctl if it's available on those architectures.

To avoid false warnings, add code to simply ignore those ioctls.

Signed-off-by: Helge Deller 
Message-Id: <20161206152403.GA6651@ls3530>
Signed-off-by: Richard Henderson 
---
 linux-user/ioctls.h  | 5 +
 linux-user/syscall.c | 6 ++
 2 files changed, 11 insertions(+)

diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h
index 1bad701..eaf6fe6 100644
--- a/linux-user/ioctls.h
+++ b/linux-user/ioctls.h
@@ -422,3 +422,8 @@
 MK_PTR(MK_STRUCT(STRUCT_rtentry)))
   IOCTL_SPECIAL(SIOCDELRT, IOC_W, do_ioctl_rt,
 MK_PTR(MK_STRUCT(STRUCT_rtentry)))
+
+#ifdef TARGET_TIOCSTART
+  IOCTL_IGNORE(TIOCSTART)
+  IOCTL_IGNORE(TIOCSTOP)
+#endif
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 7b77503..acb004f 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -5453,6 +5453,8 @@ static IOCTLEntry ioctl_entries[] = {
 { TARGET_ ## cmd, cmd, #cmd, access, 0, {  __VA_ARGS__ } },
 #define IOCTL_SPECIAL(cmd, access, dofn, ...)  \
 { TARGET_ ## cmd, cmd, #cmd, access, dofn, {  __VA_ARGS__ } },
+#define IOCTL_IGNORE(cmd) \
+{ TARGET_ ## cmd, 0, #cmd },
 #include "ioctls.h"
 { 0, 0, },
 };
@@ -5484,6 +5486,10 @@ static abi_long do_ioctl(int fd, int cmd, abi_long arg)
 #endif
 if (ie->do_ioctl) {
 return ie->do_ioctl(ie, buf_temp, fd, cmd, arg);
+} else if (!ie->host_cmd) {
+/* Some architectures define BSD ioctls in their headers
+   that are not implemented in Linux.  */
+return -TARGET_ENOSYS;
 }
 
 switch(arg_type[0]) {
-- 
2.9.3




[Qemu-devel] [PULL 12/26] linux-user: Add HPPA definitions to syscall_defs.h

2017-01-22 Thread Richard Henderson
---
 linux-user/syscall_defs.h | 131 +-
 1 file changed, 130 insertions(+), 1 deletion(-)

diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index 957b737..39848a8 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -90,6 +90,15 @@
 #define TARGET_IOC_READ  2U
 #define TARGET_IOC_WRITE  4U
 
+#elif defined(TARGET_HPPA)
+
+#define TARGET_IOC_SIZEBITS  14
+#define TARGET_IOC_DIRBITS2
+
+#define TARGET_IOC_NONE   0U
+#define TARGET_IOC_WRITE  2U
+#define TARGET_IOC_READ   1U
+
 #else
 #error unsupported CPU
 #endif
@@ -417,7 +426,7 @@ int do_sigaction(int sig, const struct target_sigaction 
*act,
 || defined(TARGET_M68K) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) \
 || defined(TARGET_MICROBLAZE) || defined(TARGET_UNICORE32) \
 || defined(TARGET_S390X) || defined(TARGET_OPENRISC) \
-|| defined(TARGET_TILEGX)
+|| defined(TARGET_TILEGX) || defined(TARGET_HPPA)
 
 #if defined(TARGET_SPARC)
 #define TARGET_SA_NOCLDSTOP8u
@@ -587,6 +596,46 @@ int do_sigaction(int sig, const struct target_sigaction 
*act,
 #define TARGET_SIG_UNBLOCK 2   /* for unblocking signals */
 #define TARGET_SIG_SETMASK 3   /* for setting the signal mask */
 
+#elif defined(TARGET_HPPA)
+
+#define TARGET_SIGHUP   1
+#define TARGET_SIGINT   2
+#define TARGET_SIGQUIT  3
+#define TARGET_SIGILL   4
+#define TARGET_SIGTRAP  5
+#define TARGET_SIGABRT  6
+#define TARGET_SIGIOT   6
+#define TARGET_SIGSTKFLT7
+#define TARGET_SIGFPE   8
+#define TARGET_SIGKILL  9
+#define TARGET_SIGBUS  10
+#define TARGET_SIGSEGV 11
+#define TARGET_SIGXCPU 12
+#define TARGET_SIGPIPE 13
+#define TARGET_SIGALRM 14
+#define TARGET_SIGTERM 15
+#define TARGET_SIGUSR1 16
+#define TARGET_SIGUSR2 17
+#define TARGET_SIGCHLD 18
+#define TARGET_SIGPWR  19
+#define TARGET_SIGVTALRM   20
+#define TARGET_SIGPROF 21
+#define TARGET_SIGIO   22
+#define TARGET_SIGPOLL TARGET_SIGIO
+#define TARGET_SIGWINCH23
+#define TARGET_SIGSTOP 24
+#define TARGET_SIGTSTP 25
+#define TARGET_SIGCONT 26
+#define TARGET_SIGTTIN 27
+#define TARGET_SIGTTOU 28
+#define TARGET_SIGURG  29
+#define TARGET_SIGXFSZ 30
+#define TARGET_SIGSYS  31
+
+#define TARGET_SIG_BLOCK   0
+#define TARGET_SIG_UNBLOCK 1
+#define TARGET_SIG_SETMASK 2
+
 #else
 
 /* OpenRISC Using the general signals */
@@ -1279,6 +1328,16 @@ struct target_winsize {
 #define TARGET_MAP_NORESERVE   0x1 /* no check for reservations */
 #define TARGET_MAP_POPULATE0x2 /* pop (prefault) pagetables */
 #define TARGET_MAP_NONBLOCK0x4 /* do not block on IO */
+#elif defined(TARGET_HPPA)
+#define TARGET_MAP_ANONYMOUS   0x10/* don't use a file */
+#define TARGET_MAP_FIXED   0x04/* Interpret addr exactly */
+#define TARGET_MAP_GROWSDOWN   0x08000 /* stack-like segment */
+#define TARGET_MAP_DENYWRITE   0x00800 /* ETXTBSY */
+#define TARGET_MAP_EXECUTABLE  0x01000 /* mark it as an executable */
+#define TARGET_MAP_LOCKED  0x02000 /* lock the mapping */
+#define TARGET_MAP_NORESERVE   0x04000 /* no check for reservations */
+#define TARGET_MAP_POPULATE0x1 /* pop (prefault) pagetables */
+#define TARGET_MAP_NONBLOCK0x2 /* do not block on IO */
 #else
 #define TARGET_MAP_FIXED   0x10/* Interpret addr exactly */
 #define TARGET_MAP_ANONYMOUS   0x20/* don't use a file */
@@ -2029,6 +2088,62 @@ struct target_stat64 {
 unsigned int __unused5;
 };
 
+#elif defined(TARGET_HPPA)
+
+struct target_stat {
+abi_uint   st_dev;
+abi_uint   st_ino;
+abi_ushort st_mode;
+abi_ushort st_nlink;
+abi_ushort _res1;
+abi_ushort _res2;
+abi_uint   st_rdev;
+abi_intst_size;
+abi_inttarget_st_atime;
+abi_uint   target_st_atime_nsec;
+abi_inttarget_st_mtime;
+abi_uint   target_st_mtime_nsec;
+abi_inttarget_st_ctime;
+abi_uint   target_st_ctime_nsec;
+abi_intst_blksize;
+abi_intst_blocks;
+abi_uint   _unused1;
+abi_uint   _unused2;
+abi_uint   _unused3;
+abi_uint   _unused4;
+abi_ushort _unused5;
+abi_short  st_fstype;
+abi_uint   st_realdev;
+abi_ushort st_basemode;
+abi_ushort _unused6;
+abi_uint   st_uid;
+abi_uint   st_gid;
+abi_uint   _unused7[3];
+};
+
+#define TARGET_HAS_STRUCT_STAT64
+struct target_stat64 {
+uint64_t   st_dev;
+abi_uint   _pad1;
+abi_uint   _res1;
+abi_uint   st_mode;
+abi_uint   st_nlink;
+abi_uint   st_uid;
+abi_uint   st_gid;
+uint64_t   st_rdev;
+abi_uint   _pad2;
+int64_tst_size;
+abi_int

Re: [Qemu-devel] [PATCH RFC v4 18/20] intel_iommu: enable vfio devices

2017-01-22 Thread Jason Wang



On 2017年01月23日 10:01, Jason Wang wrote:

On 2017年01月20日 21:08, Peter Xu wrote:

This patch is based on Aviv Ben-David ()'s patch
upstream:

   "IOMMU: enable intel_iommu map and unmap notifiers"
https://lists.gnu.org/archive/html/qemu-devel/2016-11/msg01453.html

However I removed/fixed some content, and added my own codes.

Instead of translate() every page for iotlb invalidations (which is
slower), we walk the pages when needed and notify in a hook function.

This patch enables vfio devices for VT-d emulation.

Signed-off-by: Peter Xu
---
  hw/i386/intel_iommu.c | 66 
+--

  include/hw/i386/intel_iommu.h |  8 ++
  2 files changed, 65 insertions(+), 9 deletions(-)


A good side effect of this patch is that it makes vhost device IOTLB 
works without ATS (though may be slow). We probably need a better 
title :)


Probably something like "remote IOMMU/IOTLB" support.

Thanks



Re: [Qemu-devel] [PATCH RFC v4 18/20] intel_iommu: enable vfio devices

2017-01-22 Thread Jason Wang



On 2017年01月20日 21:08, Peter Xu wrote:

This patch is based on Aviv Ben-David ()'s patch
upstream:

   "IOMMU: enable intel_iommu map and unmap notifiers"
   https://lists.gnu.org/archive/html/qemu-devel/2016-11/msg01453.html

However I removed/fixed some content, and added my own codes.

Instead of translate() every page for iotlb invalidations (which is
slower), we walk the pages when needed and notify in a hook function.

This patch enables vfio devices for VT-d emulation.

Signed-off-by: Peter Xu
---
  hw/i386/intel_iommu.c | 66 +--
  include/hw/i386/intel_iommu.h |  8 ++
  2 files changed, 65 insertions(+), 9 deletions(-)


A good side effect of this patch is that it makes vhost device IOTLB 
works without ATS (though may be slow). We probably need a better title :)


And I think we should block notifiers during PSI/DSI/GLOBAL for device 
with ATS enabled.


Thanks



Re: [Qemu-devel] [PATCH RFC v4 19/20] intel_iommu: unmap existing pages before replay

2017-01-22 Thread Jason Wang



On 2017年01月22日 17:09, Peter Xu wrote:

On Sun, Jan 22, 2017 at 04:13:32PM +0800, Jason Wang wrote:


On 2017年01月20日 21:08, Peter Xu wrote:

Previous replay works for domain switch only if the original domain does
not have mapped pages. For example, if we switch domain from A to B, it
will only work if A has no existing mapping. If there is, then there's
problem - current replay didn't make sure the old mappings are cleared
before replaying the new one.

I'm not quite sure this is needed. I thought the only thing we need to do is
stop DMA of device during the moving? Or is there an example that will cause
trouble?

I think this patch is essential.

Example:

- device D1 moved to domain A, domain A has no mapping
- map page P1 in domain A, so D1 will have a mapping of page P1
- create domain B with mapping P2
- move D1 from domain A to domain B

Here if we don't unmap existing pages in domain A (P1),


I thought driver should do this work instead of device, because only 
driver knows whether or not iova is still needed?


Thanks


  after the
switch, we'll have D1 with both P1/P2 mapped, while domain B actually
only has P2. That's unaligned mapping, and it should be wrong.

If you (or anyone) think this is a bug as well for patch 18, I can
just squash both 19/20 into patch 18.

Thanks,

-- peterx





Re: [Qemu-devel] [PATCH RFC v4 18/20] intel_iommu: enable vfio devices

2017-01-22 Thread Jason Wang



On 2017年01月22日 17:04, Peter Xu wrote:

On Sun, Jan 22, 2017 at 04:08:04PM +0800, Jason Wang wrote:

[...]


+static void vtd_iotlb_page_invalidate_notify(IntelIOMMUState *s,
+   uint16_t domain_id, hwaddr addr,
+   uint8_t am)
+{
+IntelIOMMUNotifierNode *node;
+VTDContextEntry ce;
+int ret;
+
+QLIST_FOREACH(node, &(s->notifiers_list), next) {
+VTDAddressSpace *vtd_as = node->vtd_as;
+ret = vtd_dev_to_context_entry(s, pci_bus_num(vtd_as->bus),
+   vtd_as->devfn, );
+if (!ret && domain_id == VTD_CONTEXT_ENTRY_DID(ce.hi)) {
+vtd_page_walk(, addr, addr + (1 << am) * VTD_PAGE_SIZE,
+  vtd_page_invalidate_notify_hook,
+  (void *)_as->iommu, true);

Why not simply trigger the notifier here? (or is this vfio required?)

Because we may only want to notify part of the region - we are with
mask here, but not exact size.

Consider this: guest (with caching mode) maps 12K memory (4K*3 pages),
the mask will be extended to 16K in the guest. In that case, we need
to explicitly go over the page entry to know that the 4th page should
not be notified.


I see. Then it was required by vfio only, I think we can add a fast path 
for !CM in this case by triggering the notifier directly.


Another possible issue is, consider (with CM) a 16K contiguous iova with 
the last page has already been mapped. In this case, if we want to map 
first three pages, when handling IOTLB invalidation, am would be 16K, 
then the last page will be mapped twice. Can this lead some issue?


Thanks



Re: [Qemu-devel] [PATCH RFC v4 15/20] intel_iommu: provide its own replay() callback

2017-01-22 Thread Jason Wang



On 2017年01月22日 17:36, Peter Xu wrote:

Besides this one, I tried to fix the comments in this function as
below, hope this is better (I removed 1-3 thing since I think that's
clearer from below code):

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index e958f53..f3fe8c4 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -735,15 +735,6 @@ static int vtd_page_walk_level(dma_addr_t addr, uint64_t 
start,
  offset = vtd_iova_level_offset(iova, level);
  slpte = vtd_get_slpte(addr, offset);

-/*
- * When one of the following case happens, we assume the whole
- * range is invalid:
- *
- * 1. read block failed
- * 3. reserved area non-zero
- * 2. both read & write flag are not set
- */
-
  if (slpte == (uint64_t)-1) {
  trace_vtd_page_walk_skip_read(iova, iova_next);
  skipped_local++;
@@ -761,20 +752,16 @@ static int vtd_page_walk_level(dma_addr_t addr, uint64_t 
start,
  write_cur = write && (slpte & VTD_SL_W);

  /*
- * As long as we have either read/write permission, this is
- * a valid entry. The rule works for both page or page tables.
+ * As long as we have either read/write permission, this is a
+ * valid entry. The rule works for both page entries and page
+ * table entries.
   */
  entry_valid = read_cur | write_cur;

  if (vtd_is_last_slpte(slpte, level)) {
  entry.target_as = _space_memory;
  entry.iova = iova & subpage_mask;
-/*
- * This might be meaningless addr if (!read_cur &&
- * !write_cur), but after all this field will be
- * meaningless in that case, so let's share the code to
- * generate the IOTLBs no matter it's an MAP or UNMAP
- */
+/* NOTE: this is only meaningful if entry_valid == true */
  entry.translated_addr = vtd_get_slpte_addr(slpte);
  entry.addr_mask = ~subpage_mask;
  entry.perm = IOMMU_ACCESS_FLAG(read_cur, write_cur);

Thanks,

-- peterx


I still prefer to do this on patch 18 probably.

Thanks



Re: [Qemu-devel] [PATCH RFC v4 15/20] intel_iommu: provide its own replay() callback

2017-01-22 Thread Jason Wang



On 2017年01月22日 16:51, Peter Xu wrote:

On Sun, Jan 22, 2017 at 03:56:10PM +0800, Jason Wang wrote:

[...]


+/**
+ * vtd_page_walk_level - walk over specific level for IOVA range
+ *
+ * @addr: base GPA addr to start the walk
+ * @start: IOVA range start address
+ * @end: IOVA range end address (start <= addr < end)
+ * @hook_fn: hook func to be called when detected page
+ * @private: private data to be passed into hook func
+ * @read: whether parent level has read permission
+ * @write: whether parent level has write permission
+ * @skipped: accumulated skipped ranges

What's the usage for this parameter? Looks like it was never used in this
series.

This was for debugging purpose before, and I kept it in case one day
it can be used again, considering that will not affect much on the
overall performance.


I think we usually do not keep debugging codes outside debug macros.




+ * @notify_unmap: whether we should notify invalid entries
+ */
+static int vtd_page_walk_level(dma_addr_t addr, uint64_t start,
+   uint64_t end, vtd_page_walk_hook hook_fn,
+   void *private, uint32_t level,
+   bool read, bool write, uint64_t *skipped,
+   bool notify_unmap)
+{
+bool read_cur, write_cur, entry_valid;
+uint32_t offset;
+uint64_t slpte;
+uint64_t subpage_size, subpage_mask;
+IOMMUTLBEntry entry;
+uint64_t iova = start;
+uint64_t iova_next;
+uint64_t skipped_local = 0;
+int ret = 0;
+
+trace_vtd_page_walk_level(addr, level, start, end);
+
+subpage_size = 1ULL << vtd_slpt_level_shift(level);
+subpage_mask = vtd_slpt_level_page_mask(level);
+
+while (iova < end) {
+iova_next = (iova & subpage_mask) + subpage_size;
+
+offset = vtd_iova_level_offset(iova, level);
+slpte = vtd_get_slpte(addr, offset);
+
+/*
+ * When one of the following case happens, we assume the whole
+ * range is invalid:
+ *
+ * 1. read block failed

Don't get the meaning (and don't see any code relate to this comment).

I took above vtd_get_slpte() a "read", so I was trying to mean that we
failed to read the SLPTE due to some reason, we assume the range is
invalid.


I see, so we'd better move the comment above of vtd_get_slpte().




+ * 3. reserved area non-zero
+ * 2. both read & write flag are not set

Should be 1,2,3? And the above comment is conflict with the code at least
when notify_unmap is true.

Yes, okay I don't know why 3 jumped. :(

And yes, I should mention that "both read & write flag not set" only
suites for page tables here.


+ */
+
+if (slpte == (uint64_t)-1) {

If this is true, vtd_slpte_nonzero_rsvd(slpte) should be true too I think?

Yes, but we are doing two checks here:

- checking against -1 to make sure slpte read success
- checking against nonzero reserved fields to make sure it follows spec

Imho we should not skip the first check here, only if one day removing
this may really matter (e.g., for performance reason? I cannot think
of one yet).


Ok. (return -1 seems not good, but we can address this in the future).




+trace_vtd_page_walk_skip_read(iova, iova_next);
+skipped_local++;
+goto next;
+}
+
+if (vtd_slpte_nonzero_rsvd(slpte, level)) {
+trace_vtd_page_walk_skip_reserve(iova, iova_next);
+skipped_local++;
+goto next;
+}
+
+/* Permissions are stacked with parents' */
+read_cur = read && (slpte & VTD_SL_R);
+write_cur = write && (slpte & VTD_SL_W);
+
+/*
+ * As long as we have either read/write permission, this is
+ * a valid entry. The rule works for both page or page tables.
+ */
+entry_valid = read_cur | write_cur;
+
+if (vtd_is_last_slpte(slpte, level)) {
+entry.target_as = _space_memory;
+entry.iova = iova & subpage_mask;
+/*
+ * This might be meaningless addr if (!read_cur &&
+ * !write_cur), but after all this field will be
+ * meaningless in that case, so let's share the code to
+ * generate the IOTLBs no matter it's an MAP or UNMAP
+ */
+entry.translated_addr = vtd_get_slpte_addr(slpte);
+entry.addr_mask = ~subpage_mask;
+entry.perm = IOMMU_ACCESS_FLAG(read_cur, write_cur);
+if (!entry_valid && !notify_unmap) {
+trace_vtd_page_walk_skip_perm(iova, iova_next);
+skipped_local++;
+goto next;
+}

Under which case should we care about unmap here (better with a comment I
think)?

When PSIs are for invalidation, rather than newly mapped entries. In
that case, notify_unmap will be true, and here we need to notify
IOMMU_NONE to do the cache flush or unmap.

(this page walk is not only for 

[Qemu-devel] [PATCH V2] virtio: Fix no interrupt when not creating msi controller

2017-01-22 Thread Shannon Zhao
From: Shannon Zhao 

For ARM virt machine, if we use virt-2.7 which will not create ITS node,
the virtio-net can not recieve interrupts so it can't get ip address
through dhcp.
This fixes commit 83d768b(virtio: set ISR on dataplane notifications).

Signed-off-by: Shannon Zhao 
---
V2: Factor out a common function instead of duplicating code
---
 hw/virtio/virtio.c | 11 ---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index aa4f38f..00e8f74 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -1441,6 +1441,12 @@ void virtio_notify_irqfd(VirtIODevice *vdev, VirtQueue 
*vq)
 event_notifier_set(>guest_notifier);
 }
 
+static void virtio_irq(VirtQueue *vq)
+{
+virtio_set_isr(vq->vdev, 0x1);
+virtio_notify_vector(vq->vdev, vq->vector);
+}
+
 void virtio_notify(VirtIODevice *vdev, VirtQueue *vq)
 {
 if (!virtio_should_notify(vdev, vq)) {
@@ -1448,8 +1454,7 @@ void virtio_notify(VirtIODevice *vdev, VirtQueue *vq)
 }
 
 trace_virtio_notify(vdev, vq);
-virtio_set_isr(vq->vdev, 0x1);
-virtio_notify_vector(vdev, vq->vector);
+virtio_irq(vq);
 }
 
 void virtio_notify_config(VirtIODevice *vdev)
@@ -2082,7 +2087,7 @@ static void 
virtio_queue_guest_notifier_read(EventNotifier *n)
 {
 VirtQueue *vq = container_of(n, VirtQueue, guest_notifier);
 if (event_notifier_test_and_clear(n)) {
-virtio_notify_vector(vq->vdev, vq->vector);
+virtio_irq(vq);
 }
 }
 
-- 
2.0.4





[Qemu-devel] [Bug 1658506] [NEW] qemu/hw/intc/arm_gicv3_cpuif.c:2433: bad expression ?

2017-01-22 Thread dcb
Public bug reported:

qemu/hw/intc/arm_gicv3_cpuif.c:2433]: (style) Expression '(X &
0x2000) == 0x1' is always false.

Source code is

   ((lr & ICH_LR_EL2_HW) == 1 || (lr & ICH_LR_EL2_EOI) == 0)) {

Maybe better code

   ((lr & ICH_LR_EL2_HW) != 0 || (lr & ICH_LR_EL2_EOI) == 0)) {

** Affects: qemu
 Importance: Undecided
 Status: New

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

Title:
  qemu/hw/intc/arm_gicv3_cpuif.c:2433: bad expression ?

Status in QEMU:
  New

Bug description:
  qemu/hw/intc/arm_gicv3_cpuif.c:2433]: (style) Expression '(X &
  0x2000) == 0x1' is always false.

  Source code is

 ((lr & ICH_LR_EL2_HW) == 1 || (lr & ICH_LR_EL2_EOI) == 0))
  {

  Maybe better code

 ((lr & ICH_LR_EL2_HW) != 0 || (lr & ICH_LR_EL2_EOI) == 0))
  {

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



Re: [Qemu-devel] QEMU website (wiki) improvements

2017-01-22 Thread Stefan Weil

On 03/02/15 23:12, Stefan Hajnoczi wrote:

On Sat, Feb 28, 2015 at 04:29:44PM +0100, Stefan Weil wrote:

* It does not support secure access (https), so each login is insecure.
  Can we get a free server certificate?


This is on my todo list.  I'm travelling right now but will work on it
over the coming weeks.

There are some gotchas:

1. qemu.org vs qemu-project.org.  Unless we get a SNI certificate, the
   certificate will only be valid for one or the other.  Users will get
   an untrusted certificate message if they go to the other domain name.

2. We use subdomains, so a wildcard certificate is necessary.  That's
   not always offered for free so I need to compare the certificate
   vendors.

Stefan



Although this discussion thread is rather old, its subject
still applies.

In the meantime there are free certificates available.
We could add https support with a certificate from
https://letsencrypt.org/. As long as there is only a
small number of host names (*), I'd simply add them all
to the primary certificate. In addition, SNI certificates
for the different names can be installed.

I can help with the installation if that is needed.

Stefan

(*)

qemu.org
qemu.osuosl.org
qemu-project.org
wiki.qemu.org
wiki.qemu-project.org
www.qemu.org
www.qemu-project.org

Are there more host names used?




[Qemu-devel] [PATCH] qapi: Remove unwanted commas after #optional keyword

2017-01-22 Thread Stefan Weil
We don't want that commas to be part of the generated documentation,
so remove them.

Signed-off-by: Stefan Weil 
---

This is an alternative solution for the issue which is also addressed
by my previous patch http://patchwork.ozlabs.org/patch/718177/.

It's also possible to apply both patches.

Stefan

 qapi-schema.json |  4 ++--
 qapi/block-core.json | 10 +-
 qapi/event.json  |  6 +++---
 3 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/qapi-schema.json b/qapi-schema.json
index ddc878390e..176e1a5a0b 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -1506,7 +1506,7 @@
 #
 # The network connection information for server
 #
-# @auth: #optional, authentication method
+# @auth: #optional authentication method
 #
 # Since: 2.1
 ##
@@ -1694,7 +1694,7 @@
 #
 # Information about a SPICE server
 #
-# @auth: #optional, authentication method
+# @auth: #optional authentication method
 #
 # Since: 2.1
 ##
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 1b3e6eb0e8..932f5bb3b4 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -3126,10 +3126,10 @@
 #
 # @filename:filename of the new image to be loaded
 #
-# @format:  #optional, format to open the new image with (defaults to
+# @format:  #optional format to open the new image with (defaults to
 #   the probed format)
 #
-# @read-only-mode:  #optional, change the read-only mode of the device; 
defaults
+# @read-only-mode:  #optional change the read-only mode of the device; defaults
 #   to 'retain'
 #
 # Since: 2.5
@@ -3208,10 +3208,10 @@
 #   corruption being detected. It should not be parsed by machine as it is
 #   not guaranteed to be stable
 #
-# @offset: #optional, if the corruption resulted from an image access, this is
+# @offset: #optional if the corruption resulted from an image access, this is
 #  the host's access offset into the image
 #
-# @size: #optional, if the corruption resulted from an image access, this is
+# @size: #optional if the corruption resulted from an image access, this is
 #the access size
 #
 # @fatal: if set, the image is marked corrupt and therefore unusable after this
@@ -3302,7 +3302,7 @@
 #
 # @speed: rate limit, bytes per second
 #
-# @error: #optional, error message. Only present on failure. This field
+# @error: #optional error message. Only present on failure. This field
 # contains a human-readable error message. There are no semantics
 # other than that streaming has failed and clients should not try to
 # interpret the error string
diff --git a/qapi/event.json b/qapi/event.json
index f3737b771f..7bf539b84d 100644
--- a/qapi/event.json
+++ b/qapi/event.json
@@ -186,7 +186,7 @@
 # At this point, it's safe to reuse the specified device ID. Device removal can
 # be initiated by the guest or by HMP/QMP commands.
 #
-# @device: #optional, device name
+# @device: #optional device name
 #
 # @path: device path
 #
@@ -209,7 +209,7 @@
 # Emitted once until the 'query-rx-filter' command is executed, the first event
 # will always be emitted
 #
-# @name: #optional, net client name
+# @name: #optional net client name
 #
 # @path: device path
 #
@@ -531,7 +531,7 @@
 #
 # @type: quorum operation type (Since 2.6)
 #
-# @error: #optional, error message. Only present on failure. This field
+# @error: #optional error message. Only present on failure. This field
 # contains a human-readable error message. There are no semantics other
 # than that the block layer reported an error and clients should not
 # try to interpret the error string.
-- 
2.11.0




Re: [Qemu-devel] [PATCH v3 0/3] scsi-generic and BLKSECTGET

2017-01-22 Thread Fam Zheng
On Fri, 01/20 17:25, Eric Farman wrote:
> Changes:
>  v2->v3:
>   - Move byte/sector conversions to patch 2 [Fam Zheng]
>   - Rename "max_sectors" when holding a byte value [Fam Zheng]
>  v1->v2:
>   - Patch 3, make hdev_get_max_transfer_length return bytes [Fam Zheng]

Reviewed-by: Fam Zheng 



Re: [Qemu-devel] [PATCH] qapi2texi: Suppress unwanted commas in generated output

2017-01-22 Thread Marc-André Lureau
Hi

On Sun, Jan 22, 2017 at 5:39 PM Stefan Weil  wrote:

> Parts of the code use #optional followed by a comma.
>
> We don't want that comma to be part of the generated documentation,
> so remove it, too.
>
> Signed-off-by: Stefan Weil 
> ---
>
> I added the generated documentation to https://qemu.weilnetz.de/doc/.
>
> See https://qemu.weilnetz.de/doc/qemu-qmp-ref.html for an
> example of the output without this patch (look for ", net").
>
> We could also remove the commas from the code, but I think
> that removing them programmatically is more robust (and also
> allows people placing commas as they like).
>

Sometime there is also a - : @ipv6: #optional - force the use of ipv6

I think I would rather fix the doc. Making the parser/generator more subtle
will also be harder to document or change later on.


> Regards
> Stefan
>
>  scripts/qapi2texi.py | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/scripts/qapi2texi.py b/scripts/qapi2texi.py
> index 83ded95c2d..65c4aecfaf 100755
> --- a/scripts/qapi2texi.py
> +++ b/scripts/qapi2texi.py
> @@ -146,7 +146,7 @@ def texi_body(doc):
>  desc = str(section)
>  opt = ''
>  if "#optional" in desc:
> -desc = desc.replace("#optional", "")
> +desc = re.sub("#optional,?", "", desc)
>  opt = ' (optional)'
>  body += "@item @code{'%s'}%s\n%s\n" % (arg, opt,
> texi_format(desc))
> --
> 2.11.0
>
>
> --
Marc-André Lureau


[Qemu-devel] [PATCH] qapi2texi: Suppress unwanted commas in generated output

2017-01-22 Thread Stefan Weil
Parts of the code use #optional followed by a comma.

We don't want that comma to be part of the generated documentation,
so remove it, too.

Signed-off-by: Stefan Weil 
---

I added the generated documentation to https://qemu.weilnetz.de/doc/.

See https://qemu.weilnetz.de/doc/qemu-qmp-ref.html for an
example of the output without this patch (look for ", net").

We could also remove the commas from the code, but I think
that removing them programmatically is more robust (and also
allows people placing commas as they like).

Regards
Stefan

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

diff --git a/scripts/qapi2texi.py b/scripts/qapi2texi.py
index 83ded95c2d..65c4aecfaf 100755
--- a/scripts/qapi2texi.py
+++ b/scripts/qapi2texi.py
@@ -146,7 +146,7 @@ def texi_body(doc):
 desc = str(section)
 opt = ''
 if "#optional" in desc:
-desc = desc.replace("#optional", "")
+desc = re.sub("#optional,?", "", desc)
 opt = ' (optional)'
 body += "@item @code{'%s'}%s\n%s\n" % (arg, opt,
texi_format(desc))
-- 
2.11.0




Re: [Qemu-devel] [Nbd] [Qemu-block] How to online resize qemu disk with nbd protocol?

2017-01-22 Thread Wouter Verhelst
On Sun, Jan 22, 2017 at 06:25:09PM +0800, Bob Chen wrote:
> Hi folks,
> 
> My time schedule doesn't allow me to wait for the community's solution, so I
> started to work on quick fix, which is to add a 'bdrv_truncate' function to 
> the
> current NBD's BlockDriver. Basically it's an 'active resize' implementation.

Fair enough.

If you're going to do that though, please add some negotiation before
trying to use the option, too. That way, other implementations can add
support for that option too, if they want

Having given this some more thought, I'm not entirely sure anymore that
an active resize from the NBD layer is necessarily a layering violation.
There might be other cases where this is useful, and e.g., the Linux
kernel also supports active resizes of block devices in some cases
(e.g., LVM). We'll also need to define what happens in case the resize
operation isn't possible for some reason (e.g., the size increase asks
for more space than the server's storage has available).

I suggest the following semantics:

- Add a transmission flag to indicate resize is possible for
  transmission phase (NBD_FLAG_SEND_RESIZE, flag 10). I don't see any
  need for an NBD_OPT_RESIZE or some such; just the flag should suffice.
- NBD_CMD_RESIZE (command 7): resize the export. The "offset" field
  contains the new size, "length" is reserved (why not the other way
  around? offset is 64 bits, length is 32)
- resize command can fail with:
  EPERM: server configuration does not allow this resize, or
  (optionally) other clients are using the same export and the request
  was for a smaller size.
  EIO: I/O error while trying to resize the device
  ENOSPC: new export size requires more space than is available
  ESHUTDOWN: server is shutting down

I've added an "extension-resize" branch with the above. If that works
for you, then run with it. If not, just implement what you want and send
updates as you go along.

> I also realized that the 'bdrv_truncate' caller stack is not in a coroutine,
> seemed to be the main thread? Then I tried some synchronous code as below:
> 
> int nbd_truncate(BlockDriverState *bs, int64_t offset)
> {
>     //...
>     nbd_client_detach_aio_context(bs);
>     qio_channel_set_blocking(client->ioc, true, NULL);
> 
>     ret = nbd_send_request(client->ioc, );            // step 1, send
> custom NBD_CMD_RESIZE request
>     ret = nbd_receive_reply(client->ioc, );
> 
>     read_sync(client->ioc, _size, sizeof(new_size));     // step 2,
> expected to receive the confirmed new_size as data
>     new_size = be64_to_cpu(new_size);
> 
>     qio_channel_set_blocking(client->ioc, false, NULL);
>     nbd_client_attach_aio_context(bs, aio_context);
>     //...
> }
> 
> However at step 2, the 'new_size' I read is not always correct. Sometimes the
> bytes are repeating, for instance 1073741824 (1GB) became 1073741824073741824
> ...
> 
> Could you help me figure out what went wrong?
> 
> 
> Regards, 
> Bob
> 
> 2017-01-18 16:01 GMT+08:00 Wouter Verhelst :
> 
> On Mon, Jan 16, 2017 at 01:36:21PM -0600, Eric Blake wrote:
> > Maybe the structured reply proposal can be extended into this (reserve a
> > "reply" header that can be issued as many times as desired by the server
> > without the client ever having issued the request first, and where the
> > reply never uses the end-of-reply marker), but I'm not sure I want to go
> > that direction just yet.
> 
> It's not necessarily a bad idea, which could also be used for:
> - keepalive probes from server to client
> - unsolicited ESHUTDOWN messages
> 
> both of which are currently not possible and might be useful for the
> protocol to have.
> 
> --
> < ron> I mean, the main *practical* problem with C++, is there's like a
> dozen
>        people in the world who think they really understand all of its
> rules,
>        and pretty much all of them are just lying to themselves too.
>  -- #debian-devel, OFTC, 2016-02-12
> 
> 

-- 
< ron> I mean, the main *practical* problem with C++, is there's like a dozen
   people in the world who think they really understand all of its rules,
   and pretty much all of them are just lying to themselves too.
 -- #debian-devel, OFTC, 2016-02-12



Re: [Qemu-devel] [Nbd] [Qemu-block] How to online resize qemu disk with nbd protocol?

2017-01-22 Thread Bob Chen
Hi folks,

My time schedule doesn't allow me to wait for the community's solution, so
I started to work on quick fix, which is to add a 'bdrv_truncate' function
to the current NBD's BlockDriver. Basically it's an 'active resize'
implementation.

I also realized that the 'bdrv_truncate' caller stack is not in a
coroutine, seemed to be the main thread? Then I tried some synchronous code
as below:

int nbd_truncate(BlockDriverState *bs, int64_t offset)
{
//...
nbd_client_detach_aio_context(bs);
qio_channel_set_blocking(client->ioc, true, NULL);

ret = nbd_send_request(client->ioc, );// step 1,
send custom NBD_CMD_RESIZE request
ret = nbd_receive_reply(client->ioc, );

read_sync(client->ioc, _size, sizeof(new_size)); // step 2,
expected to receive the confirmed new_size as data
new_size = be64_to_cpu(new_size);

qio_channel_set_blocking(client->ioc, false, NULL);
nbd_client_attach_aio_context(bs, aio_context);
//...
}

However at step 2, the 'new_size' I read is not always correct. Sometimes
the bytes are repeating, for instance 1073741824 (1GB)
became 1073741824073741824 ...

Could you help me figure out what went wrong?


Regards,
Bob

2017-01-18 16:01 GMT+08:00 Wouter Verhelst :

> On Mon, Jan 16, 2017 at 01:36:21PM -0600, Eric Blake wrote:
> > Maybe the structured reply proposal can be extended into this (reserve a
> > "reply" header that can be issued as many times as desired by the server
> > without the client ever having issued the request first, and where the
> > reply never uses the end-of-reply marker), but I'm not sure I want to go
> > that direction just yet.
>
> It's not necessarily a bad idea, which could also be used for:
> - keepalive probes from server to client
> - unsolicited ESHUTDOWN messages
>
> both of which are currently not possible and might be useful for the
> protocol to have.
>
> --
> < ron> I mean, the main *practical* problem with C++, is there's like a
> dozen
>people in the world who think they really understand all of its
> rules,
>and pretty much all of them are just lying to themselves too.
>  -- #debian-devel, OFTC, 2016-02-12
>


Re: [Qemu-devel] [PATCH RFC v4 15/20] intel_iommu: provide its own replay() callback

2017-01-22 Thread Peter Xu
On Sun, Jan 22, 2017 at 04:51:18PM +0800, Peter Xu wrote:
> On Sun, Jan 22, 2017 at 03:56:10PM +0800, Jason Wang wrote:
> 
> [...]
> 
> > >+/**
> > >+ * vtd_page_walk_level - walk over specific level for IOVA range
> > >+ *
> > >+ * @addr: base GPA addr to start the walk
> > >+ * @start: IOVA range start address
> > >+ * @end: IOVA range end address (start <= addr < end)
> > >+ * @hook_fn: hook func to be called when detected page
> > >+ * @private: private data to be passed into hook func
> > >+ * @read: whether parent level has read permission
> > >+ * @write: whether parent level has write permission
> > >+ * @skipped: accumulated skipped ranges
> > 
> > What's the usage for this parameter? Looks like it was never used in this
> > series.
> 
> This was for debugging purpose before, and I kept it in case one day
> it can be used again, considering that will not affect much on the
> overall performance.
> 
> > 
> > >+ * @notify_unmap: whether we should notify invalid entries
> > >+ */
> > >+static int vtd_page_walk_level(dma_addr_t addr, uint64_t start,
> > >+   uint64_t end, vtd_page_walk_hook hook_fn,
> > >+   void *private, uint32_t level,
> > >+   bool read, bool write, uint64_t *skipped,
> > >+   bool notify_unmap)
> > >+{
> > >+bool read_cur, write_cur, entry_valid;
> > >+uint32_t offset;
> > >+uint64_t slpte;
> > >+uint64_t subpage_size, subpage_mask;
> > >+IOMMUTLBEntry entry;
> > >+uint64_t iova = start;
> > >+uint64_t iova_next;
> > >+uint64_t skipped_local = 0;
> > >+int ret = 0;
> > >+
> > >+trace_vtd_page_walk_level(addr, level, start, end);
> > >+
> > >+subpage_size = 1ULL << vtd_slpt_level_shift(level);
> > >+subpage_mask = vtd_slpt_level_page_mask(level);
> > >+
> > >+while (iova < end) {
> > >+iova_next = (iova & subpage_mask) + subpage_size;
> > >+
> > >+offset = vtd_iova_level_offset(iova, level);
> > >+slpte = vtd_get_slpte(addr, offset);
> > >+
> > >+/*
> > >+ * When one of the following case happens, we assume the whole
> > >+ * range is invalid:
> > >+ *
> > >+ * 1. read block failed
> > 
> > Don't get the meaning (and don't see any code relate to this comment).
> 
> I took above vtd_get_slpte() a "read", so I was trying to mean that we
> failed to read the SLPTE due to some reason, we assume the range is
> invalid.
> 
> > 
> > >+ * 3. reserved area non-zero
> > >+ * 2. both read & write flag are not set
> > 
> > Should be 1,2,3? And the above comment is conflict with the code at least
> > when notify_unmap is true.
> 
> Yes, okay I don't know why 3 jumped. :(
> 
> And yes, I should mention that "both read & write flag not set" only
> suites for page tables here.
> 
> > 
> > >+ */
> > >+
> > >+if (slpte == (uint64_t)-1) {
> > 
> > If this is true, vtd_slpte_nonzero_rsvd(slpte) should be true too I think?
> 
> Yes, but we are doing two checks here:
> 
> - checking against -1 to make sure slpte read success
> - checking against nonzero reserved fields to make sure it follows spec
> 
> Imho we should not skip the first check here, only if one day removing
> this may really matter (e.g., for performance reason? I cannot think
> of one yet).
> 
> > 
> > >+trace_vtd_page_walk_skip_read(iova, iova_next);
> > >+skipped_local++;
> > >+goto next;
> > >+}
> > >+
> > >+if (vtd_slpte_nonzero_rsvd(slpte, level)) {
> > >+trace_vtd_page_walk_skip_reserve(iova, iova_next);
> > >+skipped_local++;
> > >+goto next;
> > >+}
> > >+
> > >+/* Permissions are stacked with parents' */
> > >+read_cur = read && (slpte & VTD_SL_R);
> > >+write_cur = write && (slpte & VTD_SL_W);
> > >+
> > >+/*
> > >+ * As long as we have either read/write permission, this is
> > >+ * a valid entry. The rule works for both page or page tables.
> > >+ */
> > >+entry_valid = read_cur | write_cur;
> > >+
> > >+if (vtd_is_last_slpte(slpte, level)) {
> > >+entry.target_as = _space_memory;
> > >+entry.iova = iova & subpage_mask;
> > >+/*
> > >+ * This might be meaningless addr if (!read_cur &&
> > >+ * !write_cur), but after all this field will be
> > >+ * meaningless in that case, so let's share the code to
> > >+ * generate the IOTLBs no matter it's an MAP or UNMAP
> > >+ */
> > >+entry.translated_addr = vtd_get_slpte_addr(slpte);
> > >+entry.addr_mask = ~subpage_mask;
> > >+entry.perm = IOMMU_ACCESS_FLAG(read_cur, write_cur);
> > >+if (!entry_valid && !notify_unmap) {
> > >+trace_vtd_page_walk_skip_perm(iova, iova_next);
> > >+

Re: [Qemu-devel] [PATCH RFC v4 19/20] intel_iommu: unmap existing pages before replay

2017-01-22 Thread Peter Xu
On Sun, Jan 22, 2017 at 04:13:32PM +0800, Jason Wang wrote:
> 
> 
> On 2017年01月20日 21:08, Peter Xu wrote:
> >Previous replay works for domain switch only if the original domain does
> >not have mapped pages. For example, if we switch domain from A to B, it
> >will only work if A has no existing mapping. If there is, then there's
> >problem - current replay didn't make sure the old mappings are cleared
> >before replaying the new one.
> 
> I'm not quite sure this is needed. I thought the only thing we need to do is
> stop DMA of device during the moving? Or is there an example that will cause
> trouble?

I think this patch is essential.

Example:

- device D1 moved to domain A, domain A has no mapping
- map page P1 in domain A, so D1 will have a mapping of page P1
- create domain B with mapping P2
- move D1 from domain A to domain B

Here if we don't unmap existing pages in domain A (P1), after the
switch, we'll have D1 with both P1/P2 mapped, while domain B actually
only has P2. That's unaligned mapping, and it should be wrong.

If you (or anyone) think this is a bug as well for patch 18, I can
just squash both 19/20 into patch 18.

Thanks,

-- peterx



Re: [Qemu-devel] [PATCH] util/envlist: Fix 2 bugs in envlist_setenv and envlist_unsetenv

2017-01-22 Thread no-reply
Hi,

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

Subject: [Qemu-devel] [PATCH] util/envlist: Fix 2 bugs in envlist_setenv and 
envlist_unsetenv
Message-id: 
cy1pr17mb031324368f190b92efa547acdb...@cy1pr17mb0313.namprd17.prod.outlook.com
Type: series

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

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

# Useful git options
git config --local diff.renamelimit 0
git config --local diff.renames True

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

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

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
3d0c260 util/envlist: Fix 2 bugs in envlist_setenv and envlist_unsetenv

=== OUTPUT BEGIN ===
Checking PATCH 1/1: util/envlist: Fix 2 bugs in envlist_setenv and 
envlist_unsetenv...
ERROR: code indent should never use tabs
#29: FILE: util/envlist.c:133:
+^Istruct envlist_entry *entry = NULL, *entry_old = NULL;$

ERROR: code indent should never use tabs
#40: FILE: util/envlist.c:150:
+^Ifor (entry_old = envlist->el_entries.lh_first; entry_old != NULL;$

ERROR: code indent should never use tabs
#41: FILE: util/envlist.c:151:
+^Ientry_old = entry_old->ev_link.le_next) {$

ERROR: code indent should never use tabs
#42: FILE: util/envlist.c:152:
+^I^Iif (strncmp(entry_old->ev_var, env, envname_len) == 0)$

ERROR: braces {} are necessary for all arms of this statement
#42: FILE: util/envlist.c:152:
+   if (strncmp(entry_old->ev_var, env, envname_len) == 0)
[...]

ERROR: code indent should never use tabs
#61: FILE: util/envlist.c:163:
+^Iif (entry_old != NULL) {$

ERROR: code indent should never use tabs
#62: FILE: util/envlist.c:164:
+^I^IQLIST_REMOVE(entry_old, ev_link);$

ERROR: code indent should never use tabs
#63: FILE: util/envlist.c:165:
+^I^Ifree((char *)entry_old->ev_var);$

ERROR: code indent should never use tabs
#64: FILE: util/envlist.c:166:
+^I^Ifree(entry_old);$

ERROR: code indent should never use tabs
#65: FILE: util/envlist.c:167:
+^I} else {$

ERROR: code indent should never use tabs
#66: FILE: util/envlist.c:168:
+^I^Ienvlist->el_count++;$

ERROR: code indent should never use tabs
#67: FILE: util/envlist.c:169:
+^I}$

ERROR: code indent should never use tabs
#76: FILE: util/envlist.c:189:
+^Ienvname_len = strlen(env);$

ERROR: code indent should never use tabs
#77: FILE: util/envlist.c:190:
+^Iif(0 == envname_len)$

ERROR: space required before the open parenthesis '('
#77: FILE: util/envlist.c:190:
+   if(0 == envname_len)

ERROR: braces {} are necessary for all arms of this statement
#77: FILE: util/envlist.c:190:
+   if(0 == envname_len)
[...]

ERROR: code indent should never use tabs
#78: FILE: util/envlist.c:191:
+^I^Ireturn (EINVAL);$

ERROR: return is not a function, parentheses are not required
#78: FILE: util/envlist.c:191:
+   return (EINVAL);

total: 18 errors, 0 warnings, 63 lines checked

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

=== OUTPUT END ===

Test command exited with code: 1


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

Re: [Qemu-devel] [PATCH RFC v4 18/20] intel_iommu: enable vfio devices

2017-01-22 Thread Peter Xu
On Sun, Jan 22, 2017 at 04:08:04PM +0800, Jason Wang wrote:

[...]

> >+static void vtd_iotlb_page_invalidate_notify(IntelIOMMUState *s,
> >+   uint16_t domain_id, hwaddr addr,
> >+   uint8_t am)
> >+{
> >+IntelIOMMUNotifierNode *node;
> >+VTDContextEntry ce;
> >+int ret;
> >+
> >+QLIST_FOREACH(node, &(s->notifiers_list), next) {
> >+VTDAddressSpace *vtd_as = node->vtd_as;
> >+ret = vtd_dev_to_context_entry(s, pci_bus_num(vtd_as->bus),
> >+   vtd_as->devfn, );
> >+if (!ret && domain_id == VTD_CONTEXT_ENTRY_DID(ce.hi)) {
> >+vtd_page_walk(, addr, addr + (1 << am) * VTD_PAGE_SIZE,
> >+  vtd_page_invalidate_notify_hook,
> >+  (void *)_as->iommu, true);
> 
> Why not simply trigger the notifier here? (or is this vfio required?)

Because we may only want to notify part of the region - we are with
mask here, but not exact size.

Consider this: guest (with caching mode) maps 12K memory (4K*3 pages),
the mask will be extended to 16K in the guest. In that case, we need
to explicitly go over the page entry to know that the 4th page should
not be notified.

> 
> >+}
> >+}
> >+}
> >+
> >  static void vtd_iotlb_page_invalidate(IntelIOMMUState *s, uint16_t 
> > domain_id,
> >hwaddr addr, uint8_t am)
> >  {
> >@@ -1215,6 +1243,7 @@ static void vtd_iotlb_page_invalidate(IntelIOMMUState 
> >*s, uint16_t domain_id,
> >  info.addr = addr;
> >  info.mask = ~((1 << am) - 1);
> >  g_hash_table_foreach_remove(s->iotlb, vtd_hash_remove_by_page, );
> >+vtd_iotlb_page_invalidate_notify(s, domain_id, addr, am);
> 
> I think it's better to squash DSI and GLOBAL invalidation into this patch,
> otherwise the patch is buggy.

I can do this. Thanks,

-- peterx



[Qemu-devel] [PATCH] util/envlist: Fix 2 bugs in envlist_setenv and envlist_unsetenv

2017-01-22 Thread Hu Chaojian
From: chaojianhu 

In envlist_setenv, if any malloc fails, there will be inconsistency on el_count.

And in envlist_unsetenv, if env is "", the strncmp will be passed, eventually 
wrong envlist_entry (shoud be the first one) will be  removed.

Finally, in envlist_parse, to delimit environments with ',' is wrong, since 
value
may contain ','. I suggest delete envlist_parse from the source code.

Reported-by: chaojianhu 
Signed-off-by: chaojianhu 

---
 util/envlist.c | 30 +-
 1 file changed, 17 insertions(+), 13 deletions(-)

diff --git a/util/envlist.c b/util/envlist.c
index e86857e..327478b 100644
--- a/util/envlist.c
+++ b/util/envlist.c
@@ -130,7 +130,7 @@ envlist_parse(envlist_t *envlist, const char *env,
 int
 envlist_setenv(envlist_t *envlist, const char *env)
 {
-   struct envlist_entry *entry = NULL;
+   struct envlist_entry *entry = NULL, *entry_old = NULL;
const char *eq_sign;
size_t envname_len;
 
@@ -147,26 +147,27 @@ envlist_setenv(envlist_t *envlist, const char *env)
 * we remove and release it before allocating a whole
 * new entry.
 */
-   for (entry = envlist->el_entries.lh_first; entry != NULL;
-   entry = entry->ev_link.le_next) {
-   if (strncmp(entry->ev_var, env, envname_len) == 0)
+   for (entry_old = envlist->el_entries.lh_first; entry_old != NULL;
+   entry_old = entry_old->ev_link.le_next) {
+   if (strncmp(entry_old->ev_var, env, envname_len) == 0)
break;
}
 
-   if (entry != NULL) {
-   QLIST_REMOVE(entry, ev_link);
-   free((char *)entry->ev_var);
-   free(entry);
-   } else {
-   envlist->el_count++;
-   }
-
if ((entry = malloc(sizeof (*entry))) == NULL)
return (errno);
if ((entry->ev_var = strdup(env)) == NULL) {
free(entry);
return (errno);
}
+
+   if (entry_old != NULL) {
+   QLIST_REMOVE(entry_old, ev_link);
+   free((char *)entry_old->ev_var);
+   free(entry_old);
+   } else {
+   envlist->el_count++;
+   }
+
QLIST_INSERT_HEAD(>el_entries, entry, ev_link);
 
return (0);
@@ -185,6 +186,10 @@ envlist_unsetenv(envlist_t *envlist, const char *env)
if ((envlist == NULL) || (env == NULL))
return (EINVAL);
 
+   envname_len = strlen(env);
+   if(0 == envname_len)
+   return (EINVAL);
+
/* env is not allowed to contain '=' */
if (strchr(env, '=') != NULL)
return (EINVAL);
@@ -193,7 +198,6 @@ envlist_unsetenv(envlist_t *envlist, const char *env)
 * Find out the requested entry and remove
 * it from the list.
 */
-   envname_len = strlen(env);
for (entry = envlist->el_entries.lh_first; entry != NULL;
entry = entry->ev_link.le_next) {
if (strncmp(entry->ev_var, env, envname_len) == 0)
-- 
1.9.1




Re: [Qemu-devel] [PATCH RFC v4 15/20] intel_iommu: provide its own replay() callback

2017-01-22 Thread Peter Xu
On Sun, Jan 22, 2017 at 03:56:10PM +0800, Jason Wang wrote:

[...]

> >+/**
> >+ * vtd_page_walk_level - walk over specific level for IOVA range
> >+ *
> >+ * @addr: base GPA addr to start the walk
> >+ * @start: IOVA range start address
> >+ * @end: IOVA range end address (start <= addr < end)
> >+ * @hook_fn: hook func to be called when detected page
> >+ * @private: private data to be passed into hook func
> >+ * @read: whether parent level has read permission
> >+ * @write: whether parent level has write permission
> >+ * @skipped: accumulated skipped ranges
> 
> What's the usage for this parameter? Looks like it was never used in this
> series.

This was for debugging purpose before, and I kept it in case one day
it can be used again, considering that will not affect much on the
overall performance.

> 
> >+ * @notify_unmap: whether we should notify invalid entries
> >+ */
> >+static int vtd_page_walk_level(dma_addr_t addr, uint64_t start,
> >+   uint64_t end, vtd_page_walk_hook hook_fn,
> >+   void *private, uint32_t level,
> >+   bool read, bool write, uint64_t *skipped,
> >+   bool notify_unmap)
> >+{
> >+bool read_cur, write_cur, entry_valid;
> >+uint32_t offset;
> >+uint64_t slpte;
> >+uint64_t subpage_size, subpage_mask;
> >+IOMMUTLBEntry entry;
> >+uint64_t iova = start;
> >+uint64_t iova_next;
> >+uint64_t skipped_local = 0;
> >+int ret = 0;
> >+
> >+trace_vtd_page_walk_level(addr, level, start, end);
> >+
> >+subpage_size = 1ULL << vtd_slpt_level_shift(level);
> >+subpage_mask = vtd_slpt_level_page_mask(level);
> >+
> >+while (iova < end) {
> >+iova_next = (iova & subpage_mask) + subpage_size;
> >+
> >+offset = vtd_iova_level_offset(iova, level);
> >+slpte = vtd_get_slpte(addr, offset);
> >+
> >+/*
> >+ * When one of the following case happens, we assume the whole
> >+ * range is invalid:
> >+ *
> >+ * 1. read block failed
> 
> Don't get the meaning (and don't see any code relate to this comment).

I took above vtd_get_slpte() a "read", so I was trying to mean that we
failed to read the SLPTE due to some reason, we assume the range is
invalid.

> 
> >+ * 3. reserved area non-zero
> >+ * 2. both read & write flag are not set
> 
> Should be 1,2,3? And the above comment is conflict with the code at least
> when notify_unmap is true.

Yes, okay I don't know why 3 jumped. :(

And yes, I should mention that "both read & write flag not set" only
suites for page tables here.

> 
> >+ */
> >+
> >+if (slpte == (uint64_t)-1) {
> 
> If this is true, vtd_slpte_nonzero_rsvd(slpte) should be true too I think?

Yes, but we are doing two checks here:

- checking against -1 to make sure slpte read success
- checking against nonzero reserved fields to make sure it follows spec

Imho we should not skip the first check here, only if one day removing
this may really matter (e.g., for performance reason? I cannot think
of one yet).

> 
> >+trace_vtd_page_walk_skip_read(iova, iova_next);
> >+skipped_local++;
> >+goto next;
> >+}
> >+
> >+if (vtd_slpte_nonzero_rsvd(slpte, level)) {
> >+trace_vtd_page_walk_skip_reserve(iova, iova_next);
> >+skipped_local++;
> >+goto next;
> >+}
> >+
> >+/* Permissions are stacked with parents' */
> >+read_cur = read && (slpte & VTD_SL_R);
> >+write_cur = write && (slpte & VTD_SL_W);
> >+
> >+/*
> >+ * As long as we have either read/write permission, this is
> >+ * a valid entry. The rule works for both page or page tables.
> >+ */
> >+entry_valid = read_cur | write_cur;
> >+
> >+if (vtd_is_last_slpte(slpte, level)) {
> >+entry.target_as = _space_memory;
> >+entry.iova = iova & subpage_mask;
> >+/*
> >+ * This might be meaningless addr if (!read_cur &&
> >+ * !write_cur), but after all this field will be
> >+ * meaningless in that case, so let's share the code to
> >+ * generate the IOTLBs no matter it's an MAP or UNMAP
> >+ */
> >+entry.translated_addr = vtd_get_slpte_addr(slpte);
> >+entry.addr_mask = ~subpage_mask;
> >+entry.perm = IOMMU_ACCESS_FLAG(read_cur, write_cur);
> >+if (!entry_valid && !notify_unmap) {
> >+trace_vtd_page_walk_skip_perm(iova, iova_next);
> >+skipped_local++;
> >+goto next;
> >+}
> 
> Under which case should we care about unmap here (better with a comment I
> think)?

When PSIs are for invalidation, rather than newly mapped entries. In
that case, notify_unmap will be true, and here we need to notify
IOMMU_NONE to do the cache flush or 

Re: [Qemu-devel] [PATCH RFC v4 19/20] intel_iommu: unmap existing pages before replay

2017-01-22 Thread Jason Wang



On 2017年01月20日 21:08, Peter Xu wrote:

Previous replay works for domain switch only if the original domain does
not have mapped pages. For example, if we switch domain from A to B, it
will only work if A has no existing mapping. If there is, then there's
problem - current replay didn't make sure the old mappings are cleared
before replaying the new one.


I'm not quite sure this is needed. I thought the only thing we need to 
do is stop DMA of device during the moving? Or is there an example that 
will cause trouble?


Thanks



Re: [Qemu-devel] [PATCH RFC v4 18/20] intel_iommu: enable vfio devices

2017-01-22 Thread Jason Wang



On 2017年01月20日 21:08, Peter Xu wrote:

This patch is based on Aviv Ben-David ()'s patch
upstream:

   "IOMMU: enable intel_iommu map and unmap notifiers"
   https://lists.gnu.org/archive/html/qemu-devel/2016-11/msg01453.html

However I removed/fixed some content, and added my own codes.

Instead of translate() every page for iotlb invalidations (which is
slower), we walk the pages when needed and notify in a hook function.

This patch enables vfio devices for VT-d emulation.

Signed-off-by: Peter Xu 
---
  hw/i386/intel_iommu.c | 66 +--
  include/hw/i386/intel_iommu.h |  8 ++
  2 files changed, 65 insertions(+), 9 deletions(-)

diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 83a2e1f..7cbf057 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -833,7 +833,8 @@ next:
   * @private: private data for the hook function
   */
  static int vtd_page_walk(VTDContextEntry *ce, uint64_t start, uint64_t end,
- vtd_page_walk_hook hook_fn, void *private)
+ vtd_page_walk_hook hook_fn, void *private,
+ bool notify_unmap)
  {
  dma_addr_t addr = vtd_get_slpt_base_from_context(ce);
  uint32_t level = vtd_get_level_from_context_entry(ce);
@@ -852,7 +853,7 @@ static int vtd_page_walk(VTDContextEntry *ce, uint64_t 
start, uint64_t end,
  trace_vtd_page_walk_level(addr, level, start, end);
  
  return vtd_page_walk_level(addr, start, end, hook_fn, private,

-   level, true, true, NULL, false);
+   level, true, true, NULL, notify_unmap);
  }
  
  /* Map a device to its corresponding domain (context-entry) */

@@ -1205,6 +1206,33 @@ static void vtd_iotlb_domain_invalidate(IntelIOMMUState 
*s, uint16_t domain_id)
  _id);
  }
  
+static int vtd_page_invalidate_notify_hook(IOMMUTLBEntry *entry,

+   void *private)
+{
+memory_region_notify_iommu((MemoryRegion *)private, *entry);
+return 0;
+}
+
+static void vtd_iotlb_page_invalidate_notify(IntelIOMMUState *s,
+   uint16_t domain_id, hwaddr addr,
+   uint8_t am)
+{
+IntelIOMMUNotifierNode *node;
+VTDContextEntry ce;
+int ret;
+
+QLIST_FOREACH(node, &(s->notifiers_list), next) {
+VTDAddressSpace *vtd_as = node->vtd_as;
+ret = vtd_dev_to_context_entry(s, pci_bus_num(vtd_as->bus),
+   vtd_as->devfn, );
+if (!ret && domain_id == VTD_CONTEXT_ENTRY_DID(ce.hi)) {
+vtd_page_walk(, addr, addr + (1 << am) * VTD_PAGE_SIZE,
+  vtd_page_invalidate_notify_hook,
+  (void *)_as->iommu, true);


Why not simply trigger the notifier here? (or is this vfio required?)


+}
+}
+}
+
  static void vtd_iotlb_page_invalidate(IntelIOMMUState *s, uint16_t domain_id,
hwaddr addr, uint8_t am)
  {
@@ -1215,6 +1243,7 @@ static void vtd_iotlb_page_invalidate(IntelIOMMUState *s, 
uint16_t domain_id,
  info.addr = addr;
  info.mask = ~((1 << am) - 1);
  g_hash_table_foreach_remove(s->iotlb, vtd_hash_remove_by_page, );
+vtd_iotlb_page_invalidate_notify(s, domain_id, addr, am);


I think it's better to squash DSI and GLOBAL invalidation into this 
patch, otherwise the patch is buggy.


Thanks