Re: [Qemu-devel] [PATCH v1 3/8] throttle: Add throttle group infrastructure tests
On Tue, 10/07 15:24, Benoît Canet wrote: Signed-off-by: Benoit Canet benoit.ca...@nodalink.com --- tests/test-throttle.c | 51 +++ 1 file changed, 51 insertions(+) diff --git a/tests/test-throttle.c b/tests/test-throttle.c index 3e52df3..ecb5504 100644 --- a/tests/test-throttle.c +++ b/tests/test-throttle.c @@ -15,6 +15,7 @@ #include block/aio.h #include qemu/throttle.h #include qemu/error-report.h +#include block/throttle-groups.h static AioContext *ctx; static LeakyBucketbkt; @@ -500,6 +501,55 @@ static void test_accounting(void) (64.0 / 13))); } +static void test_groups(void) +{ +bool removed; + +ThrottleState *ts_foo, *ts_bar, *tmp; + +ts_bar = throttle_group_incref(bar); +throttle_group_set_token(ts_bar, (BlockDriverState *) 0x5, false); Why do you have the magic numbers cast to pointers instead of allocated objects with bdrv_new? Fam +ts_foo = throttle_group_incref(foo); + +tmp = throttle_group_incref(foo); +throttle_group_set_token(tmp, (BlockDriverState *) 0x7, true); +g_assert(tmp == ts_foo); + +tmp = throttle_group_incref(bar); +g_assert(tmp == ts_bar); + +tmp = throttle_group_incref(bar); +g_assert(tmp == ts_bar); + +g_assert((int64_t) throttle_group_token(ts_bar, false) == 0x5); +g_assert((int64_t) throttle_group_token(ts_foo, true) == 0x7); + +removed = throttle_group_unref(ts_foo); +g_assert(removed); +removed = throttle_group_unref(ts_bar); +g_assert(removed); + +g_assert((int64_t) throttle_group_token(ts_foo, true) == 0x7); + +removed = throttle_group_unref(ts_foo); +g_assert(removed); +removed = throttle_group_unref(ts_bar); +g_assert(removed); + +/* foo group should be destroyed when reaching this */ +removed = throttle_group_unref(ts_foo); +g_assert(!removed); + +g_assert((int64_t) throttle_group_token(ts_bar, false) == 0x5); + +removed = throttle_group_unref(ts_bar); +g_assert(removed); + +/* bar group should be destroyed when reaching this */ +removed = throttle_group_unref(ts_bar); +g_assert(!removed); +} + int main(int argc, char **argv) { GSource *src; @@ -533,6 +583,7 @@ int main(int argc, char **argv) g_test_add_func(/throttle/config/is_valid,test_is_valid); g_test_add_func(/throttle/config_functions, test_config_functions); g_test_add_func(/throttle/accounting, test_accounting); +g_test_add_func(/throttle/groups, test_groups); return g_test_run(); } -- 2.1.1
Re: [Qemu-devel] [PATCH v1 6/8] throttle: Add a way to fire one of the timers asap like a bottom half
On Tue, 10/07 15:24, Benoît Canet wrote: This will be needed by the group throttling algorithm. Signed-off-by: Benoit Canet benoit.ca...@nodalink.com --- include/qemu/throttle.h | 2 ++ util/throttle.c | 11 +++ 2 files changed, 13 insertions(+) diff --git a/include/qemu/throttle.h b/include/qemu/throttle.h index 3a16c48..3b9d1b8 100644 --- a/include/qemu/throttle.h +++ b/include/qemu/throttle.h @@ -127,6 +127,8 @@ bool throttle_schedule_timer(ThrottleState *ts, bool is_write, bool *armed); +void throttle_fire_timer(ThrottleTimers *tt, bool is_write); + void throttle_timer_fired(ThrottleState *ts, bool is_write); void throttle_account(ThrottleState *ts, bool is_write, uint64_t size); diff --git a/util/throttle.c b/util/throttle.c index a273acb..163b9d0 100644 --- a/util/throttle.c +++ b/util/throttle.c @@ -403,6 +403,17 @@ bool throttle_schedule_timer(ThrottleState *ts, return true; } +/* Schedule a throttle timer like a BH Why not use a real BH? It's more efficient than a timer scheduled at now + 1. Fam + * + * @tt: The timers structure + * @is_write: the type of operation (read/write) + */ +void throttle_fire_timer(ThrottleTimers *tt, bool is_write) +{ +int64_t now = qemu_clock_get_ns(tt-clock_type); +timer_mod(tt-timers[is_write], now + 1); +} + /* Remember that now timers are currently armed * * @ts: the throttle state we are working on -- 2.1.1
Re: [Qemu-devel] [PATCH v1 7/8] throttle: Add throttle group support
On Tue, 10/07 15:24, Benoît Canet wrote: The throttle group support use a cooperative round robin scheduling algorithm. The principle of the algorithm are simple: s/principle/principles/ - Each BDS of the group is used as a token in a circular way. - The active BDS compute if a wait must be done and arm the right timer. - If a wait must be done the token timer will be armed so the token will become the next active BDS. Signed-off-by: Benoit Canet benoit.ca...@nodalink.com --- block.c | 191 -- block/qapi.c | 7 +- block/throttle-groups.c | 2 +- blockdev.c| 19 - hmp.c | 4 +- include/block/block.h | 3 +- include/block/block_int.h | 9 ++- qapi/block-core.json | 5 +- qemu-options.hx | 1 + qmp-commands.hx | 3 +- 10 files changed, 209 insertions(+), 35 deletions(-) diff --git a/block.c b/block.c index 527ea48..e7e5607 100644 --- a/block.c +++ b/block.c @@ -36,6 +36,7 @@ #include qmp-commands.h #include qemu/timer.h #include qapi-event.h +#include block/throttle-groups.h #ifdef CONFIG_BSD #include sys/types.h @@ -129,7 +130,9 @@ void bdrv_set_io_limits(BlockDriverState *bs, { int i; -throttle_config(bs-throttle_state, bs-throttle_timers, cfg); +throttle_group_lock(bs-throttle_state); +throttle_config(bs-throttle_state, bs-throttle_timers, cfg); +throttle_group_unlock(bs-throttle_state); for (i = 0; i 2; i++) { qemu_co_enter_next(bs-throttled_reqs[i]); @@ -156,34 +159,99 @@ static bool bdrv_start_throttled_reqs(BlockDriverState *bs) return drained; } +static void bdrv_throttle_group_add(BlockDriverState *bs) +{ +int i; +BlockDriverState *token; + +for (i = 0; i 2; i++) { +/* Get the BlockDriverState having the round robin token */ +token = throttle_group_token(bs-throttle_state, i); + +/* If the ThrottleGroup is new set the current BlockDriverState as + * token + */ +if (!token) { +throttle_group_set_token(bs-throttle_state, bs, i); +} + +} + +throttle_group_register_bs(bs-throttle_state, bs); +} + +static void bdrv_throttle_group_remove(BlockDriverState *bs) +{ +BlockDriverState *token; +int i; + +for (i = 0; i 2; i++) { +/* Get the BlockDriverState having the round robin token */ +token = throttle_group_token(bs-throttle_state, i); +/* if this bs is the current token set the next bs as token */ +if (token == bs) { +token = throttle_group_next_bs(token); +/* take care of the case where bs is the only bs of the group */ +if (token == bs) { +token = NULL; +} +throttle_group_set_token(bs-throttle_state, token, i); +} +} + +/* remove the current bs from the list */ +QLIST_REMOVE(bs, round_robin); +} + void bdrv_io_limits_disable(BlockDriverState *bs) { + +throttle_group_lock(bs-throttle_state); bs-io_limits_enabled = false; +throttle_group_unlock(bs-throttle_state); bdrv_start_throttled_reqs(bs); +throttle_group_lock(bs-throttle_state); +bdrv_throttle_group_remove(bs); +throttle_group_unlock(bs-throttle_state); + +throttle_group_unref(bs-throttle_state); +bs-throttle_state = NULL; + throttle_timers_destroy(bs-throttle_timers); } static void bdrv_throttle_read_timer_cb(void *opaque) { BlockDriverState *bs = opaque; -throttle_timer_fired(bs-throttle_state, false); + +throttle_group_lock(bs-throttle_state); +throttle_timer_fired(bs-throttle_state, false); +throttle_group_unlock(bs-throttle_state); + qemu_co_enter_next(bs-throttled_reqs[0]); } static void bdrv_throttle_write_timer_cb(void *opaque) { BlockDriverState *bs = opaque; -throttle_timer_fired(bs-throttle_state, true); + +throttle_group_lock(bs-throttle_state); +throttle_timer_fired(bs-throttle_state, true); +throttle_group_unlock(bs-throttle_state); + qemu_co_enter_next(bs-throttled_reqs[1]); } /* should be called before bdrv_set_io_limits if a limit is set */ -void bdrv_io_limits_enable(BlockDriverState *bs) +void bdrv_io_limits_enable(BlockDriverState *bs, const char *group) Does this mean that after this series, all the throttle_states must be contained inside its own throttle group? If so, we could embed ThrottleGroup fields in ThrottleState. It's weird when a function called throttle_group_compare takes a parameter of ThrottleState pointer, and cast it back to ThrottleGroup with container_of. Fam
Re: [Qemu-devel] [PATCH 1/2] qemu-char: Fix reconnect socket error reporting
miny...@acm.org writes: From: Corey Minyard cminy...@mvista.com If reconnect was set, errors wouldn't always be reported. Fix that and also only report a connect error once until a connection has been made. The primary purpose of this is to tell the user that a connection failed so they can know they need to figure out what went wrong. So we don't want to spew too much out here, just enough so they know. Signed-off-by: Corey Minyard cminy...@mvista.com --- qemu-char.c | 47 --- 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/qemu-char.c b/qemu-char.c index 62af0ef..fb895c7 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -2509,6 +2509,7 @@ typedef struct { guint reconnect_timer; int64_t reconnect_time; +bool connect_err_reported; } TCPCharDriver; static gboolean socket_reconnect_timeout(gpointer opaque); Doesn't apply, obviously depends on some other patch. Always state your dependencies explicitly in the cover letter! [...]
Re: [Qemu-devel] [PATCH v2] qemu-ga: added windows support for 'guest-network-get-interfaces'
I will take care of the below items as soon as I get some free time. /Kenth On 01 Oct 2014, at 19:45, Michael Roth mdr...@linux.vnet.ibm.com wrote: Quoting Kenth Andersson (2014-09-29 13:22:54) Implementation of guest-network-get-interfaces for windows Signed-off-by: Kenth Andersson ke...@eastmark.net Thanks! I've been testing the functionality and it seems work nicely. Some review comments below though: --- configure| 2 +- qga/commands-win32.c | 247 ++- 2 files changed, 244 insertions(+), 5 deletions(-) diff --git a/configure b/configure index 681abfc..7c6c60c 100755 --- a/configure +++ b/configure @@ -717,7 +717,7 @@ EOF sysconfdir=\${prefix} local_statedir= confsuffix= - libs_qga=-lws2_32 -lwinmm -lpowrprof $libs_qga + libs_qga=-lws2_32 -lwinmm -lpowrprof -liphlpapi $libs_qga fi werror= diff --git a/qga/commands-win32.c b/qga/commands-win32.c index 3bcbeae..fb6fdba 100644 --- a/qga/commands-win32.c +++ b/qga/commands-win32.c @@ -14,6 +14,9 @@ #include glib.h #include wtypes.h #include powrprof.h +#include winsock2.h +#include iphlpapi.h +#include ws2tcpip.h #include qga/guest-agent-core.h #include qga/vss-win32.h #include qga-qmp-commands.h @@ -29,6 +32,9 @@ (365 * (1970 - 1601) + \ (1970 - 1601) / 4 - 3)) +/* Defines the max length of an IPv6 address in human readable format + pad */ +#define MAX_IPv6_LEN 50 + static void acquire_privilege(const char *name, Error **errp) { HANDLE token = NULL; @@ -359,10 +365,244 @@ void qmp_guest_suspend_hybrid(Error **errp) error_set(errp, QERR_UNSUPPORTED); } +static int get_prefix_length(PIP_ADAPTER_PREFIX prefix, + SOCKET_ADDRESS *sockaddr, int socklen) +{ +PIP_ADAPTER_PREFIX p; +struct sockaddr *addr = sockaddr-lpSockaddr; + +for (p = prefix; p; p = p-Next) { +/* Compare the ip-adderss address family with the prefix + * address family */ +if (addr-sa_family == p-Address.lpSockaddr-sa_family) { +int num_bytes = p-PrefixLength / 8; +unsigned char *src = 0; +unsigned char *dst = 0; +int remaining_bits; + +if (addr-sa_family == AF_INET) { +struct sockaddr_in *sin = (struct sockaddr_in *)addr; +src = (unsigned char *)(sin-sin_addr.s_addr); +} else if (addr-sa_family == AF_INET6) { +struct sockaddr_in6 *sin = (struct sockaddr_in6 *)addr; +src = (unsigned char *)sin-sin6_addr.s6_addr; +} + +if (p-Address.lpSockaddr-sa_family == AF_INET) { +struct sockaddr_in *sin = +(struct sockaddr_in *)p-Address.lpSockaddr; +dst = (unsigned char *)(sin-sin_addr.s_addr); +} else if (p-Address.lpSockaddr-sa_family == AF_INET6) { +struct sockaddr_in6 *sin = +(struct sockaddr_in6 *)p-Address.lpSockaddr; +dst = (unsigned char *)sin-sin6_addr.s6_addr; +} + +/* If non of the addresses are in correct format we will continue + * to next one */ +if (src == 0 || dst == 0) { +continue; +} + +/* Check if prefix network is the same network as we are testing + * start with whole bytes */ + +if (memcmp(src, dst, num_bytes) != 0) { +continue; +} + +/* Check the remaning bits */ +remaining_bits = p-PrefixLength % 8; + +if (remaining_bits != 0) { +unsigned char mask = 0xff (8 - remaining_bits); +int i = num_bytes; + +if ((src[i] mask) != (dst[i] mask)) { +continue; +} +} + +return p-PrefixLength; +} +} +return 0; +} + + + GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp) { -error_set(errp, QERR_UNSUPPORTED); -return NULL; +GuestNetworkInterfaceList *head = NULL, *curr_item = NULL; +DWORD ret_val; + +PIP_ADAPTER_ADDRESSES adpt_addrs; +PIP_ADAPTER_ADDRESSES curr_adpt_addrs; +PIP_ADAPTER_UNICAST_ADDRESS adpt_uc_addr; + +/* GetAdaptersAddresses requires ULONG */ +ULONG bufLen = sizeof(IP_ADAPTER_ADDRESSES); buf_len + +/* Startup WinSock32 */ +WORD ws_version_requested = MAKEWORD(2, 2); +WSADATA ws_data; +WSAStartup(ws_version_requested, ws_data); Since this can fail, we should return an error and bail (after calling WSACleanup). Something like: error_setg(errp, failed to initialize Windows Socket API v2.2); + +/* Allocate adapter address list with one entry, used to + * fetch the
Re: [Qemu-devel] [QA-virtio]:Why vring size is limited to 1024?
Thanks for your patient answer! :-) On 2014/9/30 17:33, Michael S. Tsirkin wrote: On Tue, Sep 30, 2014 at 04:36:00PM +0800, Zhangjie (HZ) wrote: Hi, There exits packets loss when we do packet forwarding in VM, especially when we use dpdk to do the forwarding. By enlarging vring can alleviate the problem. I think this has to do with the fact that dpdk disables checksum offloading, this has the side effect of disabling segmentation offloading. Please fix dpdk to support checksum offloading, and I think the problem will go away. In some application scene, loss of udp packets are not allowed, and udp packets are always short than mtu. So, we need to support high pps(eg.0.3M Packets/s) forwarding, and offloading cannot fix it. But now vring size is limited to 1024 as follows: VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size, void (*handle_output)(VirtIODevice *, VirtQueue *)) { ... if (i == VIRTIO_PCI_QUEUE_MAX || queue_size VIRTQUEUE_MAX_SIZE) abort(); } ps:#define VIRTQUEUE_MAX_SIZE 1024 I delete the judgement code, and set vring size to 2048, VM can be successfully started, and the network is ok too. So, Why vring size is limited to 1024 and what is the influence? Thanks! There are several reason for this limit. First guest has to allocate descriptor buffer which is 16 * vring size. With 1K size that is already 16K which might be tricky to allocate contigiously if memory is fragmented when device is added by hotplug. That is very The second issue is that we want to be able to implement the device on top of linux kernel, and a single descriptor might use all of the virtqueue. In this case we wont to be able to pass the descriptor directly to linux as a single iov, since that is limited to 1K entries. For the second issue, I wonder if it is ok to set vring size of virtio-net to large than 1024, as for net work, there is at most 18 pages for a skb, it will not exceed iov. -- Best Wishes! Zhang Jie . -- Best Wishes! Zhang Jie
Re: [Qemu-devel] [PATCH v3] pc-dimm/numa: Fix stat of memory size in node when hotplug memory
Hi Igor, On 2014/9/26 19:53, Igor Mammedov wrote: On Tue, 23 Sep 2014 16:11:25 +0800 zhanghailiang zhang.zhanghaili...@huawei.com wrote: When do memory hotplug, if there is numa node, we should add the memory size to the corresponding node memory size. For now, it mainly affects the result of hmp command info numa. Signed-off-by: zhanghailiang zhang.zhanghaili...@huawei.com please make sure that this doesn't breaks other targets. PS: to make test builds you can use travis-ci.org+github service Sorry for the delayed response.;) I have test the build as you suggested, and yes, it will break other targets. The main reason here is, there is a compile switch for memory hotplug (CONFIG_MEM_HOTPLUG), which is off for other targets, and pc-dimm.c is not include when compile. Here i also use the compile switch to fix this problem, and will send V4. Thanks, zhanghailiang --- v3: - cold-plugged memory should not be excluded when stat memory size (Igor Mammedov) v2: - Don't modify the numa_info.node_mem directly when treating hotplug memory, fix the info numa instead (suggested by Igor Mammedov) --- hw/mem/pc-dimm.c | 30 ++ include/hw/mem/pc-dimm.h | 2 ++ include/sysemu/sysemu.h | 1 + monitor.c| 6 +- numa.c | 15 +++ 5 files changed, 53 insertions(+), 1 deletion(-) diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c index 5bfc5b7..8e80d74 100644 --- a/hw/mem/pc-dimm.c +++ b/hw/mem/pc-dimm.c @@ -195,6 +195,36 @@ out: return ret; } +static int pc_dimm_stat_mem_size(Object *obj, void *opaque) +{ +uint64_t *node_mem = opaque; +int ret; + +if (object_dynamic_cast(obj, TYPE_PC_DIMM)) { +DeviceState *dev = DEVICE(obj); + +if (dev-realized) { +PCDIMMDevice *dimm = PC_DIMM(obj); +int size; + +size = object_property_get_int(OBJECT(dimm), PC_DIMM_SIZE_PROP, + NULL); +if (size 0) { +return -1; +} +node_mem[dimm-node] += size; +} +} + +ret = object_child_foreach(obj, pc_dimm_stat_mem_size, opaque); +return ret; +} + +void pc_dimm_stat_node_mem(uint64_t *node_mem) +{ +object_child_foreach(qdev_get_machine(), pc_dimm_stat_mem_size, node_mem); +} + static Property pc_dimm_properties[] = { DEFINE_PROP_UINT64(PC_DIMM_ADDR_PROP, PCDIMMDevice, addr, 0), DEFINE_PROP_UINT32(PC_DIMM_NODE_PROP, PCDIMMDevice, node, 0), diff --git a/include/hw/mem/pc-dimm.h b/include/hw/mem/pc-dimm.h index 761eeef..0c9a8eb 100644 --- a/include/hw/mem/pc-dimm.h +++ b/include/hw/mem/pc-dimm.h @@ -78,4 +78,6 @@ uint64_t pc_dimm_get_free_addr(uint64_t address_space_start, int pc_dimm_get_free_slot(const int *hint, int max_slots, Error **errp); int qmp_pc_dimm_device_list(Object *obj, void *opaque); + +void pc_dimm_stat_node_mem(uint64_t *node_mem); #endif diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h index d8539fd..cfc1592 100644 --- a/include/sysemu/sysemu.h +++ b/include/sysemu/sysemu.h @@ -160,6 +160,7 @@ typedef struct node_info { extern NodeInfo numa_info[MAX_NODES]; void set_numa_nodes(void); void set_numa_modes(void); +int query_numa_node_mem(uint64_t *node_mem); extern QemuOptsList qemu_numa_opts; int numa_init_func(QemuOpts *opts, void *opaque); diff --git a/monitor.c b/monitor.c index 7467521..c8c812f 100644 --- a/monitor.c +++ b/monitor.c @@ -1948,7 +1948,10 @@ static void do_info_numa(Monitor *mon, const QDict *qdict) { int i; CPUState *cpu; +uint64_t *node_mem; +node_mem = g_new0(uint64_t, nb_numa_nodes); +query_numa_node_mem(node_mem); monitor_printf(mon, %d nodes\n, nb_numa_nodes); for (i = 0; i nb_numa_nodes; i++) { monitor_printf(mon, node %d cpus:, i); @@ -1959,8 +1962,9 @@ static void do_info_numa(Monitor *mon, const QDict *qdict) } monitor_printf(mon, \n); monitor_printf(mon, node %d size: % PRId64 MB\n, i, -numa_info[i].node_mem 20); +node_mem[i] 20); } +g_free(node_mem); } #ifdef CONFIG_PROFILER diff --git a/numa.c b/numa.c index 3b98135..4e27dd8 100644 --- a/numa.c +++ b/numa.c @@ -35,6 +35,7 @@ #include hw/boards.h #include sysemu/hostmem.h #include qmp-commands.h +#include hw/mem/pc-dimm.h QemuOptsList qemu_numa_opts = { .name = numa, @@ -315,6 +316,20 @@ void memory_region_allocate_system_memory(MemoryRegion *mr, Object *owner, } } +int query_numa_node_mem(uint64_t *node_mem) +{ +int i; + +if (nb_numa_nodes = 0) { +return 0; +} +pc_dimm_stat_node_mem(node_mem); +for (i = 0; i nb_numa_nodes; i++) { +node_mem[i] += numa_info[i].node_mem; +} +return 0; +} + static int query_memdev(Object *obj, void *opaque) { MemdevList **list = opaque; .
Re: [Qemu-devel] [QA-virtio]:Why vring size is limited to 1024?
On Wed, Oct 08, 2014 at 03:17:56PM +0800, Zhangjie (HZ) wrote: Thanks for your patient answer! :-) On 2014/9/30 17:33, Michael S. Tsirkin wrote: On Tue, Sep 30, 2014 at 04:36:00PM +0800, Zhangjie (HZ) wrote: Hi, There exits packets loss when we do packet forwarding in VM, especially when we use dpdk to do the forwarding. By enlarging vring can alleviate the problem. I think this has to do with the fact that dpdk disables checksum offloading, this has the side effect of disabling segmentation offloading. Please fix dpdk to support checksum offloading, and I think the problem will go away. In some application scene, loss of udp packets are not allowed, and udp packets are always short than mtu. So, we need to support high pps(eg.0.3M Packets/s) forwarding, and offloading cannot fix it. That's the point. With UFO you get larger than MTU UDP packets: http://www.linuxfoundation.org/collaborate/workgroups/networking/ufo Additionally, checksum offloading reduces CPU utilization and reduces the number of data copies, allowing higher pps with smaller buffers. It might look like queue depth helps performance for netperf, but in real-life workloads the latency under load will suffer, with more protocols implementing tunnelling on top of UDP such extreme bufferbloat will not be tolerated. But now vring size is limited to 1024 as follows: VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size, void (*handle_output)(VirtIODevice *, VirtQueue *)) { ... if (i == VIRTIO_PCI_QUEUE_MAX || queue_size VIRTQUEUE_MAX_SIZE) abort(); } ps:#define VIRTQUEUE_MAX_SIZE 1024 I delete the judgement code, and set vring size to 2048, VM can be successfully started, and the network is ok too. So, Why vring size is limited to 1024 and what is the influence? Thanks! There are several reason for this limit. First guest has to allocate descriptor buffer which is 16 * vring size. With 1K size that is already 16K which might be tricky to allocate contigiously if memory is fragmented when device is added by hotplug. That is very The second issue is that we want to be able to implement the device on top of linux kernel, and a single descriptor might use all of the virtqueue. In this case we wont to be able to pass the descriptor directly to linux as a single iov, since that is limited to 1K entries. For the second issue, I wonder if it is ok to set vring size of virtio-net to large than 1024, as for net work, there is at most 18 pages for a skb, it will not exceed iov. -- Best Wishes! Zhang Jie . -- Best Wishes! Zhang Jie
Re: [Qemu-devel] [QA-virtio]:Why vring size is limited to 1024?
On 09/30/2014 12:33 PM, Michael S. Tsirkin wrote: a single descriptor might use all of the virtqueue. In this case we wont to be able to pass the descriptor directly to linux as a single iov, since You could separate maximum request scatter/gather list size from the virtqueue size. They are totally unrelated - even now you can have a larger request by using indirect descriptors.
Re: [Qemu-devel] [PATCH 1/1] target-i386: prevent users from setting threads1 for AMD CPUs
Il 08/10/2014 02:41, Wei Huang ha scritto: I am OK with either way. The key question is: should QEMU presents CPUIDs strictly as specified by the command line or QEMU can tweak a little bit on behalf of end-users? For instance, if end-users say -smp 8,cores=2,threads=2,sockets=2, they meant two socket, each has two 2-hyperthread cores. Current QEMU will convert CPUID as two socket, each has 4 cores. My patch will forbid the tweaking... Understood---it actually looks like it was intentional: commit 400281af34e5ee6aa9f5496b53d8f82c6fef9319 Author: Andre Przywara andre.przyw...@amd.com Date: Wed Aug 19 15:42:42 2009 +0200 set CPUID bits to present cores and threads topology Controlled by the enhanced -smp option set the CPUID bits to present the guest the desired topology. This is vendor specific, but (with the exception of the CMP_LEGACY bit) not conflicting, so we set all bits everytime. There is no real multithreading support for AMD CPUs, so report cores instead. Signed-off-by: Andre Przywara andre.przyw...@amd.com Signed-off-by: Anthony Liguori aligu...@us.ibm.com Paolo
Re: [Qemu-devel] [PATCH v4 36/47] Page request: Process incoming page request
* zhanghailiang (zhang.zhanghaili...@huawei.com) wrote: typedef struct Visitor Visitor; @@ -80,6 +81,6 @@ typedef struct FWCfgState FWCfgState; typedef struct PcGuestInfo PcGuestInfo; typedef struct PostcopyPMI PostcopyPMI; typedef struct Range Range; -typedef struct AdapterInfo AdapterInfo; +typedef struct RAMBlock RAMBlock; :(, another redefinition, 'RAMBlock' also defined in 'include/exec/cpu-all.h:314', Am i miss something when compile qemu? Interesting; I'm not seeing that problem at all (gcc 4.8.3-7) What compiler and flags are you using? Dave #endif /* QEMU_TYPEDEFS_H */ diff --git a/migration.c b/migration.c index cfdaa52..63d7699 100644 --- a/migration.c +++ b/migration.c @@ -26,6 +26,8 @@ #include qemu/thread.h #include qmp-commands.h #include trace.h +#include exec/memory.h +#include exec/address-spaces.h //#define DEBUG_MIGRATION @@ -504,6 +506,15 @@ static void migrate_fd_cleanup(void *opaque) migrate_fd_cleanup_src_rp(s); +/* This queue generally should be empty - but in the case of a failed + * migration might have some droppings in. + */ +struct MigrationSrcPageRequest *mspr, *next_mspr; +QSIMPLEQ_FOREACH_SAFE(mspr, s-src_page_requests, next_req, next_mspr) { +QSIMPLEQ_REMOVE_HEAD(s-src_page_requests, next_req); +g_free(mspr); +} + if (s-file) { trace_migrate_fd_cleanup(); qemu_mutex_unlock_iothread(); @@ -610,6 +621,9 @@ MigrationState *migrate_init(const MigrationParams *params) s-state = MIG_STATE_SETUP; trace_migrate_set_state(MIG_STATE_SETUP); +qemu_mutex_init(s-src_page_req_mutex); +QSIMPLEQ_INIT(s-src_page_requests); + s-total_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME); return s; } @@ -823,7 +837,25 @@ static void source_return_path_bad(MigrationState *s) static void migrate_handle_rp_reqpages(MigrationState *ms, const char* rbname, ram_addr_t start, ram_addr_t len) { -DPRINTF(migrate_handle_rp_reqpages: at %zx for len %zx, start, len); +DPRINTF(migrate_handle_rp_reqpages: in %s start %zx len %zx, +rbname, start, len); + +/* Round everything up to our host page size */ +long our_host_ps = sysconf(_SC_PAGESIZE); +if (start (our_host_ps-1)) { +long roundings = start (our_host_ps-1); +start -= roundings; +len += roundings; +} +if (len (our_host_ps-1)) { +long roundings = len (our_host_ps-1); +len -= roundings; +len += our_host_ps; +} + +if (ram_save_queue_pages(ms, rbname, start, len)) { +source_return_path_bad(ms); +} } /* -- Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK
Re: [Qemu-devel] [PATCH v2 37/36] qdev: device_del: search for to be unplugged device in 'peripheral' container
Il 08/10/2014 05:49, Zhu Guihua ha scritto: when device_add pc-dimm, only 'memdev' property is necessary, but the 'id' property is optional. So I execute the command as followings: object_add memory-backend-ram,id=ram0,size=128M device_add pc-dimm,memdev=ram0 Now it is impossible to delete the pc-dimm, because it has no id, and it is inside of 'peripheral-anon' container. Sure; but that was an explicit choice when you issued device_add. Paolo
Re: [Qemu-devel] [PATCH v4 36/47] Page request: Process incoming page request
Il 08/10/2014 09:49, Dr. David Alan Gilbert ha scritto: :(, another redefinition, 'RAMBlock' also defined in 'include/exec/cpu-all.h:314', Am i miss something when compile qemu? Interesting; I'm not seeing that problem at all (gcc 4.8.3-7) What compiler and flags are you using? I think it is visible with CentOS 6. Paolo
Re: [Qemu-devel] [QA-virtio]:Why vring size is limited to 1024?
MST, Thanks very much, I get it. On 2014/10/8 15:37, Michael S. Tsirkin wrote: On Wed, Oct 08, 2014 at 03:17:56PM +0800, Zhangjie (HZ) wrote: Thanks for your patient answer! :-) On 2014/9/30 17:33, Michael S. Tsirkin wrote: On Tue, Sep 30, 2014 at 04:36:00PM +0800, Zhangjie (HZ) wrote: Hi, There exits packets loss when we do packet forwarding in VM, especially when we use dpdk to do the forwarding. By enlarging vring can alleviate the problem. I think this has to do with the fact that dpdk disables checksum offloading, this has the side effect of disabling segmentation offloading. Please fix dpdk to support checksum offloading, and I think the problem will go away. In some application scene, loss of udp packets are not allowed, and udp packets are always short than mtu. So, we need to support high pps(eg.0.3M Packets/s) forwarding, and offloading cannot fix it. That's the point. With UFO you get larger than MTU UDP packets: http://www.linuxfoundation.org/collaborate/workgroups/networking/ufo Then vm only do forwarding, and not create new packets itself. As we can not gro normal udp packets, when udp packets come from the nic of host, ufo cannot work. Additionally, checksum offloading reduces CPU utilization and reduces the number of data copies, allowing higher pps with smaller buffers. It might look like queue depth helps performance for netperf, but in real-life workloads the latency under load will suffer, with more protocols implementing tunnelling on top of UDP such extreme bufferbloat will not be tolerated. But now vring size is limited to 1024 as follows: VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size, void (*handle_output)(VirtIODevice *, VirtQueue *)) { ... if (i == VIRTIO_PCI_QUEUE_MAX || queue_size VIRTQUEUE_MAX_SIZE) abort(); } ps:#define VIRTQUEUE_MAX_SIZE 1024 I delete the judgement code, and set vring size to 2048, VM can be successfully started, and the network is ok too. So, Why vring size is limited to 1024 and what is the influence? Thanks! There are several reason for this limit. First guest has to allocate descriptor buffer which is 16 * vring size. With 1K size that is already 16K which might be tricky to allocate contigiously if memory is fragmented when device is added by hotplug. That is very The second issue is that we want to be able to implement the device on top of linux kernel, and a single descriptor might use all of the virtqueue. In this case we wont to be able to pass the descriptor directly to linux as a single iov, since that is limited to 1K entries. For the second issue, I wonder if it is ok to set vring size of virtio-net to large than 1024, as for net work, there is at most 18 pages for a skb, it will not exceed iov. -- Best Wishes! Zhang Jie . -- Best Wishes! Zhang Jie . -- Best Wishes! Zhang Jie
Re: [Qemu-devel] [PATCH v4 36/47] Page request: Process incoming page request
On 2014/10/8 15:49, Dr. David Alan Gilbert wrote: * zhanghailiang (zhang.zhanghaili...@huawei.com) wrote: typedef struct Visitor Visitor; @@ -80,6 +81,6 @@ typedef struct FWCfgState FWCfgState; typedef struct PcGuestInfo PcGuestInfo; typedef struct PostcopyPMI PostcopyPMI; typedef struct Range Range; -typedef struct AdapterInfo AdapterInfo; +typedef struct RAMBlock RAMBlock; :(, another redefinition, 'RAMBlock' also defined in 'include/exec/cpu-all.h:314', Am i miss something when compile qemu? Interesting; I'm not seeing that problem at all (gcc 4.8.3-7) What compiler and flags are you using? Dave Hi Dave, My compiler info: gcc (SUSE Linux) 4.3.4 The configure info is: #./configure --target-list=x86_64-softmmu --enable-debug --disable-gtk ... CFLAGS-pthread -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -g QEMU_CFLAGS -fPIE -DPIE -m64 -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -Wstrict-prototypes -Wredundant-decls -Wall -Wundef -Wwrite-strings -Wmissing-prototypes -fno-strict-aliasing -fno-common -Wendif-labels -Wmissing-include-dirs -Wempty-body -Wnested-externs -Wformat-security -Wformat-y2k -Winit-self -Wignored-qualifiers -Wold-style-declaration -Wold-style-definition -Wtype-limits -fstack-protector-all-I/usr/include/libpng12 -I/usr/include/pixman-1 LDFLAGS -Wl,--warn-common -Wl,-z,relro -Wl,-z,now -pie -m64 -g ... Maybe its gcc's limitation, but why this redefinition need? After i remove one, it compiles successfully;) Thanks, zhanghailiang #endif /* QEMU_TYPEDEFS_H */ diff --git a/migration.c b/migration.c index cfdaa52..63d7699 100644 --- a/migration.c +++ b/migration.c @@ -26,6 +26,8 @@ #include qemu/thread.h #include qmp-commands.h #include trace.h +#include exec/memory.h +#include exec/address-spaces.h //#define DEBUG_MIGRATION @@ -504,6 +506,15 @@ static void migrate_fd_cleanup(void *opaque) migrate_fd_cleanup_src_rp(s); +/* This queue generally should be empty - but in the case of a failed + * migration might have some droppings in. + */ +struct MigrationSrcPageRequest *mspr, *next_mspr; +QSIMPLEQ_FOREACH_SAFE(mspr, s-src_page_requests, next_req, next_mspr) { +QSIMPLEQ_REMOVE_HEAD(s-src_page_requests, next_req); +g_free(mspr); +} + if (s-file) { trace_migrate_fd_cleanup(); qemu_mutex_unlock_iothread(); @@ -610,6 +621,9 @@ MigrationState *migrate_init(const MigrationParams *params) s-state = MIG_STATE_SETUP; trace_migrate_set_state(MIG_STATE_SETUP); +qemu_mutex_init(s-src_page_req_mutex); +QSIMPLEQ_INIT(s-src_page_requests); + s-total_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME); return s; } @@ -823,7 +837,25 @@ static void source_return_path_bad(MigrationState *s) static void migrate_handle_rp_reqpages(MigrationState *ms, const char* rbname, ram_addr_t start, ram_addr_t len) { -DPRINTF(migrate_handle_rp_reqpages: at %zx for len %zx, start, len); +DPRINTF(migrate_handle_rp_reqpages: in %s start %zx len %zx, +rbname, start, len); + +/* Round everything up to our host page size */ +long our_host_ps = sysconf(_SC_PAGESIZE); +if (start (our_host_ps-1)) { +long roundings = start (our_host_ps-1); +start -= roundings; +len += roundings; +} +if (len (our_host_ps-1)) { +long roundings = len (our_host_ps-1); +len -= roundings; +len += our_host_ps; +} + +if (ram_save_queue_pages(ms, rbname, start, len)) { +source_return_path_bad(ms); +} } /* -- Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK .
Re: [Qemu-devel] [PATCH v4 36/47] Page request: Process incoming page request
* zhanghailiang (zhang.zhanghaili...@huawei.com) wrote: On 2014/10/8 15:49, Dr. David Alan Gilbert wrote: * zhanghailiang (zhang.zhanghaili...@huawei.com) wrote: typedef struct Visitor Visitor; @@ -80,6 +81,6 @@ typedef struct FWCfgState FWCfgState; typedef struct PcGuestInfo PcGuestInfo; typedef struct PostcopyPMI PostcopyPMI; typedef struct Range Range; -typedef struct AdapterInfo AdapterInfo; +typedef struct RAMBlock RAMBlock; :(, another redefinition, 'RAMBlock' also defined in 'include/exec/cpu-all.h:314', Am i miss something when compile qemu? Interesting; I'm not seeing that problem at all (gcc 4.8.3-7) What compiler and flags are you using? Dave Hi Dave, My compiler info: gcc (SUSE Linux) 4.3.4 The configure info is: #./configure --target-list=x86_64-softmmu --enable-debug --disable-gtk ... CFLAGS-pthread -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -g QEMU_CFLAGS -fPIE -DPIE -m64 -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -Wstrict-prototypes -Wredundant-decls -Wall -Wundef -Wwrite-strings -Wmissing-prototypes -fno-strict-aliasing -fno-common -Wendif-labels -Wmissing-include-dirs -Wempty-body -Wnested-externs -Wformat-security -Wformat-y2k -Winit-self -Wignored-qualifiers -Wold-style-declaration -Wold-style-definition -Wtype-limits -fstack-protector-all-I/usr/include/libpng12 -I/usr/include/pixman-1 LDFLAGS -Wl,--warn-common -Wl,-z,relro -Wl,-z,now -pie -m64 -g ... Maybe its gcc's limitation, but why this redefinition need? After i remove one, it compiles successfully;) OK, thanks. I'll clean them up. Dave Thanks, zhanghailiang #endif /* QEMU_TYPEDEFS_H */ diff --git a/migration.c b/migration.c index cfdaa52..63d7699 100644 --- a/migration.c +++ b/migration.c @@ -26,6 +26,8 @@ #include qemu/thread.h #include qmp-commands.h #include trace.h +#include exec/memory.h +#include exec/address-spaces.h //#define DEBUG_MIGRATION @@ -504,6 +506,15 @@ static void migrate_fd_cleanup(void *opaque) migrate_fd_cleanup_src_rp(s); +/* This queue generally should be empty - but in the case of a failed + * migration might have some droppings in. + */ +struct MigrationSrcPageRequest *mspr, *next_mspr; +QSIMPLEQ_FOREACH_SAFE(mspr, s-src_page_requests, next_req, next_mspr) { +QSIMPLEQ_REMOVE_HEAD(s-src_page_requests, next_req); +g_free(mspr); +} + if (s-file) { trace_migrate_fd_cleanup(); qemu_mutex_unlock_iothread(); @@ -610,6 +621,9 @@ MigrationState *migrate_init(const MigrationParams *params) s-state = MIG_STATE_SETUP; trace_migrate_set_state(MIG_STATE_SETUP); +qemu_mutex_init(s-src_page_req_mutex); +QSIMPLEQ_INIT(s-src_page_requests); + s-total_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME); return s; } @@ -823,7 +837,25 @@ static void source_return_path_bad(MigrationState *s) static void migrate_handle_rp_reqpages(MigrationState *ms, const char* rbname, ram_addr_t start, ram_addr_t len) { -DPRINTF(migrate_handle_rp_reqpages: at %zx for len %zx, start, len); +DPRINTF(migrate_handle_rp_reqpages: in %s start %zx len %zx, +rbname, start, len); + +/* Round everything up to our host page size */ +long our_host_ps = sysconf(_SC_PAGESIZE); +if (start (our_host_ps-1)) { +long roundings = start (our_host_ps-1); +start -= roundings; +len += roundings; +} +if (len (our_host_ps-1)) { +long roundings = len (our_host_ps-1); +len -= roundings; +len += our_host_ps; +} + +if (ram_save_queue_pages(ms, rbname, start, len)) { +source_return_path_bad(ms); +} } /* -- Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK . -- Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK
Re: [Qemu-devel] [PATCH v5 1/2] QEMUSizedBuffer based QEMUFile
* zhanghailiang (zhang.zhanghaili...@huawei.com) wrote: On 2014/9/29 17:41, Dr. David Alan Gilbert (git) wrote: +static ssize_t qsb_grow(QEMUSizedBuffer *qsb, size_t new_size) +{ +size_t needed_chunks, i; + +if (qsb-size new_size) { +struct iovec *new_iov; +size_t size_diff = new_size - qsb-size; +size_t chunk_size = (size_diff QSB_MAX_CHUNK_SIZE) + ? QSB_MAX_CHUNK_SIZE : QSB_CHUNK_SIZE; + +needed_chunks = DIV_ROUND_UP(size_diff, chunk_size); + +new_iov = g_try_malloc_n(qsb-n_iov + needed_chunks, + sizeof(struct iovec)); It seems that *g_try_malloc_n* was supported since glib2-2.24 version, But it don't check this when do *configure* before compile...;) OK, that's a shame - it was a nice easy function to use :-) I'll fix it. Dave -- Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK
Re: [Qemu-devel] [QA-virtio]:Why vring size is limited to 1024?
On 2014/10/8 15:43, Avi Kivity wrote: You could separate maximum request scatter/gather list size from the virtqueue size. They are totally unrelated - even now you can have a larger request by using indirect descriptors. Yes, there is no strong correlation between virtqueue size and iov form the code. -- Best Wishes! Zhang Jie
Re: [Qemu-devel] [PATCH v5 1/2] QEMUSizedBuffer based QEMUFile
Dr. David Alan Gilbert dgilb...@redhat.com writes: * zhanghailiang (zhang.zhanghaili...@huawei.com) wrote: On 2014/9/29 17:41, Dr. David Alan Gilbert (git) wrote: +static ssize_t qsb_grow(QEMUSizedBuffer *qsb, size_t new_size) +{ +size_t needed_chunks, i; + +if (qsb-size new_size) { +struct iovec *new_iov; +size_t size_diff = new_size - qsb-size; +size_t chunk_size = (size_diff QSB_MAX_CHUNK_SIZE) + ? QSB_MAX_CHUNK_SIZE : QSB_CHUNK_SIZE; + +needed_chunks = DIV_ROUND_UP(size_diff, chunk_size); + +new_iov = g_try_malloc_n(qsb-n_iov + needed_chunks, + sizeof(struct iovec)); It seems that *g_try_malloc_n* was supported since glib2-2.24 version, But it don't check this when do *configure* before compile...;) OK, that's a shame - it was a nice easy function to use :-) I'll fix it. See also commit 02c4f26.
Re: [Qemu-devel] [PATCH v4 00/47] Postcopy implementation
On 07 Oct 2014, at 17:12 , Dr. David Alan Gilbert dgilb...@redhat.com wrote: * Cristian Klein (cristian.kl...@cs.umu.se) wrote: On 04 Oct 2014, at 4:21 , Dr. David Alan Gilbert dgilb...@redhat.com wrote: I've updated our github at: https://github.com/orbitfp7/qemu/tree/wp3-postcopy to have this version. and it corresponds to the tag: https://github.com/orbitfp7/qemu/releases/tag/wp3-postcopy-v4 Hi Dave, I just tested this version of post-copy using the libvirt patches I recently posted and it works a lot better. The video streaming VM migrates with a downtime of less than 1 second. Before post-copy finishes, the VM is a bit slow but otherwise running well. I also tested the patches with a VM doing ?ping? and the downtime was around 0.6 seconds. I suspect that this delay could be caused by libvirt and not by qemu. Notice that, libvirt is a bit special, in the sense that the VM is migrated in suspended state and resumed only after the network was set up on the destination. I will investigate and let you know. That's great news - although I'm not quite sure what caused the improvement, there were quite a few minor bug fixes and things but nothing that I can think of that would directly contribute (except the patches I'd sent you which you'd already tried). Unfortunately, I made an error in my experiments (post-copy started too late). I re-launched the experiments a few times. A ping VM observes a downtime of about 2 seconds, whereas a video streaming VM of about 4 seconds. Cristian * Dr. David Alan Gilbert (git) (dgilb...@redhat.com) wrote: From: Dr. David Alan Gilbert dgilb...@redhat.com Hi, This is the 4th cut of my version of postcopy; it is designed for use with the Linux kernel additions just posted by Andrea Arcangeli here: http://marc.info/?l=linux-kernelm=141235633015100w=2 (Note: This is a new version compared to my previous postcopy patchset; you'll need to update the kernel to the new version.) Other than the new kernel ABI (which is only a small change to the userspace side); the major changes are; a) Code for host page size != target page size b) Support for migration over fd From Cristian Klein; this is for libvirt support which Cristian recently posted to the libvirt list. c) It's now build bisectable and builds on 32bit Testing wise; I've now done many thousand of postcopy migrations without failure (both of idle and busy guests); so it seems pretty solid. Must-TODO's: 1) A partially repeatable migration_cancel failure 2) virt_test's migrate.with_reboot test is failing 3) The ACPI fix in 2.1 that allowed migrating RAMBlocks to be larger than the source feels like it needs looking at for postcopy. 4) Paolo's comments with respect to the wakeup_request/is_running code in the migration thread 5) xbzrle needs disabling once in postcopy Later-TODO's: 1) Control the rate of background page transfers during postcopy to reduce their impact on the latency of postcopy requests. 2) Work with RDMA 3) Could destination RP be made blocking (as per discussion with Paolo; I'm still worried that that changes too many assumptions) V4: Initial support for host page size != target page size - tested heavily on hps==tps - only partially tested on hps!=tps systems - This involved quite a bit of rework around the discard code Updated to new kernel userfault ABI - It won't work with the previous version Fix mis-optimisation of postcopy request for wrong RAMBlock request for block A offset n un-needed fault for block B/m (already received - no req sent) request for block B/l - wrongly sent as request for A/l Fix thinko in discard bitmap processing (missed last word of bitmap) Symptom: remap failures near the top of RAM if postcopy started late Fix bug that caused kernel page acknowledgments to be misaligned May have meant the guest was paused for longer than required Fix potential for crashing cleaning up failed RP Fixes in docs (from Yang) Handle migration by fd as sockets if they are sockets Build tested on 32bit Fully build bisectable (x86-64) Dave Cristian Klein (1): Handle bi-directional communication for fd migration Dr. David Alan Gilbert (46): QEMUSizedBuffer based QEMUFile Tests: QEMUSizedBuffer/QEMUBuffer Start documenting how postcopy works. qemu_ram_foreach_block: pass up error value, and down the ramblock name improve DPRINTF macros, add to savevm Add qemu_get_counted_string to read a string prefixed by a count byte Create MigrationIncomingState socket shutdown Provide runtime Target page information Return path: Open a return path on QEMUFile for sockets Return path: socket_writev_buffer: Block even on non-blocking fd's Migration commands Return path: Control commands Return path: Send responses from destination to source Return path: Source handling of return path qemu_loadvm errors and debug
Re: [Qemu-devel] [PATCH v3] pc-dimm/numa: Fix stat of memory size in node when hotplug memory
On 2014/10/8 15:28, zhanghailiang wrote: Hi Igor, On 2014/9/26 19:53, Igor Mammedov wrote: On Tue, 23 Sep 2014 16:11:25 +0800 zhanghailiang zhang.zhanghaili...@huawei.com wrote: When do memory hotplug, if there is numa node, we should add the memory size to the corresponding node memory size. For now, it mainly affects the result of hmp command info numa. Signed-off-by: zhanghailiang zhang.zhanghaili...@huawei.com please make sure that this doesn't breaks other targets. PS: to make test builds you can use travis-ci.org+github service Sorry for the delayed response.;) I have test the build as you suggested, and yes, it will break other targets. The main reason here is, there is a compile switch for memory hotplug (CONFIG_MEM_HOTPLUG), which is off for other targets, and pc-dimm.c is not include when compile. Here i also use the compile switch to fix this problem, and will send V4. ): Actually this macro (CONFIG_MEM_HOTPLUG) can't be automatically generated like CONFIG_KVM in config-target.h, so i can't use this compile macro. What's your suggestion? Thanks! zhanghailiang --- v3: - cold-plugged memory should not be excluded when stat memory size (Igor Mammedov) v2: - Don't modify the numa_info.node_mem directly when treating hotplug memory, fix the info numa instead (suggested by Igor Mammedov) --- hw/mem/pc-dimm.c | 30 ++ include/hw/mem/pc-dimm.h | 2 ++ include/sysemu/sysemu.h | 1 + monitor.c| 6 +- numa.c | 15 +++ 5 files changed, 53 insertions(+), 1 deletion(-) diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c index 5bfc5b7..8e80d74 100644 --- a/hw/mem/pc-dimm.c +++ b/hw/mem/pc-dimm.c @@ -195,6 +195,36 @@ out: return ret; } +static int pc_dimm_stat_mem_size(Object *obj, void *opaque) +{ +uint64_t *node_mem = opaque; +int ret; + +if (object_dynamic_cast(obj, TYPE_PC_DIMM)) { +DeviceState *dev = DEVICE(obj); + +if (dev-realized) { +PCDIMMDevice *dimm = PC_DIMM(obj); +int size; + +size = object_property_get_int(OBJECT(dimm), PC_DIMM_SIZE_PROP, + NULL); +if (size 0) { +return -1; +} +node_mem[dimm-node] += size; +} +} + +ret = object_child_foreach(obj, pc_dimm_stat_mem_size, opaque); +return ret; +} + +void pc_dimm_stat_node_mem(uint64_t *node_mem) +{ +object_child_foreach(qdev_get_machine(), pc_dimm_stat_mem_size, node_mem); +} + static Property pc_dimm_properties[] = { DEFINE_PROP_UINT64(PC_DIMM_ADDR_PROP, PCDIMMDevice, addr, 0), DEFINE_PROP_UINT32(PC_DIMM_NODE_PROP, PCDIMMDevice, node, 0), diff --git a/include/hw/mem/pc-dimm.h b/include/hw/mem/pc-dimm.h index 761eeef..0c9a8eb 100644 --- a/include/hw/mem/pc-dimm.h +++ b/include/hw/mem/pc-dimm.h @@ -78,4 +78,6 @@ uint64_t pc_dimm_get_free_addr(uint64_t address_space_start, int pc_dimm_get_free_slot(const int *hint, int max_slots, Error **errp); int qmp_pc_dimm_device_list(Object *obj, void *opaque); + +void pc_dimm_stat_node_mem(uint64_t *node_mem); #endif diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h index d8539fd..cfc1592 100644 --- a/include/sysemu/sysemu.h +++ b/include/sysemu/sysemu.h @@ -160,6 +160,7 @@ typedef struct node_info { extern NodeInfo numa_info[MAX_NODES]; void set_numa_nodes(void); void set_numa_modes(void); +int query_numa_node_mem(uint64_t *node_mem); extern QemuOptsList qemu_numa_opts; int numa_init_func(QemuOpts *opts, void *opaque); diff --git a/monitor.c b/monitor.c index 7467521..c8c812f 100644 --- a/monitor.c +++ b/monitor.c @@ -1948,7 +1948,10 @@ static void do_info_numa(Monitor *mon, const QDict *qdict) { int i; CPUState *cpu; +uint64_t *node_mem; +node_mem = g_new0(uint64_t, nb_numa_nodes); +query_numa_node_mem(node_mem); monitor_printf(mon, %d nodes\n, nb_numa_nodes); for (i = 0; i nb_numa_nodes; i++) { monitor_printf(mon, node %d cpus:, i); @@ -1959,8 +1962,9 @@ static void do_info_numa(Monitor *mon, const QDict *qdict) } monitor_printf(mon, \n); monitor_printf(mon, node %d size: % PRId64 MB\n, i, -numa_info[i].node_mem 20); +node_mem[i] 20); } +g_free(node_mem); } #ifdef CONFIG_PROFILER diff --git a/numa.c b/numa.c index 3b98135..4e27dd8 100644 --- a/numa.c +++ b/numa.c @@ -35,6 +35,7 @@ #include hw/boards.h #include sysemu/hostmem.h #include qmp-commands.h +#include hw/mem/pc-dimm.h QemuOptsList qemu_numa_opts = { .name = numa, @@ -315,6 +316,20 @@ void memory_region_allocate_system_memory(MemoryRegion *mr, Object *owner, } } +int query_numa_node_mem(uint64_t *node_mem) +{ +int i; + +if (nb_numa_nodes = 0) { +return 0; +} +pc_dimm_stat_node_mem(node_mem); +for (i = 0; i nb_numa_nodes;
Re: [Qemu-devel] [PATCH RFC 00/11] qemu: towards virtio-1 host support
On Tue, 07 Oct 2014 18:24:22 -0700 Andy Lutomirski l...@amacapital.net wrote: On 10/07/2014 07:39 AM, Cornelia Huck wrote: This patchset aims to get us some way to implement virtio-1 compliant and transitional devices in qemu. Branch available at git://github.com/cohuck/qemu virtio-1 I've mainly focused on: - endianness handling - extended feature bits - virtio-ccw new/changed commands At the risk of some distraction, would it be worth thinking about a solution to the IOMMU bypassing mess as part of this? I think that is a whole different issue. virtio-1 is basically done - we just need to implement it - while the IOMMU/DMA stuff certainly needs more discussion. Therefore, I'd like to defer to the other discussion thread here.
Re: [Qemu-devel] [PATCH v5 1/2] QEMUSizedBuffer based QEMUFile
* zhanghailiang (zhang.zhanghaili...@huawei.com) wrote: +static ssize_t qsb_grow(QEMUSizedBuffer *qsb, size_t new_size) +{ +size_t needed_chunks, i; + +if (qsb-size new_size) { +struct iovec *new_iov; +size_t size_diff = new_size - qsb-size; +size_t chunk_size = (size_diff QSB_MAX_CHUNK_SIZE) + ? QSB_MAX_CHUNK_SIZE : QSB_CHUNK_SIZE; + +needed_chunks = DIV_ROUND_UP(size_diff, chunk_size); + +new_iov = g_try_malloc_n(qsb-n_iov + needed_chunks, + sizeof(struct iovec)); It seems that *g_try_malloc_n* was supported since glib2-2.24 version, But it don't check this when do *configure* before compile...;) new_iov = g_try_new(struct iovec, qsb-n_iov + needed_chunks); seems to work for me; let me know if you hit any others. Dave +if (new_iov == NULL) { +return -ENOMEM; +} + +/* Allocate new chunks as needed into new_iov */ +for (i = qsb-n_iov; i qsb-n_iov + needed_chunks; i++) { +new_iov[i].iov_base = g_try_malloc0(chunk_size); +new_iov[i].iov_len = chunk_size; +if (!new_iov[i].iov_base) { +size_t j; + +/* Free previously allocated new chunks */ +for (j = qsb-n_iov; j i; j++) { +g_free(new_iov[j].iov_base); +} +g_free(new_iov); + +return -ENOMEM; +} +} + +/* + * Now we can't get any allocation errors, copy over to new iov + * and switch. + */ +for (i = 0; i qsb-n_iov; i++) { +new_iov[i] = qsb-iov[i]; +} + +qsb-n_iov += needed_chunks; +g_free(qsb-iov); +qsb-iov = new_iov; +qsb-size += (needed_chunks * chunk_size); +} + +return qsb-size; +} + +/** + * Write into the QEMUSizedBuffer at a given position and a given + * number of bytes. This function will automatically grow the + * QEMUSizedBuffer. + * + * @qsb: A QEMUSizedBuffer + * @source: A byte array to copy data from + * @pos: The position within the @qsb to write data to + * @size: The number of bytes to copy into the @qsb + * + * Returns @size or a negative error code in case of memory allocation failure, + * or with an invalid 'pos' + */ +ssize_t qsb_write_at(QEMUSizedBuffer *qsb, const uint8_t *source, + off_t pos, size_t count) +{ +ssize_t rc = qsb_grow(qsb, pos + count); +size_t to_copy; +size_t all_copy = count; +const struct iovec *iov; +ssize_t index; +char *dest; +off_t d_off, s_off = 0; + +if (rc 0) { +return rc; +} + +if (pos + count qsb-used) { +qsb-used = pos + count; +} + +index = qsb_get_iovec(qsb, pos, d_off); +if (index 0) { +return -EINVAL; +} + +while (all_copy 0) { +iov = qsb-iov[index]; + +dest = iov-iov_base; + +to_copy = iov-iov_len - d_off; +if (to_copy all_copy) { +to_copy = all_copy; +} + +memcpy(dest[d_off], source[s_off], to_copy); + +s_off += to_copy; +all_copy -= to_copy; + +d_off = 0; +index++; +} + +return count; +} + +/** + * Create a deep copy of the given QEMUSizedBuffer. + * + * @qsb: A QEMUSizedBuffer + * + * Returns a clone of @qsb or NULL on allocation failure + */ +QEMUSizedBuffer *qsb_clone(const QEMUSizedBuffer *qsb) +{ +QEMUSizedBuffer *out = qsb_create(NULL, qsb_get_length(qsb)); +size_t i; +ssize_t res; +off_t pos = 0; + +if (!out) { +return NULL; +} + +for (i = 0; i qsb-n_iov; i++) { +res = qsb_write_at(out, qsb-iov[i].iov_base, +pos, qsb-iov[i].iov_len); +if (res 0) { +qsb_free(out); +return NULL; +} +pos += res; +} + +return out; +} + +typedef struct QEMUBuffer { +QEMUSizedBuffer *qsb; +QEMUFile *file; +} QEMUBuffer; + +static int buf_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size) +{ +QEMUBuffer *s = opaque; +ssize_t len = qsb_get_length(s-qsb) - pos; + +if (len = 0) { +return 0; +} + +if (len size) { +len = size; +} +return qsb_get_buffer(s-qsb, pos, len, buf); +} + +static int buf_put_buffer(void *opaque, const uint8_t *buf, + int64_t pos, int size) +{ +QEMUBuffer *s = opaque; + +return qsb_write_at(s-qsb, buf, pos, size); +} + +static int buf_close(void *opaque) +{ +QEMUBuffer *s = opaque; + +qsb_free(s-qsb); + +g_free(s); + +return 0; +} + +const QEMUSizedBuffer *qemu_buf_get(QEMUFile *f) +{ +QEMUBuffer *p; + +
Re: [Qemu-devel] [QA-virtio]:Why vring size is limited to 1024?
On Wed, Oct 08, 2014 at 04:07:47PM +0800, Zhangjie (HZ) wrote: MST, Thanks very much, I get it. On 2014/10/8 15:37, Michael S. Tsirkin wrote: On Wed, Oct 08, 2014 at 03:17:56PM +0800, Zhangjie (HZ) wrote: Thanks for your patient answer! :-) On 2014/9/30 17:33, Michael S. Tsirkin wrote: On Tue, Sep 30, 2014 at 04:36:00PM +0800, Zhangjie (HZ) wrote: Hi, There exits packets loss when we do packet forwarding in VM, especially when we use dpdk to do the forwarding. By enlarging vring can alleviate the problem. I think this has to do with the fact that dpdk disables checksum offloading, this has the side effect of disabling segmentation offloading. Please fix dpdk to support checksum offloading, and I think the problem will go away. In some application scene, loss of udp packets are not allowed, and udp packets are always short than mtu. So, we need to support high pps(eg.0.3M Packets/s) forwarding, and offloading cannot fix it. That's the point. With UFO you get larger than MTU UDP packets: http://www.linuxfoundation.org/collaborate/workgroups/networking/ufo Then vm only do forwarding, and not create new packets itself. As we can not gro normal udp packets, when udp packets come from the nic of host, ufo cannot work. This is something I've been thinking about for a while now. We really should add GRO-like path for UDP, this isn't too different from UDP. LRO can often work with UDP too, but linux discards too much info on LRO, but if you are doing drivers in userspace you might be able to support this. Additionally, checksum offloading reduces CPU utilization and reduces the number of data copies, allowing higher pps with smaller buffers. It might look like queue depth helps performance for netperf, but in real-life workloads the latency under load will suffer, with more protocols implementing tunnelling on top of UDP such extreme bufferbloat will not be tolerated. But now vring size is limited to 1024 as follows: VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size, void (*handle_output)(VirtIODevice *, VirtQueue *)) { ... if (i == VIRTIO_PCI_QUEUE_MAX || queue_size VIRTQUEUE_MAX_SIZE) abort(); } ps:#define VIRTQUEUE_MAX_SIZE 1024 I delete the judgement code, and set vring size to 2048, VM can be successfully started, and the network is ok too. So, Why vring size is limited to 1024 and what is the influence? Thanks! There are several reason for this limit. First guest has to allocate descriptor buffer which is 16 * vring size. With 1K size that is already 16K which might be tricky to allocate contigiously if memory is fragmented when device is added by hotplug. That is very The second issue is that we want to be able to implement the device on top of linux kernel, and a single descriptor might use all of the virtqueue. In this case we wont to be able to pass the descriptor directly to linux as a single iov, since that is limited to 1K entries. For the second issue, I wonder if it is ok to set vring size of virtio-net to large than 1024, as for net work, there is at most 18 pages for a skb, it will not exceed iov. -- Best Wishes! Zhang Jie . -- Best Wishes! Zhang Jie . -- Best Wishes! Zhang Jie
Re: [Qemu-devel] [QA-virtio]:Why vring size is limited to 1024?
On Wed, Oct 08, 2014 at 10:43:07AM +0300, Avi Kivity wrote: On 09/30/2014 12:33 PM, Michael S. Tsirkin wrote: a single descriptor might use all of the virtqueue. In this case we wont to be able to pass the descriptor directly to linux as a single iov, since You could separate maximum request scatter/gather list size from the virtqueue size. They are totally unrelated - even now you can have a larger request by using indirect descriptors. We could add a feature to have a smaller or larger S/G length limit. Is this something useful? -- MST
[Qemu-devel] [PATCH 3/3] block/parallels: fix access to not initialized memory in catalog_bitmap
found by valgrind. Command: ./qemu-img convert -f parallels -O qcow2 1.hds 1.img Invalid read of size 4 at 0x17D0EF: parallels_co_read (parallels.c:357) by 0x11FEE4: bdrv_aio_rw_vector (block.c:4640) by 0x11FFBF: bdrv_aio_readv_em (block.c:4652) by 0x11F55F: bdrv_co_readv_em (block.c:4862) by 0x123428: bdrv_aligned_preadv (block.c:3056) by 0x1239FA: bdrv_co_do_preadv (block.c:3162) by 0x125424: bdrv_rw_co_entry (block.c:2706) by 0x155DD9: coroutine_trampoline (coroutine-ucontext.c:118) by 0x6975B6F: ??? (in /lib/x86_64-linux-gnu/libc-2.19.so) The problem is that s-catalog_bitmap is allocated/filled as gmalloc(s-catalog_size) thus index validity check must be inclusive, i.e. index = s-catalog_size is invalid. Signed-off-by: Denis V. Lunev d...@openvz.org CC: Jeff Cody jc...@redhat.com CC: Kevin Wolf kw...@redhat.com CC: Stefan Hajnoczi stefa...@redhat.com --- block/parallels.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block/parallels.c b/block/parallels.c index 2a814f3..4f9cd8d 100644 --- a/block/parallels.c +++ b/block/parallels.c @@ -155,7 +155,7 @@ static int64_t seek_to_sector(BlockDriverState *bs, int64_t sector_num) offset = sector_num % s-tracks; /* not allocated */ -if ((index s-catalog_size) || (s-catalog_bitmap[index] == 0)) +if ((index = s-catalog_size) || (s-catalog_bitmap[index] == 0)) return -1; return ((uint64_t)s-catalog_bitmap[index] * s-off_multiplier + offset) * 512; -- 1.9.1
[Qemu-devel] [PATCH 0/3] parallels: additional iotests and a minor bugfix
Pls find here test authentic test material, i.e. parallels images with WithoutFreeSpace and WithouFreSpacExt signatures created in authentic way + a minor bug fix for access to non-initialized memory found by valgrind. Signed-off-by: Denis V. Lunev d...@openvz.org CC: Jeff Cody jc...@redhat.com CC: Kevin Wolf kw...@redhat.com CC: Stefan Hajnoczi stefa...@redhat.com
[Qemu-devel] [PATCH 2/3] iotests: add v2 parallels sample image and simple test for it
This is simple test image for the following commit made by me. commit d25d59802021a747812472780d80a0e792078f40 Author: Denis V. Lunev d...@openvz.org Date: Mon Jul 28 20:23:55 2014 +0400 parallels: 2TB+ parallels images support Signed-off-by: Denis V. Lunev d...@openvz.org CC: Jeff Cody jc...@redhat.com CC: Kevin Wolf kw...@redhat.com CC: Stefan Hajnoczi stefa...@redhat.com --- tests/qemu-iotests/076| 5 + tests/qemu-iotests/076.out| 4 tests/qemu-iotests/sample_images/parallels-v2.bz2 | Bin 0 - 150 bytes 3 files changed, 9 insertions(+) create mode 100644 tests/qemu-iotests/sample_images/parallels-v2.bz2 diff --git a/tests/qemu-iotests/076 b/tests/qemu-iotests/076 index a300ee2..98d67b3 100755 --- a/tests/qemu-iotests/076 +++ b/tests/qemu-iotests/076 @@ -70,6 +70,11 @@ _use_sample_img parallels-v1.bz2 poke_file $TEST_IMG $tracks_offset \x00\x00\x00\x00 { $QEMU_IO -c read 0 512 $TEST_IMG; } 21 | _filter_qemu_io | _filter_testdir +echo +echo == Read from a valid v2 image == +_use_sample_img parallels-v2.bz2 +{ $QEMU_IO -c read -P 0x11 0 64k $TEST_IMG; } 21 | _filter_qemu_io | _filter_testdir + # success, all done echo *** done rm -f $seq.full diff --git a/tests/qemu-iotests/076.out b/tests/qemu-iotests/076.out index fd26f3c..32ade08 100644 --- a/tests/qemu-iotests/076.out +++ b/tests/qemu-iotests/076.out @@ -15,4 +15,8 @@ no file open, try 'help open' == Zero sectors per track == qemu-io: can't open device TEST_DIR/parallels-v1: Invalid image: Zero sectors per track no file open, try 'help open' + +== Read from a valid v2 image == +read 65536/65536 bytes at offset 0 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) *** done diff --git a/tests/qemu-iotests/sample_images/parallels-v2.bz2 b/tests/qemu-iotests/sample_images/parallels-v2.bz2 new file mode 100644 index ..fd8614d061172faae50a993ac7acd3173de9aa98 GIT binary patch literal 150 zcmV;H0BQe1T4*^jL0KkKS`z1ga8U8f6)C%U;t162ml8F2!JYJ)8f2004jpFaWp= zU;vl^35GBLOaKJHsVaJ=X*QsGnW)758mCWPt$+@EvggMtTP~K8Aeq(bOlAS_fGVI1 zR{#%`0aSoc2hsqlKqv!50aXBg@8a8e-{1Q8zBk4(ssXG4tO2Y6qyhdece^iA*S{R E2o5o3;+NC literal 0 HcmV?d1 -- 1.9.1
[Qemu-devel] [PATCH 1/3] iotests: replace fake parallels image with authentic one
The image was generated using http://openvz.org/Ploop utility and properly filled with the same content as original one. Signed-off-by: Denis V. Lunev d...@openvz.org CC: Jeff Cody jc...@redhat.com CC: Kevin Wolf kw...@redhat.com CC: Stefan Hajnoczi stefa...@redhat.com --- tests/qemu-iotests/076 | 10 +- tests/qemu-iotests/076.out | 8 tests/qemu-iotests/sample_images/fake.parallels.bz2 | Bin 141 - 0 bytes tests/qemu-iotests/sample_images/parallels-v1.bz2 | Bin 0 - 147 bytes 4 files changed, 9 insertions(+), 9 deletions(-) delete mode 100644 tests/qemu-iotests/sample_images/fake.parallels.bz2 create mode 100644 tests/qemu-iotests/sample_images/parallels-v1.bz2 diff --git a/tests/qemu-iotests/076 b/tests/qemu-iotests/076 index b614a7d..a300ee2 100755 --- a/tests/qemu-iotests/076 +++ b/tests/qemu-iotests/076 @@ -47,26 +47,26 @@ catalog_entries_offset=$((0x20)) nb_sectors_offset=$((0x24)) echo -echo == Read from a valid (enough) image == -_use_sample_img fake.parallels.bz2 +echo == Read from a valid v1 image == +_use_sample_img parallels-v1.bz2 { $QEMU_IO -c read -P 0x11 0 64k $TEST_IMG; } 21 | _filter_qemu_io | _filter_testdir echo echo == Negative catalog size == -_use_sample_img fake.parallels.bz2 +_use_sample_img parallels-v1.bz2 poke_file $TEST_IMG $catalog_entries_offset \xff\xff\xff\xff { $QEMU_IO -c read 0 512 $TEST_IMG; } 21 | _filter_qemu_io | _filter_testdir echo echo == Overflow in catalog allocation == -_use_sample_img fake.parallels.bz2 +_use_sample_img parallels-v1.bz2 poke_file $TEST_IMG $nb_sectors_offset \xff\xff\xff\xff poke_file $TEST_IMG $catalog_entries_offset \x01\x00\x00\x40 { $QEMU_IO -c read 64M 64M $TEST_IMG; } 21 | _filter_qemu_io | _filter_testdir echo echo == Zero sectors per track == -_use_sample_img fake.parallels.bz2 +_use_sample_img parallels-v1.bz2 poke_file $TEST_IMG $tracks_offset \x00\x00\x00\x00 { $QEMU_IO -c read 0 512 $TEST_IMG; } 21 | _filter_qemu_io | _filter_testdir diff --git a/tests/qemu-iotests/076.out b/tests/qemu-iotests/076.out index f7745d8..fd26f3c 100644 --- a/tests/qemu-iotests/076.out +++ b/tests/qemu-iotests/076.out @@ -1,18 +1,18 @@ QA output created by 076 -== Read from a valid (enough) image == +== Read from a valid v1 image == read 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) == Negative catalog size == -qemu-io: can't open device TEST_DIR/fake.parallels: Catalog too large +qemu-io: can't open device TEST_DIR/parallels-v1: Catalog too large no file open, try 'help open' == Overflow in catalog allocation == -qemu-io: can't open device TEST_DIR/fake.parallels: Catalog too large +qemu-io: can't open device TEST_DIR/parallels-v1: Catalog too large no file open, try 'help open' == Zero sectors per track == -qemu-io: can't open device TEST_DIR/fake.parallels: Invalid image: Zero sectors per track +qemu-io: can't open device TEST_DIR/parallels-v1: Invalid image: Zero sectors per track no file open, try 'help open' *** done diff --git a/tests/qemu-iotests/sample_images/fake.parallels.bz2 b/tests/qemu-iotests/sample_images/fake.parallels.bz2 deleted file mode 100644 index ffb5f13bac31bc9ab6e1ea5c0cfa26786f2c4cc6.. GIT binary patch literal 0 HcmV?d1 literal 141 zcmV;80CN9AT4*^jL0KkKS*iLJ^%_Hf6(xNVE_;S2ml2D2!JYJ)M{N00969FaWp; z000b`1pojBOn|7QnnOSv)YEF7cgIVO0ByGSdk7e?fW`f$x`2Bi3t$bd06owJs09G{ vKo+1B1LXi)0CVe)J@eC^zBuEJbFFJA24D=p8Gt*$AL8yvrwS4kK_LggA5|C diff --git a/tests/qemu-iotests/sample_images/parallels-v1.bz2 b/tests/qemu-iotests/sample_images/parallels-v1.bz2 new file mode 100644 index ..d1ef14205401a8e010d1be68bffeee92ce137d39 GIT binary patch literal 147 zcmZY%CIzaj8qGbU2HxlYvY5|Amhp2@C-Y91N@s91U6t*BBfa7#JBi3bEBnV0~X zZfy+=3|x~mCkJ!L1skp^{Ftks!;qfyS}R^xuR}6WLEksaZ~=P@V!18pfv#p$a05 xpBl6#a54OH5Dj3ritc|OYkB_O@ArL$J-G_f4j?FXKpD?kL6rKj5mT56#x^qEyDl+ literal 0 HcmV?d1 -- 1.9.1
Re: [Qemu-devel] [Bug 1378554] [NEW] qemu segfault in virtio_scsi_handle_cmd_req_submit on ARM 32 bit
On Wed, Oct 08, 2014 at 01:18:04AM +0200, Paolo Bonzini wrote: Does this work: diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index 203e624..c6d4f2e 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -545,11 +545,12 @@ bool virtio_scsi_handle_cmd_req_prepare(VirtIOSCSI *s, VirtIOSCSIReq *req) void virtio_scsi_handle_cmd_req_submit(VirtIOSCSI *s, VirtIOSCSIReq *req) { -if (scsi_req_enqueue(req-sreq)) { -scsi_req_continue(req-sreq); +SCSIRequest *sreq = req-sreq; +bdrv_io_unplug(sreq-dev-conf.bs); +if (scsi_req_enqueue(sreq)) { +scsi_req_continue(sreq); } -bdrv_io_unplug(req-sreq-dev-conf.bs); -scsi_req_unref(req-sreq); +scsi_req_unref(sreq); } static void virtio_scsi_handle_cmd(VirtIODevice *vdev, VirtQueue *vq) ? Yes, that fixes it. Tested-by: Richard W.M. Jones rjo...@redhat.com Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com Fedora Windows cross-compiler. Compile Windows programs, test, and build Windows installers. Over 100 libraries supported. http://fedoraproject.org/wiki/MinGW
Re: [Qemu-devel] [PATCH v5 1/2] QEMUSizedBuffer based QEMUFile
On 2014/10/8 17:08, Dr. David Alan Gilbert wrote: * zhanghailiang (zhang.zhanghaili...@huawei.com) wrote: +static ssize_t qsb_grow(QEMUSizedBuffer *qsb, size_t new_size) +{ +size_t needed_chunks, i; + +if (qsb-size new_size) { +struct iovec *new_iov; +size_t size_diff = new_size - qsb-size; +size_t chunk_size = (size_diff QSB_MAX_CHUNK_SIZE) + ? QSB_MAX_CHUNK_SIZE : QSB_CHUNK_SIZE; + +needed_chunks = DIV_ROUND_UP(size_diff, chunk_size); + +new_iov = g_try_malloc_n(qsb-n_iov + needed_chunks, + sizeof(struct iovec)); It seems that *g_try_malloc_n* was supported since glib2-2.24 version, But it don't check this when do *configure* before compile...;) new_iov = g_try_new(struct iovec, qsb-n_iov + needed_chunks); seems to work for me; let me know if you hit any others. ;), This also works for me. Thanks. Dave +if (new_iov == NULL) { +return -ENOMEM; +} + +/* Allocate new chunks as needed into new_iov */ +for (i = qsb-n_iov; i qsb-n_iov + needed_chunks; i++) { +new_iov[i].iov_base = g_try_malloc0(chunk_size); +new_iov[i].iov_len = chunk_size; +if (!new_iov[i].iov_base) { +size_t j; + +/* Free previously allocated new chunks */ +for (j = qsb-n_iov; j i; j++) { +g_free(new_iov[j].iov_base); +} +g_free(new_iov); + +return -ENOMEM; +} +} + +/* + * Now we can't get any allocation errors, copy over to new iov + * and switch. + */ +for (i = 0; i qsb-n_iov; i++) { +new_iov[i] = qsb-iov[i]; +} + +qsb-n_iov += needed_chunks; +g_free(qsb-iov); +qsb-iov = new_iov; +qsb-size += (needed_chunks * chunk_size); +} + +return qsb-size; +} + +/** + * Write into the QEMUSizedBuffer at a given position and a given + * number of bytes. This function will automatically grow the + * QEMUSizedBuffer. + * + * @qsb: A QEMUSizedBuffer + * @source: A byte array to copy data from + * @pos: The position within the @qsb to write data to + * @size: The number of bytes to copy into the @qsb + * + * Returns @size or a negative error code in case of memory allocation failure, + * or with an invalid 'pos' + */ +ssize_t qsb_write_at(QEMUSizedBuffer *qsb, const uint8_t *source, + off_t pos, size_t count) +{ +ssize_t rc = qsb_grow(qsb, pos + count); +size_t to_copy; +size_t all_copy = count; +const struct iovec *iov; +ssize_t index; +char *dest; +off_t d_off, s_off = 0; + +if (rc 0) { +return rc; +} + +if (pos + count qsb-used) { +qsb-used = pos + count; +} + +index = qsb_get_iovec(qsb, pos, d_off); +if (index 0) { +return -EINVAL; +} + +while (all_copy 0) { +iov = qsb-iov[index]; + +dest = iov-iov_base; + +to_copy = iov-iov_len - d_off; +if (to_copy all_copy) { +to_copy = all_copy; +} + +memcpy(dest[d_off], source[s_off], to_copy); + +s_off += to_copy; +all_copy -= to_copy; + +d_off = 0; +index++; +} + +return count; +} + +/** + * Create a deep copy of the given QEMUSizedBuffer. + * + * @qsb: A QEMUSizedBuffer + * + * Returns a clone of @qsb or NULL on allocation failure + */ +QEMUSizedBuffer *qsb_clone(const QEMUSizedBuffer *qsb) +{ +QEMUSizedBuffer *out = qsb_create(NULL, qsb_get_length(qsb)); +size_t i; +ssize_t res; +off_t pos = 0; + +if (!out) { +return NULL; +} + +for (i = 0; i qsb-n_iov; i++) { +res = qsb_write_at(out, qsb-iov[i].iov_base, +pos, qsb-iov[i].iov_len); +if (res 0) { +qsb_free(out); +return NULL; +} +pos += res; +} + +return out; +} + +typedef struct QEMUBuffer { +QEMUSizedBuffer *qsb; +QEMUFile *file; +} QEMUBuffer; + +static int buf_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size) +{ +QEMUBuffer *s = opaque; +ssize_t len = qsb_get_length(s-qsb) - pos; + +if (len = 0) { +return 0; +} + +if (len size) { +len = size; +} +return qsb_get_buffer(s-qsb, pos, len, buf); +} + +static int buf_put_buffer(void *opaque, const uint8_t *buf, + int64_t pos, int size) +{ +QEMUBuffer *s = opaque; + +return qsb_write_at(s-qsb, buf, pos, size); +} + +static int buf_close(void *opaque) +{ +QEMUBuffer *s = opaque; + +qsb_free(s-qsb); + +g_free(s); + +return 0; +} + +const QEMUSizedBuffer *qemu_buf_get(QEMUFile *f) +{ +QEMUBuffer *p; + +qemu_fflush(f); + +p = f-opaque; + +return p-qsb; +} + +static const QEMUFileOps buf_read_ops =
[Qemu-devel] [PATCH] virtio-scsi: fix use-after-free of VirtIOSCSIReq
scsi_req_continue can complete the request and cause the VirtIOSCSIReq to be freed. Fetch req-sreq just once to avoid the bug. Reported-by: Richard Jones rjo...@redhat.com Tested-by: Richard Jones rjo...@redhat.com Signed-off-by: Paolo Bonzini pbonz...@redhat.com --- hw/scsi/virtio-scsi.c | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index 203e624..6c02fe2 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -545,11 +545,12 @@ bool virtio_scsi_handle_cmd_req_prepare(VirtIOSCSI *s, VirtIOSCSIReq *req) void virtio_scsi_handle_cmd_req_submit(VirtIOSCSI *s, VirtIOSCSIReq *req) { -if (scsi_req_enqueue(req-sreq)) { -scsi_req_continue(req-sreq); +SCSIRequest *sreq = req-sreq; +if (scsi_req_enqueue(sreq)) { +scsi_req_continue(sreq); } -bdrv_io_unplug(req-sreq-dev-conf.bs); -scsi_req_unref(req-sreq); +bdrv_io_unplug(sreq-dev-conf.bs); +scsi_req_unref(sreq); } static void virtio_scsi_handle_cmd(VirtIODevice *vdev, VirtQueue *vq) -- 1.8.3.1
Re: [Qemu-devel] [QA-virtio]:Why vring size is limited to 1024?
On 10/08/2014 12:15 PM, Michael S. Tsirkin wrote: On Wed, Oct 08, 2014 at 10:43:07AM +0300, Avi Kivity wrote: On 09/30/2014 12:33 PM, Michael S. Tsirkin wrote: a single descriptor might use all of the virtqueue. In this case we wont to be able to pass the descriptor directly to linux as a single iov, since You could separate maximum request scatter/gather list size from the virtqueue size. They are totally unrelated - even now you can have a larger request by using indirect descriptors. We could add a feature to have a smaller or larger S/G length limit. Is this something useful? Having a larger ring size is useful, esp. with zero-copy transmit, and you would need the sglist length limit in order to not require linearization on linux hosts. So the limit is not useful in itself, only indirectly. Google cloud engine exposes virtio ring sizes of 16384. Even more useful is getting rid of the desc array and instead passing descs inline in avail and used.
Re: [Qemu-devel] [QA-virtio]:Why vring size is limited to 1024?
On Wed, Oct 08, 2014 at 12:51:21PM +0300, Avi Kivity wrote: On 10/08/2014 12:15 PM, Michael S. Tsirkin wrote: On Wed, Oct 08, 2014 at 10:43:07AM +0300, Avi Kivity wrote: On 09/30/2014 12:33 PM, Michael S. Tsirkin wrote: a single descriptor might use all of the virtqueue. In this case we wont to be able to pass the descriptor directly to linux as a single iov, since You could separate maximum request scatter/gather list size from the virtqueue size. They are totally unrelated - even now you can have a larger request by using indirect descriptors. We could add a feature to have a smaller or larger S/G length limit. Is this something useful? Having a larger ring size is useful, esp. with zero-copy transmit, and you would need the sglist length limit in order to not require linearization on linux hosts. So the limit is not useful in itself, only indirectly. Google cloud engine exposes virtio ring sizes of 16384. OK this sounds useful, I'll queue this up for consideration. Thanks! Even more useful is getting rid of the desc array and instead passing descs inline in avail and used. You expect this to improve performance? Quite possibly but this will have to be demonstrated. -- MST
Re: [Qemu-devel] [QA-virtio]:Why vring size is limited to 1024?
On 10/08/2014 01:14 PM, Michael S. Tsirkin wrote: On Wed, Oct 08, 2014 at 12:51:21PM +0300, Avi Kivity wrote: On 10/08/2014 12:15 PM, Michael S. Tsirkin wrote: On Wed, Oct 08, 2014 at 10:43:07AM +0300, Avi Kivity wrote: On 09/30/2014 12:33 PM, Michael S. Tsirkin wrote: a single descriptor might use all of the virtqueue. In this case we wont to be able to pass the descriptor directly to linux as a single iov, since You could separate maximum request scatter/gather list size from the virtqueue size. They are totally unrelated - even now you can have a larger request by using indirect descriptors. We could add a feature to have a smaller or larger S/G length limit. Is this something useful? Having a larger ring size is useful, esp. with zero-copy transmit, and you would need the sglist length limit in order to not require linearization on linux hosts. So the limit is not useful in itself, only indirectly. Google cloud engine exposes virtio ring sizes of 16384. OK this sounds useful, I'll queue this up for consideration. Thanks! Thanks. Even more useful is getting rid of the desc array and instead passing descs inline in avail and used. You expect this to improve performance? Quite possibly but this will have to be demonstrated. The top vhost function in small packet workloads is vhost_get_vq_desc, and the top instruction within that (50%) is the one that reads the first 8 bytes of desc. It's a guaranteed cache line miss (and again on the guest side when it's time to reuse). Inline descriptors will amortize the cache miss over 4 descriptors, and will allow the hardware to prefetch, since the descriptors are linear in memory.
Re: [Qemu-devel] [PATCH v5 0/5] add description field in ObjectProperty and PropertyInfo struct
On 2014/10/8 6:22, Paolo Bonzini wrote: Il 07/10/2014 08:33, arei.gong...@huawei.com ha scritto: From: Gonglei arei.gong...@huawei.com v5 - v4: 1. add some improvements by Michael's suggtion, Thanks. (Michael) 2. add 'Reviewed-by' tag (Paolo, Michael, Eric) Andreas, this series depends on patches in qom-next so you'll have to take it. Yes, please. Thanks! Best regards, -Gonglei Thanks, Paolo v4 - v3: 1. rebase on qom-next tree (Andreas) 2. fix memory leak in PATCH 2, move object_property_set_description calling in object_property_add_alias() from PATCH 3 to PATCH 2. (Paolo) 3. drop ?: in PATCH 2, call g_strdup() directly 4. rework PATCH 4, change description as optional field, drop ?: conditional express (Eric) v3 - v2: 1. add a new description field to DevicePropertyInfo, and format it in qdev_device_help() in PATCH 6 (Paolo) v2 - v1: 1. rename fail label to out in PATCH 1 (Andreas) 2. improve descriptions in PATCH 3 (Paolo, adding Signed-off-by Paolo in this patch) 3. rework PATCH 5, set description at qdev_property_add_static(), then copy the description of target_obj.property. (Paolo) 4. free description filed of ObjectProperty avoid memory leak in PATCH 4. This patch series based on qom-next tree: https://github.com/afaerber/qemu-cpu/commits/qom-next Add a description field in both ObjectProperty and PropertyInfo struct. The descriptions can serve as documentation in the code, and they can be used to provide better help. For example: Before this patch series: $./qemu-system-x86_64 -device virtio-blk-pci,? virtio-blk-pci.iothread=linkiothread virtio-blk-pci.x-data-plane=bool virtio-blk-pci.scsi=bool virtio-blk-pci.config-wce=bool virtio-blk-pci.serial=str virtio-blk-pci.secs=uint32 virtio-blk-pci.heads=uint32 virtio-blk-pci.cyls=uint32 virtio-blk-pci.discard_granularity=uint32 virtio-blk-pci.bootindex=int32 virtio-blk-pci.opt_io_size=uint32 virtio-blk-pci.min_io_size=uint16 virtio-blk-pci.physical_block_size=uint16 virtio-blk-pci.logical_block_size=uint16 virtio-blk-pci.drive=str virtio-blk-pci.virtio-backend=childvirtio-blk-device virtio-blk-pci.command_serr_enable=on/off virtio-blk-pci.multifunction=on/off virtio-blk-pci.rombar=uint32 virtio-blk-pci.romfile=str virtio-blk-pci.addr=pci-devfn virtio-blk-pci.event_idx=on/off virtio-blk-pci.indirect_desc=on/off virtio-blk-pci.vectors=uint32 virtio-blk-pci.ioeventfd=on/off virtio-blk-pci.class=uint32 After: $./qemu-system-x86_64 -device virtio-blk-pci,? virtio-blk-pci.iothread=linkiothread virtio-blk-pci.x-data-plane=bool (on/off) virtio-blk-pci.scsi=bool (on/off) virtio-blk-pci.config-wce=bool (on/off) virtio-blk-pci.serial=str virtio-blk-pci.secs=uint32 virtio-blk-pci.heads=uint32 virtio-blk-pci.cyls=uint32 virtio-blk-pci.discard_granularity=uint32 virtio-blk-pci.bootindex=int32 virtio-blk-pci.opt_io_size=uint32 virtio-blk-pci.min_io_size=uint16 virtio-blk-pci.physical_block_size=uint16 (A power of two between 512 and 32768) virtio-blk-pci.logical_block_size=uint16 (A power of two between 512 and 32768) virtio-blk-pci.drive=str (ID of a drive to use as a backend) virtio-blk-pci.virtio-backend=childvirtio-blk-device virtio-blk-pci.command_serr_enable=bool (on/off) virtio-blk-pci.multifunction=bool (on/off) virtio-blk-pci.rombar=uint32 virtio-blk-pci.romfile=str virtio-blk-pci.addr=int32 (Slot and optional function number, example: 06.0 or 06) virtio-blk-pci.event_idx=bool (on/off) virtio-blk-pci.indirect_desc=bool (on/off) virtio-blk-pci.vectors=uint32 virtio-blk-pci.ioeventfd=bool (on/off) virtio-blk-pci.class=uint32 Gonglei (5): qdev: add description field in PropertyInfo struct qom: add description field in ObjectProperty struct qdev: set the object property's description to the qdev property's. qmp: print descriptions of object properties qdev: drop legacy_name from qdev properties hw/core/qdev-properties-system.c | 8 hw/core/qdev-properties.c| 14 -- hw/core/qdev.c | 5 + include/hw/qdev-core.h | 2 +- include/qom/object.h | 14 ++ qapi-schema.json | 4 +++- qdev-monitor.c | 7 ++- qmp.c| 13 ++--- qom/object.c | 20 target-ppc/translate_init.c | 2 +- 10 files changed, 72 insertions(+), 17 deletions(-)
Re: [Qemu-devel] [QA-virtio]:Why vring size is limited to 1024?
On Wed, Oct 08, 2014 at 01:37:25PM +0300, Avi Kivity wrote: On 10/08/2014 01:14 PM, Michael S. Tsirkin wrote: On Wed, Oct 08, 2014 at 12:51:21PM +0300, Avi Kivity wrote: On 10/08/2014 12:15 PM, Michael S. Tsirkin wrote: On Wed, Oct 08, 2014 at 10:43:07AM +0300, Avi Kivity wrote: On 09/30/2014 12:33 PM, Michael S. Tsirkin wrote: a single descriptor might use all of the virtqueue. In this case we wont to be able to pass the descriptor directly to linux as a single iov, since You could separate maximum request scatter/gather list size from the virtqueue size. They are totally unrelated - even now you can have a larger request by using indirect descriptors. We could add a feature to have a smaller or larger S/G length limit. Is this something useful? Having a larger ring size is useful, esp. with zero-copy transmit, and you would need the sglist length limit in order to not require linearization on linux hosts. So the limit is not useful in itself, only indirectly. Google cloud engine exposes virtio ring sizes of 16384. OK this sounds useful, I'll queue this up for consideration. Thanks! Thanks. Even more useful is getting rid of the desc array and instead passing descs inline in avail and used. You expect this to improve performance? Quite possibly but this will have to be demonstrated. The top vhost function in small packet workloads is vhost_get_vq_desc, and the top instruction within that (50%) is the one that reads the first 8 bytes of desc. It's a guaranteed cache line miss (and again on the guest side when it's time to reuse). OK so basically what you are pointing out is that we get 5 accesses: read of available head, read of available ring, read of descriptor, write of used ring, write of used ring head. If processing is in-order, we could build a much simpler design, with a valid bit in the descriptor, cleared by host as descriptors are consumed. Basically get rid of both used and available ring. Sounds good in theory. Inline descriptors will amortize the cache miss over 4 descriptors, and will allow the hardware to prefetch, since the descriptors are linear in memory. If descriptors are used in order (as they are with current qemu) then aren't they amortized already? -- MST
Re: [Qemu-devel] [PATCH 0/3] parallels: additional iotests and a minor bugfix
Il 08/10/2014 11:13, Denis V. Lunev ha scritto: Pls find here test authentic test material, i.e. parallels images with WithoutFreeSpace and WithouFreSpacExt signatures created in authentic way + a minor bug fix for access to non-initialized memory found by valgrind. Signed-off-by: Denis V. Lunev d...@openvz.org CC: Jeff Cody jc...@redhat.com CC: Kevin Wolf kw...@redhat.com CC: Stefan Hajnoczi stefa...@redhat.com Reviewed-by: Paolo Bonzini pbonz...@redhat.com
[Qemu-devel] [PATCH v4 01/21] target-mips: define ISA_MIPS64R6
Signed-off-by: Leon Alrae leon.al...@imgtec.com Reviewed-by: Aurelien Jarno aurel...@aurel32.net --- v2: * move new CPU definition to a separate patch --- target-mips/mips-defs.h | 28 +++- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/target-mips/mips-defs.h b/target-mips/mips-defs.h index 9dfa516..6cb62b2 100644 --- a/target-mips/mips-defs.h +++ b/target-mips/mips-defs.h @@ -30,17 +30,21 @@ #defineISA_MIPS64 0x0080 #defineISA_MIPS64R20x0100 #define ISA_MIPS32R3 0x0200 -#define ISA_MIPS32R5 0x0400 +#define ISA_MIPS64R3 0x0400 +#define ISA_MIPS32R5 0x0800 +#define ISA_MIPS64R5 0x1000 +#define ISA_MIPS32R6 0x2000 +#define ISA_MIPS64R6 0x4000 /* MIPS ASEs. */ -#defineASE_MIPS16 0x1000 -#defineASE_MIPS3D 0x2000 -#defineASE_MDMX0x4000 -#defineASE_DSP 0x8000 -#defineASE_DSPR2 0x0001 -#defineASE_MT 0x0002 -#defineASE_SMARTMIPS 0x0004 -#defineASE_MICROMIPS 0x0008 +#define ASE_MIPS160x0001 +#define ASE_MIPS3D0x0002 +#define ASE_MDMX 0x0004 +#define ASE_DSP 0x0008 +#define ASE_DSPR2 0x0010 +#define ASE_MT0x0020 +#define ASE_SMARTMIPS 0x0040 +#define ASE_MICROMIPS 0x0080 /* Chip specific instructions. */ #defineINSN_LOONGSON2E 0x2000 @@ -68,9 +72,15 @@ /* MIPS Technologies Release 3 */ #define CPU_MIPS32R3 (CPU_MIPS32R2 | ISA_MIPS32R3) +#define CPU_MIPS64R3 (CPU_MIPS64R2 | CPU_MIPS32R3 | ISA_MIPS64R3) /* MIPS Technologies Release 5 */ #define CPU_MIPS32R5 (CPU_MIPS32R3 | ISA_MIPS32R5) +#define CPU_MIPS64R5 (CPU_MIPS64R3 | CPU_MIPS32R5 | ISA_MIPS64R5) + +/* MIPS Technologies Release 6 */ +#define CPU_MIPS32R6 (CPU_MIPS32R5 | ISA_MIPS32R6) +#define CPU_MIPS64R6 (CPU_MIPS64R5 | CPU_MIPS32R6 | ISA_MIPS64R6) /* Strictly follow the architecture standard: - Disallow special instruction handling for PMON/SPIM. -- 2.1.0
[Qemu-devel] [PATCH v4 00/21] target-mips: add MIPS64R6 Instruction Set support
Hi, Version 4 of the patch series with addressed more comments. Further review (especially for the remaining 3 patches #13, #14 and #21 without Reviewed-by) will be very appreciated. The following patchset implements MIPS64 Release 6 Instruction Set. New instructions are added and also there is a number of instructions which are deleted or moved (the encodings have changed). The MIPS64 Release 6 documentation is available: http://www.imgtec.com/mips/architectures/mips64.asp The following patch series is focusing on instruction set changes only. There is also a new generic cpu supporting R6. Please note that even though the new Floating Point instructions were added, softfloat for MIPS has not been updated yet (in R6 MIPS FPU is updated to IEEE2008). Also, current patchset does not include MIPS64 Privileged Resource Architecture modifications. v4: * fixes for James' and Yongbok's findings * rebased v3: * addressed further comments and suggestions (more detailed changelog included in the separate patches). * dropped patch adding function pointers due to its doubtful usefulness * rebased v2: * addressed all comments so far from Richard and Aurelien. More detailed changelog included in the separate patches. * added missing zero register case for LSA, ALIGN and BITSWAP instructions Leon Alrae (17): target-mips: define ISA_MIPS64R6 target-mips: signal RI Exception on instructions removed in R6 target-mips: add SELEQZ and SELNEZ instructions target-mips: move LL and SC instructions target-mips: extract decode_opc_special* from decode_opc target-mips: split decode_opc_special* into *_r6 and *_legacy target-mips: signal RI Exception on DSP and Loongson instructions target-mips: move PREF, CACHE, LLD and SCD instructions target-mips: redefine Integer Multiply and Divide instructions target-mips: move CLO, DCLO, CLZ, DCLZ, SDBBP and free special2 in R6 target-mips: Status.UX/SX/KX enable 32-bit address wrapping target-mips: add AUI, LSA and PCREL instruction families softfloat: add functions corresponding to IEEE-2008 min/maxNumMag target-mips: add new Floating Point instructions target-mips: do not allow Status.FR=0 mode in 64-bit FPU mips_malta: update malta's pseudo-bootloader - replace JR with JALR target-mips: define a new generic CPU supporting MIPS64 Release 6 ISA Yongbok Kim (4): target-mips: add ALIGN, DALIGN, BITSWAP and DBITSWAP instructions target-mips: add compact and CP1 branches target-mips: add new Floating Point Comparison instructions target-mips: remove JR, BLTZAL, BGEZAL and add NAL, BAL instructions disas/mips.c | 211 ++- fpu/softfloat.c | 37 +- hw/mips/mips_malta.c | 10 +- include/fpu/softfloat.h |4 + target-mips/cpu.h| 18 +- target-mips/helper.h | 52 + target-mips/mips-defs.h | 28 +- target-mips/op_helper.c | 238 +++ target-mips/translate.c | 3813 +++--- target-mips/translate_init.c | 30 + 10 files changed, 3428 insertions(+), 1013 deletions(-) -- 2.1.0
[Qemu-devel] [PATCH v4 07/21] target-mips: signal RI Exception on DSP and Loongson instructions
Move DSP and Loongson instruction to *_legacy functions as they have been removed in R6. Signed-off-by: Leon Alrae leon.al...@imgtec.com Reviewed-by: Aurelien Jarno aurel...@aurel32.net --- target-mips/translate.c | 195 1 file changed, 98 insertions(+), 97 deletions(-) diff --git a/target-mips/translate.c b/target-mips/translate.c index 0c64aeb..11967a0 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -14783,6 +14783,26 @@ static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx) case OPC_MUL: gen_arith(ctx, op1, rd, rs, rt); break; +case OPC_DIV_G_2F: +case OPC_DIVU_G_2F: +case OPC_MULT_G_2F: +case OPC_MULTU_G_2F: +case OPC_MOD_G_2F: +case OPC_MODU_G_2F: +check_insn(ctx, INSN_LOONGSON2F); +gen_loongson_integer(ctx, op1, rd, rs, rt); +break; +#if defined(TARGET_MIPS64) +case OPC_DMULT_G_2F: +case OPC_DMULTU_G_2F: +case OPC_DDIV_G_2F: +case OPC_DDIVU_G_2F: +case OPC_DMOD_G_2F: +case OPC_DMODU_G_2F: +check_insn(ctx, INSN_LOONGSON2F); +gen_loongson_integer(ctx, op1, rd, rs, rt); +break; +#endif default:/* Invalid */ MIPS_INVAL(special2_legacy); generate_exception(ctx, EXCP_RI); @@ -14792,11 +14812,10 @@ static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx) static void decode_opc_special2(CPUMIPSState *env, DisasContext *ctx) { -int rs, rt, rd; +int rs, rd; uint32_t op1; rs = (ctx-opcode 21) 0x1f; -rt = (ctx-opcode 16) 0x1f; rd = (ctx-opcode 11) 0x1f; op1 = MASK_SPECIAL2(ctx-opcode); @@ -14818,15 +14837,6 @@ static void decode_opc_special2(CPUMIPSState *env, DisasContext *ctx) } /* Treat as NOP. */ break; -case OPC_DIV_G_2F: -case OPC_DIVU_G_2F: -case OPC_MULT_G_2F: -case OPC_MULTU_G_2F: -case OPC_MOD_G_2F: -case OPC_MODU_G_2F: -check_insn(ctx, INSN_LOONGSON2F); -gen_loongson_integer(ctx, op1, rd, rs, rt); -break; #if defined(TARGET_MIPS64) case OPC_DCLO: case OPC_DCLZ: @@ -14834,15 +14844,6 @@ static void decode_opc_special2(CPUMIPSState *env, DisasContext *ctx) check_mips_64(ctx); gen_cl(ctx, op1, rd, rs); break; -case OPC_DMULT_G_2F: -case OPC_DMULTU_G_2F: -case OPC_DDIV_G_2F: -case OPC_DDIVU_G_2F: -case OPC_DMOD_G_2F: -case OPC_DMODU_G_2F: -check_insn(ctx, INSN_LOONGSON2F); -gen_loongson_integer(ctx, op1, rd, rs, rt); -break; #endif default: if (ctx-insn_flags ISA_MIPS32R6) { @@ -14880,80 +14881,15 @@ static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx) static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx) { -uint32_t op1; -#if defined(TARGET_MIPS64) -int rd = (ctx-opcode 11) 0x1f; -int rs = (ctx-opcode 21) 0x1f; -int rt = (ctx-opcode 16) 0x1f; -#endif - -op1 = MASK_SPECIAL3(ctx-opcode); -switch (op1) { -#if defined(TARGET_MIPS64) -case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E: -case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E: -case OPC_DMOD_G_2E ... OPC_DMODU_G_2E: -check_insn(ctx, INSN_LOONGSON2E); -gen_loongson_integer(ctx, op1, rd, rs, rt); -break; -#endif -default:/* Invalid */ -MIPS_INVAL(special3_legacy); -generate_exception(ctx, EXCP_RI); -break; -} -} - -static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx) -{ -int rs, rt, rd, sa; +int rs, rt, rd; uint32_t op1, op2; rs = (ctx-opcode 21) 0x1f; rt = (ctx-opcode 16) 0x1f; rd = (ctx-opcode 11) 0x1f; -sa = (ctx-opcode 6) 0x1f; op1 = MASK_SPECIAL3(ctx-opcode); switch (op1) { -case OPC_EXT: -case OPC_INS: -check_insn(ctx, ISA_MIPS32R2); -gen_bitops(ctx, op1, rt, rs, sa, rd); -break; -case OPC_BSHFL: -check_insn(ctx, ISA_MIPS32R2); -op2 = MASK_BSHFL(ctx-opcode); -gen_bshfl(ctx, op2, rt, rd); -break; -case OPC_RDHWR: -gen_rdhwr(ctx, rt, rd); -break; -case OPC_FORK: -check_insn(ctx, ASE_MT); -{ -TCGv t0 = tcg_temp_new(); -TCGv t1 = tcg_temp_new(); - -gen_load_gpr(t0, rt); -gen_load_gpr(t1, rs); -gen_helper_fork(t0, t1); -tcg_temp_free(t0); -tcg_temp_free(t1); -} -break; -case OPC_YIELD: -check_insn(ctx, ASE_MT); -{ -TCGv t0 = tcg_temp_new(); - -save_cpu_state(ctx, 1); -gen_load_gpr(t0, rs); -gen_helper_yield(t0, cpu_env, t0); -gen_store_gpr(t0, rd); -tcg_temp_free(t0); -} -break; case OPC_DIV_G_2E ... OPC_DIVU_G_2E: case OPC_MOD_G_2E ...
[Qemu-devel] [PATCH v4 08/21] target-mips: move PREF, CACHE, LLD and SCD instructions
The encoding of PREF, CACHE, LLD and SCD instruction changed in MIPS32R6. Additionally, the hint codes in PREF instruction greater than or equal to 24 generate Reserved Instruction Exception. Signed-off-by: Leon Alrae leon.al...@imgtec.com Reviewed-by: Aurelien Jarno aurel...@aurel32.net --- disas/mips.c| 4 target-mips/translate.c | 29 - 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/disas/mips.c b/disas/mips.c index f0efa8b..cae76ed 100644 --- a/disas/mips.c +++ b/disas/mips.c @@ -1219,6 +1219,10 @@ const struct mips_opcode mips_builtin_opcodes[] = /* name,args, match, mask, pinfo, membership */ {ll, t,o(b), 0x7c36, 0xfc7f, LDD|RD_b|WR_t,0, I32R6}, {sc, t,o(b), 0x7c26, 0xfc7f, LDD|RD_b|WR_t,0, I32R6}, +{lld, t,o(b), 0x7c37, 0xfc7f, LDD|RD_b|WR_t,0, I64R6}, +{scd, t,o(b), 0x7c27, 0xfc7f, LDD|RD_b|WR_t,0, I64R6}, +{pref,h,o(b), 0x7c35, 0xfc7f, RD_b, 0, I32R6}, +{cache, k,o(b), 0x7c25, 0xfc7f, RD_b, 0, I32R6}, {seleqz, d,v,t,0x0035, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I32R6}, {selnez, d,v,t,0x0037, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I32R6}, {pref,k,o(b), 0xcc00, 0xfc00, RD_b, 0, I4|I32|G3 }, diff --git a/target-mips/translate.c b/target-mips/translate.c index 11967a0..f50d906 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -349,8 +349,12 @@ enum { OPC_DEXTR_W_DSP= 0x3C | OPC_SPECIAL3, /* R6 */ +R6_OPC_PREF= 0x35 | OPC_SPECIAL3, +R6_OPC_CACHE = 0x25 | OPC_SPECIAL3, R6_OPC_LL = 0x36 | OPC_SPECIAL3, R6_OPC_SC = 0x26 | OPC_SPECIAL3, +R6_OPC_LLD = 0x37 | OPC_SPECIAL3, +R6_OPC_SCD = 0x27 | OPC_SPECIAL3, }; /* BSHFL opcodes */ @@ -1645,6 +1649,7 @@ static void gen_ld(DisasContext *ctx, uint32_t opc, opn = ld; break; case OPC_LLD: +case R6_OPC_LLD: save_cpu_state(ctx, 1); op_ld_lld(t0, t0, ctx); gen_store_gpr(t0, rt); @@ -1867,6 +1872,7 @@ static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt, switch (opc) { #if defined(TARGET_MIPS64) case OPC_SCD: +case R6_OPC_SCD: save_cpu_state(ctx, 1); op_st_scd(t1, t0, rt, ctx); opn = scd; @@ -14866,12 +14872,30 @@ static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx) op1 = MASK_SPECIAL3(ctx-opcode); switch (op1) { +case R6_OPC_PREF: +if (rt = 24) { +/* hint codes 24-31 are reserved and signal RI */ +generate_exception(ctx, EXCP_RI); +} +/* Treat as NOP. */ +break; +case R6_OPC_CACHE: +/* Treat as NOP. */ +break; case R6_OPC_SC: gen_st_cond(ctx, op1, rt, rs, imm); break; case R6_OPC_LL: gen_ld(ctx, op1, rt, rs, imm); break; +#if defined(TARGET_MIPS64) +case R6_OPC_SCD: +gen_st_cond(ctx, op1, rt, rs, imm); +break; +case R6_OPC_LLD: +gen_ld(ctx, op1, rt, rs, imm); +break; +#endif default:/* Invalid */ MIPS_INVAL(special3_r6); generate_exception(ctx, EXCP_RI); @@ -15686,11 +15710,13 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx) gen_st_cond(ctx, op, rt, rs, imm); break; case OPC_CACHE: +check_insn_opc_removed(ctx, ISA_MIPS32R6); check_cp0_enabled(ctx); check_insn(ctx, ISA_MIPS3 | ISA_MIPS32); /* Treat as NOP. */ break; case OPC_PREF: +check_insn_opc_removed(ctx, ISA_MIPS32R6); check_insn(ctx, ISA_MIPS4 | ISA_MIPS32); /* Treat as NOP. */ break; @@ -15813,9 +15839,9 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx) #if defined(TARGET_MIPS64) /* MIPS64 opcodes */ case OPC_LDL ... OPC_LDR: +case OPC_LLD: check_insn_opc_removed(ctx, ISA_MIPS32R6); case OPC_LWU: -case OPC_LLD: case OPC_LD: check_insn(ctx, ISA_MIPS3); check_mips_64(ctx); @@ -15829,6 +15855,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx) gen_st(ctx, op, rt, rs, imm); break; case OPC_SCD: +check_insn_opc_removed(ctx, ISA_MIPS32R6); check_insn(ctx, ISA_MIPS3); check_mips_64(ctx); gen_st_cond(ctx, op, rt, rs, imm); -- 2.1.0
[Qemu-devel] [PATCH v4 04/21] target-mips: move LL and SC instructions
The encoding of LL and SC instruction has changed in MIPS32 Release 6. Signed-off-by: Leon Alrae leon.al...@imgtec.com Reviewed-by: Aurelien Jarno aurel...@aurel32.net Reviewed-by: James Hogan james.ho...@imgtec.com --- v4: * fix disas mask for ll and sc * remove unnecessary check_insn_opc_removed line --- disas/mips.c| 9 - target-mips/translate.c | 28 ++-- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/disas/mips.c b/disas/mips.c index b950e53..f0efa8b 100644 --- a/disas/mips.c +++ b/disas/mips.c @@ -119,6 +119,8 @@ see http://www.gnu.org/licenses/. */ #define OP_SH_IMMEDIATE0 #define OP_MASK_DELTA 0x #define OP_SH_DELTA0 +#define OP_MASK_DELTA_R60x1ff +#define OP_SH_DELTA_R6 7 #define OP_MASK_FUNCT 0x3f #define OP_SH_FUNCT0 #define OP_MASK_SPEC 0x3f @@ -1215,6 +1217,8 @@ const struct mips_opcode mips_builtin_opcodes[] = them first. The assemblers uses a hash table based on the instruction name anyhow. */ /* name,args, match, mask, pinfo, membership */ +{ll, t,o(b), 0x7c36, 0xfc7f, LDD|RD_b|WR_t,0, I32R6}, +{sc, t,o(b), 0x7c26, 0xfc7f, LDD|RD_b|WR_t,0, I32R6}, {seleqz, d,v,t,0x0035, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I32R6}, {selnez, d,v,t,0x0037, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I32R6}, {pref,k,o(b), 0xcc00, 0xfc00, RD_b, 0, I4|I32|G3 }, @@ -3734,7 +3738,10 @@ print_insn_args (const char *d, case 'j': /* Same as i, but sign-extended. */ case 'o': - delta = (l OP_SH_DELTA) OP_MASK_DELTA; +delta = (opp-membership == I32R6) ? +(l OP_SH_DELTA_R6) OP_MASK_DELTA_R6 : +(l OP_SH_DELTA) OP_MASK_DELTA; + if (delta 0x8000) delta |= ~0x; (*info-fprintf_func) (info-stream, %d, diff --git a/target-mips/translate.c b/target-mips/translate.c index ba9daac..8606f32 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -347,6 +347,10 @@ enum { /* MIPS DSP Accumulator and DSPControl Access Sub-class */ OPC_EXTR_W_DSP = 0x38 | OPC_SPECIAL3, OPC_DEXTR_W_DSP= 0x3C | OPC_SPECIAL3, + +/* R6 */ +R6_OPC_LL = 0x36 | OPC_SPECIAL3, +R6_OPC_SC = 0x26 | OPC_SPECIAL3, }; /* BSHFL opcodes */ @@ -1775,6 +1779,7 @@ static void gen_ld(DisasContext *ctx, uint32_t opc, opn = lwr; break; case OPC_LL: +case R6_OPC_LL: save_cpu_state(ctx, 1); op_ld_ll(t0, t0, ctx); gen_store_gpr(t0, rt); @@ -1868,6 +1873,7 @@ static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt, break; #endif case OPC_SC: +case R6_OPC_SC: save_cpu_state(ctx, 1); op_st_sc(t1, t0, rt, ctx); opn = sc; @@ -14804,6 +14810,10 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx) case OPC_SPECIAL3: op1 = MASK_SPECIAL3(ctx-opcode); switch (op1) { +case R6_OPC_LL: +check_insn(ctx, ISA_MIPS32R6); +gen_ld(ctx, op1, rt, rs, imm 7); +break; case OPC_EXT: case OPC_INS: check_insn(ctx, ISA_MIPS32R2); @@ -15108,6 +15118,19 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx) break; } break; +case R6_OPC_SC: /* OPC_DMOD_G_2E */ +if (ctx-insn_flags ISA_MIPS32R6) { +gen_st_cond(ctx, op1, rt, rs, imm 7); +} else { +#if defined(TARGET_MIPS64) +check_insn(ctx, INSN_LOONGSON2E); +gen_loongson_integer(ctx, op1, rd, rs, rt); +#else +/* Invalid in MIPS32 */ +generate_exception(ctx, EXCP_RI); +#endif +} +break; #if defined(TARGET_MIPS64) case OPC_DEXTM ... OPC_DEXT: case OPC_DINSM ... OPC_DINS: @@ -15123,7 +15146,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx) break; case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E: case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E: -case OPC_DMOD_G_2E ... OPC_DMODU_G_2E: +case OPC_DMODU_G_2E: check_insn(ctx, INSN_LOONGSON2E); gen_loongson_integer(ctx, op1, rd, rs, rt); break; @@ -15512,10 +15535,10 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx) break; case OPC_LWL: /* Load and stores */ case OPC_LWR: +case OPC_LL: check_insn_opc_removed(ctx, ISA_MIPS32R6); case OPC_LB ... OPC_LH: case OPC_LW ... OPC_LHU: -case OPC_LL: gen_ld(ctx, op, rt, rs, imm); break; case OPC_SWL: @@ -15526,6 +15549,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext
[Qemu-devel] [PATCH v4 03/21] target-mips: add SELEQZ and SELNEZ instructions
Signed-off-by: Leon Alrae leon.al...@imgtec.com Reviewed-by: Aurelien Jarno aurel...@aurel32.net Reviewed-by: James Hogan james.ho...@imgtec.com --- v4: * remove OPC_SPECIAL35_RESERVED and OPC_SPECIAL37_RESERVED v2: * correct conditions to match instruction name --- disas/mips.c| 8 target-mips/translate.c | 18 -- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/disas/mips.c b/disas/mips.c index 2106b57..b950e53 100644 --- a/disas/mips.c +++ b/disas/mips.c @@ -521,6 +521,8 @@ struct mips_opcode #define INSN_ISA640x0040 #define INSN_ISA32R2 0x0080 #define INSN_ISA64R2 0x0100 +#define INSN_ISA32R6 0x0200 +#define INSN_ISA64R6 0x0400 /* Masks used for MIPS-defined ASEs. */ #define INSN_ASE_MASK0xf000 @@ -585,6 +587,8 @@ struct mips_opcode #define ISA_MIPS32R2(ISA_MIPS32 | INSN_ISA32R2) #define ISA_MIPS64R2(ISA_MIPS64 | INSN_ISA32R2 | INSN_ISA64R2) +#define ISA_MIPS32R6(ISA_MIPS32R2 | INSN_ISA32R6) +#define ISA_MIPS64R6(ISA_MIPS64R2 | INSN_ISA32R6 | INSN_ISA64R6) /* CPU defines, use instead of hardcoding processor number. Keep this in sync with bfd/archures.c in order for machine selection to work. */ @@ -1121,6 +1125,8 @@ extern const int bfd_mips16_num_opcodes; #define I64 INSN_ISA64 #define I33INSN_ISA32R2 #define I65INSN_ISA64R2 +#define I32R6 INSN_ISA32R6 +#define I64R6 INSN_ISA64R6 /* MIPS64 MIPS-3D ASE support. */ #define I16 INSN_MIPS16 @@ -1209,6 +1215,8 @@ const struct mips_opcode mips_builtin_opcodes[] = them first. The assemblers uses a hash table based on the instruction name anyhow. */ /* name,args, match, mask, pinfo, membership */ +{seleqz, d,v,t,0x0035, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I32R6}, +{selnez, d,v,t,0x0037, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I32R6}, {pref,k,o(b), 0xcc00, 0xfc00, RD_b, 0, I4|I32|G3 }, {prefx, h,t(b), 0x4c0f, 0xfc0007ff, RD_b|RD_t, 0, I4|I33 }, {nop, , 0x, 0x, 0, INSN2_ALIAS,I1 }, /* sll */ diff --git a/target-mips/translate.c b/target-mips/translate.c index de11747..ba9daac 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -193,6 +193,9 @@ enum { OPC_MOVZ = 0x0A | OPC_SPECIAL, OPC_MOVN = 0x0B | OPC_SPECIAL, +OPC_SELEQZ = 0x35 | OPC_SPECIAL, +OPC_SELNEZ = 0x37 | OPC_SPECIAL, + OPC_MOVCI= 0x01 | OPC_SPECIAL, /* Special */ @@ -205,8 +208,6 @@ enum { OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL, OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL, OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL, -OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL, -OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL, OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL, OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL, }; @@ -2412,6 +2413,14 @@ static void gen_cond_move(DisasContext *ctx, uint32_t opc, tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]); opn = movz; break; +case OPC_SELNEZ: +tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1); +opn = selnez; +break; +case OPC_SELEQZ: +tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1); +opn = seleqz; +break; } tcg_temp_free(t2); tcg_temp_free(t1); @@ -14533,6 +14542,11 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx) INSN_LOONGSON2E | INSN_LOONGSON2F); gen_cond_move(ctx, op1, rd, rs, rt); break; +case OPC_SELEQZ: +case OPC_SELNEZ: +check_insn(ctx, ISA_MIPS32R6); +gen_cond_move(ctx, op1, rd, rs, rt); +break; case OPC_ADD ... OPC_SUBU: gen_arith(ctx, op1, rd, rs, rt); break; -- 2.1.0
[Qemu-devel] [PATCH v4 09/21] target-mips: redefine Integer Multiply and Divide instructions
Use R6_ prefix in front of all new Multiply / Divide instructions for easier differentiation between R6 and preR6. Signed-off-by: Leon Alrae leon.al...@imgtec.com Reviewed-by: Aurelien Jarno aurel...@aurel32.net --- v2: * use tcg_gen_mul_* for cases where the high part is discarded --- disas/mips.c| 16 +++ target-mips/translate.c | 343 +--- 2 files changed, 338 insertions(+), 21 deletions(-) diff --git a/disas/mips.c b/disas/mips.c index cae76ed..16cb2ac 100644 --- a/disas/mips.c +++ b/disas/mips.c @@ -1217,6 +1217,22 @@ const struct mips_opcode mips_builtin_opcodes[] = them first. The assemblers uses a hash table based on the instruction name anyhow. */ /* name,args, match, mask, pinfo, membership */ +{mul, d,s,t,0x0098, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I32R6}, +{muh, d,s,t,0x00d8, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I32R6}, +{mulu,d,s,t,0x0099, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I32R6}, +{muhu,d,s,t,0x00d9, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I32R6}, +{div, d,s,t,0x009a, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I32R6}, +{mod, d,s,t,0x00da, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I32R6}, +{divu,d,s,t,0x009b, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I32R6}, +{modu,d,s,t,0x00db, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I32R6}, +{dmul,d,s,t,0x009c, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I64R6}, +{dmuh,d,s,t,0x00dc, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I64R6}, +{dmulu, d,s,t,0x009d, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I64R6}, +{dmuhu, d,s,t,0x00dd, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I64R6}, +{ddiv,d,s,t,0x009e, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I64R6}, +{dmod,d,s,t,0x00de, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I64R6}, +{ddivu, d,s,t,0x009f, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I64R6}, +{dmodu, d,s,t,0x00df, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I64R6}, {ll, t,o(b), 0x7c36, 0xfc7f, LDD|RD_b|WR_t,0, I32R6}, {sc, t,o(b), 0x7c26, 0xfc7f, LDD|RD_b|WR_t,0, I32R6}, {lld, t,o(b), 0x7c37, 0xfc7f, LDD|RD_b|WR_t,0, I64R6}, diff --git a/target-mips/translate.c b/target-mips/translate.c index f50d906..3ce9641 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -157,6 +157,7 @@ enum { OPC_DMULTU = 0x1D | OPC_SPECIAL, OPC_DDIV = 0x1E | OPC_SPECIAL, OPC_DDIVU= 0x1F | OPC_SPECIAL, + /* 2 registers arithmetic / logic */ OPC_ADD = 0x20 | OPC_SPECIAL, OPC_ADDU = 0x21 | OPC_SPECIAL, @@ -212,6 +213,30 @@ enum { OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL, }; +/* R6 Multiply and Divide instructions have the same Opcode + and function field as legacy OPC_MULT[U]/OPC_DIV[U] */ +#define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op (0x7ff))) + +enum { +R6_OPC_MUL = OPC_MULT | (2 6), +R6_OPC_MUH = OPC_MULT | (3 6), +R6_OPC_MULU = OPC_MULTU | (2 6), +R6_OPC_MUHU = OPC_MULTU | (3 6), +R6_OPC_DIV = OPC_DIV | (2 6), +R6_OPC_MOD = OPC_DIV | (3 6), +R6_OPC_DIVU = OPC_DIVU | (2 6), +R6_OPC_MODU = OPC_DIVU | (3 6), + +R6_OPC_DMUL = OPC_DMULT | (2 6), +R6_OPC_DMUH = OPC_DMULT | (3 6), +R6_OPC_DMULU = OPC_DMULTU | (2 6), +R6_OPC_DMUHU = OPC_DMULTU | (3 6), +R6_OPC_DDIV = OPC_DDIV | (2 6), +R6_OPC_DMOD = OPC_DDIV | (3 6), +R6_OPC_DDIVU = OPC_DDIVU | (2 6), +R6_OPC_DMODU = OPC_DDIVU | (3 6), +}; + /* Multiplication variants of the vr54xx. */ #define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op (0x1F 6)) @@ -2691,6 +2716,238 @@ static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg) MIPS_DEBUG(%s %s, opn, regnames[reg]); } +static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt) +{ +const char *opn = r6 mul/div; +TCGv t0, t1; + +if (rd == 0) { +/* Treat as NOP. */ +MIPS_DEBUG(NOP); +return; +} + +t0 = tcg_temp_new(); +t1 = tcg_temp_new(); + +gen_load_gpr(t0, rs); +gen_load_gpr(t1, rt); + +switch (opc) { +case R6_OPC_DIV: +{ +TCGv t2 = tcg_temp_new(); +TCGv t3 = tcg_temp_new(); +tcg_gen_ext32s_tl(t0, t0); +tcg_gen_ext32s_tl(t1, t1); +tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN); +tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1); +tcg_gen_and_tl(t2, t2, t3); +tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0); +tcg_gen_or_tl(t2, t2, t3); +tcg_gen_movi_tl(t3, 0); +tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1); +tcg_gen_div_tl(cpu_gpr[rd], t0, t1); +tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]); +
[Qemu-devel] [PATCH v4 11/21] target-mips: Status.UX/SX/KX enable 32-bit address wrapping
In R6 the special behaviour for data references is also specified for Kernel and Supervisor mode. Therefore MIPS_HFLAG_UX is replaced by generic MIPS_HFLAG_AWRAP indicating enabled 32-bit address wrapping. Signed-off-by: Leon Alrae leon.al...@imgtec.com Reviewed-by: Aurelien Jarno aurel...@aurel32.net --- v2: * set hflag indicating 32-bit wrapping in compute_hflags --- target-mips/cpu.h | 18 ++ target-mips/translate.c | 6 +- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/target-mips/cpu.h b/target-mips/cpu.h index 8b9a92e..51a8331 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -450,7 +450,7 @@ struct CPUMIPSState { and RSQRT.D. */ #define MIPS_HFLAG_COP1X 0x00080 /* COP1X instructions enabled */ #define MIPS_HFLAG_RE 0x00100 /* Reversed endianness*/ -#define MIPS_HFLAG_UX 0x00200 /* 64-bit user mode */ +#define MIPS_HFLAG_AWRAP 0x00200 /* 32-bit compatibility address wrapping */ #define MIPS_HFLAG_M160x00400 /* MIPS16 mode flag */ #define MIPS_HFLAG_M16_SHIFT 10 /* If translation is interrupted between the branch instruction and @@ -725,7 +725,7 @@ static inline void compute_hflags(CPUMIPSState *env) { env-hflags = ~(MIPS_HFLAG_COP1X | MIPS_HFLAG_64 | MIPS_HFLAG_CP0 | MIPS_HFLAG_F64 | MIPS_HFLAG_FPU | MIPS_HFLAG_KSU | - MIPS_HFLAG_UX | MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2); + MIPS_HFLAG_AWRAP | MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2); if (!(env-CP0_Status (1 CP0St_EXL)) !(env-CP0_Status (1 CP0St_ERL)) !(env-hflags MIPS_HFLAG_DM)) { @@ -737,8 +737,18 @@ static inline void compute_hflags(CPUMIPSState *env) (env-CP0_Status (1 CP0St_UX))) { env-hflags |= MIPS_HFLAG_64; } -if (env-CP0_Status (1 CP0St_UX)) { -env-hflags |= MIPS_HFLAG_UX; + +if (((env-hflags MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) +!(env-CP0_Status (1 CP0St_UX))) { +env-hflags |= MIPS_HFLAG_AWRAP; +} else if (env-insn_flags ISA_MIPS32R6) { +/* Address wrapping for Supervisor and Kernel is specified in R6 */ +if env-hflags MIPS_HFLAG_KSU) == MIPS_HFLAG_SM) + !(env-CP0_Status (1 CP0St_SX))) || +(((env-hflags MIPS_HFLAG_KSU) == MIPS_HFLAG_KM) + !(env-CP0_Status (1 CP0St_KX { +env-hflags |= MIPS_HFLAG_AWRAP; +} } #endif if ((env-CP0_Status (1 CP0St_CU0)) || diff --git a/target-mips/translate.c b/target-mips/translate.c index 34d63ea..7420485 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -1383,11 +1383,7 @@ static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv tcg_gen_add_tl(ret, arg0, arg1); #if defined(TARGET_MIPS64) -/* For compatibility with 32-bit code, data reference in user mode - with Status_UX = 0 should be casted to 32-bit and sign extended. - See the MIPS64 PRA manual, section 4.10. */ -if (((ctx-hflags MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) -!(ctx-hflags MIPS_HFLAG_UX)) { +if (ctx-hflags MIPS_HFLAG_AWRAP) { tcg_gen_ext32s_i64(ret, ret); } #endif -- 2.1.0
[Qemu-devel] [PATCH v4 05/21] target-mips: extract decode_opc_special* from decode_opc
Creating separate decode functions for special, special2 and special3 instructions to ease adding new R6 instructions and removing legacy instructions. Signed-off-by: Leon Alrae leon.al...@imgtec.com Reviewed-by: Aurelien Jarno aurel...@aurel32.net --- target-mips/translate.c | 1678 --- 1 file changed, 859 insertions(+), 819 deletions(-) diff --git a/target-mips/translate.c b/target-mips/translate.c index 8606f32..5b8f762 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -14482,911 +14482,950 @@ static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2, /* End MIPSDSP functions. */ -static void decode_opc (CPUMIPSState *env, DisasContext *ctx) +static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) { -int32_t offset; int rs, rt, rd, sa; -uint32_t op, op1, op2; -int16_t imm; - -/* make sure instructions are on a word boundary */ -if (ctx-pc 0x3) { -env-CP0_BadVAddr = ctx-pc; -generate_exception(ctx, EXCP_AdEL); -return; -} - -/* Handle blikely not taken case */ -if ((ctx-hflags MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) { -int l1 = gen_new_label(); - -MIPS_DEBUG(blikely condition ( TARGET_FMT_lx ), ctx-pc + 4); -tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1); -tcg_gen_movi_i32(hflags, ctx-hflags ~MIPS_HFLAG_BMASK); -gen_goto_tb(ctx, 1, ctx-pc + 4); -gen_set_label(l1); -} - -if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) { -tcg_gen_debug_insn_start(ctx-pc); -} +uint32_t op1; -op = MASK_OP_MAJOR(ctx-opcode); rs = (ctx-opcode 21) 0x1f; rt = (ctx-opcode 16) 0x1f; rd = (ctx-opcode 11) 0x1f; sa = (ctx-opcode 6) 0x1f; -imm = (int16_t)ctx-opcode; -switch (op) { -case OPC_SPECIAL: -op1 = MASK_SPECIAL(ctx-opcode); -switch (op1) { -case OPC_SLL: /* Shift with immediate */ -case OPC_SRA: -gen_shift_imm(ctx, op1, rd, rt, sa); -break; -case OPC_SRL: -switch ((ctx-opcode 21) 0x1f) { -case 1: -/* rotr is decoded as srl on non-R2 CPUs */ -if (ctx-insn_flags ISA_MIPS32R2) { -op1 = OPC_ROTR; -} -/* Fallthrough */ -case 0: -gen_shift_imm(ctx, op1, rd, rt, sa); -break; -default: -generate_exception(ctx, EXCP_RI); -break; + +op1 = MASK_SPECIAL(ctx-opcode); +switch (op1) { +case OPC_SLL: /* Shift with immediate */ +case OPC_SRA: +gen_shift_imm(ctx, op1, rd, rt, sa); +break; +case OPC_SRL: +switch ((ctx-opcode 21) 0x1f) { +case 1: +/* rotr is decoded as srl on non-R2 CPUs */ +if (ctx-insn_flags ISA_MIPS32R2) { +op1 = OPC_ROTR; } +/* Fallthrough */ +case 0: +gen_shift_imm(ctx, op1, rd, rt, sa); break; -case OPC_MOVN: /* Conditional move */ -case OPC_MOVZ: -check_insn_opc_removed(ctx, ISA_MIPS32R6); -check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 | - INSN_LOONGSON2E | INSN_LOONGSON2F); -gen_cond_move(ctx, op1, rd, rs, rt); -break; -case OPC_SELEQZ: -case OPC_SELNEZ: -check_insn(ctx, ISA_MIPS32R6); -gen_cond_move(ctx, op1, rd, rs, rt); -break; -case OPC_ADD ... OPC_SUBU: -gen_arith(ctx, op1, rd, rs, rt); -break; -case OPC_SLLV: /* Shifts */ -case OPC_SRAV: -gen_shift(ctx, op1, rd, rs, rt); -break; -case OPC_SRLV: -switch ((ctx-opcode 6) 0x1f) { -case 1: -/* rotrv is decoded as srlv on non-R2 CPUs */ -if (ctx-insn_flags ISA_MIPS32R2) { -op1 = OPC_ROTRV; -} -/* Fallthrough */ -case 0: -gen_shift(ctx, op1, rd, rs, rt); -break; -default: -generate_exception(ctx, EXCP_RI); -break; -} +default: +generate_exception(ctx, EXCP_RI); break; -case OPC_SLT: /* Set on less than */ -case OPC_SLTU: -gen_slt(ctx, op1, rd, rs, rt); -break; -case OPC_AND: /* Logic*/ -case OPC_OR: -case OPC_NOR: -case OPC_XOR: -gen_logic(ctx, op1, rd, rs, rt); -break; -case OPC_MULT: -case OPC_MULTU: -if (sa) { -check_insn(ctx, INSN_VR54XX); -op1 = MASK_MUL_VR54XX(ctx-opcode); -
[Qemu-devel] [PATCH v4 02/21] target-mips: signal RI Exception on instructions removed in R6
Signal Reserved Instruction Exception on instructions that do not exist in R6. In this commit the following groups of preR6 instructions are marked as deleted: - Floating Point Paired Single - Floating Point Compare - conditional moves / branches on FPU conditions - branch likelies - unaligned loads / stores - traps - legacy accumulator instructions - COP1X - MIPS-3D Signed-off-by: Leon Alrae leon.al...@imgtec.com Reviewed-by: Aurelien Jarno aurel...@aurel32.net --- target-mips/translate.c | 64 ++--- 1 file changed, 56 insertions(+), 8 deletions(-) diff --git a/target-mips/translate.c b/target-mips/translate.c index 06db150..de11747 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -1436,6 +1436,16 @@ static inline void check_insn(DisasContext *ctx, int flags) } } +/* This code generates a reserved instruction exception if the + CPU has corresponding flag set which indicates that the instruction + has been removed. */ +static inline void check_insn_opc_removed(DisasContext *ctx, int flags) +{ +if (unlikely(ctx-insn_flags flags)) { +generate_exception(ctx, EXCP_RI); +} +} + /* This code generates a reserved instruction exception if 64-bit instructions are not enabled. */ static inline void check_mips_64(DisasContext *ctx) @@ -7712,10 +7722,12 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1, opn = floor.w.s; break; case OPC_MOVCF_S: +check_insn_opc_removed(ctx, ISA_MIPS32R6); gen_movcf_s(fs, fd, (ft 2) 0x7, ft 0x1); opn = movcf.s; break; case OPC_MOVZ_S: +check_insn_opc_removed(ctx, ISA_MIPS32R6); { int l1 = gen_new_label(); TCGv_i32 fp0; @@ -7732,6 +7744,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1, opn = movz.s; break; case OPC_MOVN_S: +check_insn_opc_removed(ctx, ISA_MIPS32R6); { int l1 = gen_new_label(); TCGv_i32 fp0; @@ -7865,6 +7878,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1, opn = cvt.l.s; break; case OPC_CVT_PS_S: +check_insn_opc_removed(ctx, ISA_MIPS32R6); check_cp1_64bitmode(ctx); { TCGv_i64 fp64 = tcg_temp_new_i64(); @@ -7897,6 +7911,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1, case OPC_CMP_NGE_S: case OPC_CMP_LE_S: case OPC_CMP_NGT_S: +check_insn_opc_removed(ctx, ISA_MIPS32R6); if (ctx-opcode (1 6)) { gen_cmpabs_s(ctx, func-48, ft, fs, cc); opn = condnames_abs[func-48]; @@ -8121,10 +8136,12 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1, opn = floor.w.d; break; case OPC_MOVCF_D: +check_insn_opc_removed(ctx, ISA_MIPS32R6); gen_movcf_d(ctx, fs, fd, (ft 2) 0x7, ft 0x1); opn = movcf.d; break; case OPC_MOVZ_D: +check_insn_opc_removed(ctx, ISA_MIPS32R6); { int l1 = gen_new_label(); TCGv_i64 fp0; @@ -8141,6 +8158,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1, opn = movz.d; break; case OPC_MOVN_D: +check_insn_opc_removed(ctx, ISA_MIPS32R6); { int l1 = gen_new_label(); TCGv_i64 fp0; @@ -8250,6 +8268,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1, case OPC_CMP_NGE_D: case OPC_CMP_LE_D: case OPC_CMP_NGT_D: +check_insn_opc_removed(ctx, ISA_MIPS32R6); if (ctx-opcode (1 6)) { gen_cmpabs_d(ctx, func-48, ft, fs, cc); opn = condnames_abs[func-48]; @@ -8350,6 +8369,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1, opn = cvt.d.l; break; case OPC_CVT_PS_PW: +check_insn_opc_removed(ctx, ISA_MIPS32R6); check_cp1_64bitmode(ctx); { TCGv_i64 fp0 = tcg_temp_new_i64(); @@ -14508,6 +14528,7 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx) break; case OPC_MOVN: /* Conditional move */ case OPC_MOVZ: +check_insn_opc_removed(ctx, ISA_MIPS32R6); check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 | INSN_LOONGSON2E | INSN_LOONGSON2F); gen_cond_move(ctx, op1, rd, rs, rt); @@ -14568,10 +14589,12 @@ static void decode_opc (CPUMIPSState *env, DisasContext *ctx) break; case OPC_MFHI: /* Move from HI/LO */ case OPC_MFLO: +check_insn_opc_removed(ctx, ISA_MIPS32R6); gen_HILO(ctx, op1, rs 3, rd); break; case OPC_MTHI: case OPC_MTLO: /* Move to HI/LO */ +check_insn_opc_removed(ctx, ISA_MIPS32R6); gen_HILO(ctx, op1, rd 3, rs); break; case
[Qemu-devel] [PATCH v4 10/21] target-mips: move CLO, DCLO, CLZ, DCLZ, SDBBP and free special2 in R6
Also consider OPC_SPIM instruction as deleted in R6 because it is overlaping with MIPS32R6 SDBBP. Signed-off-by: Leon Alrae leon.al...@imgtec.com Reviewed-by: Aurelien Jarno aurel...@aurel32.net --- v2: * check_insn_opc_removed() moved to decode_opc_special2_legacy() --- disas/mips.c| 5 ++ target-mips/translate.c | 121 +--- 2 files changed, 67 insertions(+), 59 deletions(-) diff --git a/disas/mips.c b/disas/mips.c index 16cb2ac..8ee8758 100644 --- a/disas/mips.c +++ b/disas/mips.c @@ -1217,6 +1217,11 @@ const struct mips_opcode mips_builtin_opcodes[] = them first. The assemblers uses a hash table based on the instruction name anyhow. */ /* name,args, match, mask, pinfo, membership */ +{clz, U,s, 0x0050, 0xfc1f07ff, WR_d|RD_s,0, I32R6}, +{clo, U,s, 0x0051, 0xfc1f07ff, WR_d|RD_s,0, I32R6}, +{dclz,U,s, 0x0052, 0xfc1f07ff, WR_d|RD_s,0, I64R6}, +{dclo,U,s, 0x0053, 0xfc1f07ff, WR_d|RD_s,0, I64R6}, +{sdbbp, B,0x000e, 0xfc3f, TRAP, 0, I32R6}, {mul, d,s,t,0x0098, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I32R6}, {muh, d,s,t,0x00d8, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I32R6}, {mulu,d,s,t,0x0099, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I32R6}, diff --git a/target-mips/translate.c b/target-mips/translate.c index 3ce9641..34d63ea 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -235,6 +235,12 @@ enum { R6_OPC_DMOD = OPC_DDIV | (3 6), R6_OPC_DDIVU = OPC_DDIVU | (2 6), R6_OPC_DMODU = OPC_DDIVU | (3 6), + +R6_OPC_CLZ = 0x10 | OPC_SPECIAL, +R6_OPC_CLO = 0x11 | OPC_SPECIAL, +R6_OPC_DCLZ = 0x12 | OPC_SPECIAL, +R6_OPC_DCLO = 0x13 | OPC_SPECIAL, +R6_OPC_SDBBP= 0x0e | OPC_SPECIAL, }; /* Multiplication variants of the vr54xx. */ @@ -3263,19 +3269,23 @@ static void gen_cl (DisasContext *ctx, uint32_t opc, gen_load_gpr(t0, rs); switch (opc) { case OPC_CLO: +case R6_OPC_CLO: gen_helper_clo(cpu_gpr[rd], t0); opn = clo; break; case OPC_CLZ: +case R6_OPC_CLZ: gen_helper_clz(cpu_gpr[rd], t0); opn = clz; break; #if defined(TARGET_MIPS64) case OPC_DCLO: +case R6_OPC_DCLO: gen_helper_dclo(cpu_gpr[rd], t0); opn = dclo; break; case OPC_DCLZ: +case R6_OPC_DCLZ: gen_helper_dclz(cpu_gpr[rd], t0); opn = dclz; break; @@ -14747,12 +14757,13 @@ static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2, static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx) { -int rs, rt, rd; +int rs, rt, rd, sa; uint32_t op1, op2; rs = (ctx-opcode 21) 0x1f; rt = (ctx-opcode 16) 0x1f; rd = (ctx-opcode 11) 0x1f; +sa = (ctx-opcode 6) 0x1f; op1 = MASK_SPECIAL(ctx-opcode); switch (op1) { @@ -14779,7 +14790,31 @@ static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx) case OPC_SELNEZ: gen_cond_move(ctx, op1, rd, rs, rt); break; +case R6_OPC_CLO: +case R6_OPC_CLZ: +if (rt == 0 sa == 1) { +/* Major opcode and function field is shared with preR6 MFHI/MTHI. + We need additionally to check other fields */ +gen_cl(ctx, op1, rd, rs); +} else { +generate_exception(ctx, EXCP_RI); +} +break; +case R6_OPC_SDBBP: +generate_exception(ctx, EXCP_DBp); +break; #if defined(TARGET_MIPS64) +case R6_OPC_DCLO: +case R6_OPC_DCLZ: +if (rt == 0 sa == 1) { +/* Major opcode and function field is shared with preR6 MFHI/MTHI. + We need additionally to check other fields */ +check_mips_64(ctx); +gen_cl(ctx, op1, rd, rs); +} else { +generate_exception(ctx, EXCP_RI); +} +break; case OPC_DMULT ... OPC_DDIVU: op2 = MASK_R6_MULDIV(ctx-opcode); switch (op2) { @@ -14865,6 +14900,16 @@ static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx) gen_muldiv(ctx, op1, 0, rs, rt); break; #endif +case OPC_SPIM: +#ifdef MIPS_STRICT_STANDARD +MIPS_INVAL(SPIM); +generate_exception(ctx, EXCP_RI); +#else +/* Implemented as RI exception for now. */ +MIPS_INVAL(spim (unofficial)); +generate_exception(ctx, EXCP_RI); +#endif +break; default:/* Invalid */ MIPS_INVAL(special_legacy); generate_exception(ctx, EXCP_RI); @@ -14959,16 +15004,6 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) case OPC_BREAK: generate_exception(ctx, EXCP_BREAK); break; -case
[Qemu-devel] [PATCH v4 14/21] target-mips: add AUI, LSA and PCREL instruction families
Signed-off-by: Leon Alrae leon.al...@imgtec.com --- v3: * use sextract32 instead of open coding the bit field extraction * replace _i64 with _tl in DAHI, DATI and DAUI * fix misleading LDPC comment --- disas/mips.c| 42 ++- target-mips/translate.c | 197 +--- 2 files changed, 225 insertions(+), 14 deletions(-) diff --git a/disas/mips.c b/disas/mips.c index 8234369..091f4e2 100644 --- a/disas/mips.c +++ b/disas/mips.c @@ -407,6 +407,12 @@ struct mips_opcode +3 UDI immediate bits 6-20 +4 UDI immediate bits 6-25 + R6 immediates/displacements : + (adding suffix to 'o' to avoid adding new characters) + +o 9 bits immediate/displacement (shift = 7) + +o1 18 bits immediate/displacement (shift = 0) + +o2 19 bits immediate/displacement (shift = 0) + Other: () parens surrounding optional value , separates operands @@ -1217,6 +1223,17 @@ const struct mips_opcode mips_builtin_opcodes[] = them first. The assemblers uses a hash table based on the instruction name anyhow. */ /* name,args, match, mask, pinfo, membership */ +{lwpc,s,+o2,0xec08, 0xfc18, WR_d, 0, I32R6}, +{lwupc, s,+o2,0xec10, 0xfc18, WR_d, 0, I32R6}, +{ldpc,s,+o1,0xec18, 0xfc1c, WR_d, 0, I64R6}, +{addiupc, s,+o2,0xec00, 0xfc18, WR_d, 0, I32R6}, +{auipc, s,u, 0xec1e, 0xfc1f, WR_d, 0, I32R6}, +{aluipc, s,u, 0xec1f, 0xfc1f, WR_d, 0, I32R6}, +{daui,s,t,u,0x7400, 0xfc00, RD_s|WR_t,0, I64R6}, +{dahi,s,u, 0x0406, 0xfc1f, RD_s, 0, I64R6}, +{dati,s,u, 0x041e, 0xfc1f, RD_s, 0, I64R6}, +{lsa, d,s,t,0x0005, 0xfc00073f, WR_d|RD_s|RD_t, 0, I32R6}, +{dlsa,d,s,t,0x0015, 0xfc00073f, WR_d|RD_s|RD_t, 0, I64R6}, {clz, U,s, 0x0050, 0xfc1f07ff, WR_d|RD_s,0, I32R6}, {clo, U,s, 0x0051, 0xfc1f07ff, WR_d|RD_s,0, I32R6}, {dclz,U,s, 0x0052, 0xfc1f07ff, WR_d|RD_s,0, I64R6}, @@ -1822,6 +1839,7 @@ const struct mips_opcode mips_builtin_opcodes[] = {lld,t,o(b), 0xd000, 0xfc00, LDD|RD_b|WR_t, 0, I3 }, {lld, t,A(b), 0,(int) M_LLD_AB, INSN_MACRO, 0, I3 }, {lui, t,u, 0x3c00, 0xffe0, WR_t, 0, I1 }, +{aui, s,t,u,0x3c00, 0xfc00, RD_s|WR_t,0, I32R6}, {luxc1, D,t(b), 0x4c05, 0xfc00f83f, LDD|WR_D|RD_t|RD_b|FP_D, 0, I5|I33|N55}, {lw, t,o(b), 0x8c00, 0xfc00, LDD|RD_b|WR_t, 0, I1 }, {lw, t,A(b), 0,(int) M_LW_AB,INSN_MACRO, 0, I1 }, @@ -3645,10 +3663,28 @@ print_insn_args (const char *d, break; case 'o': -delta = (l OP_SH_DELTA_R6) OP_MASK_DELTA_R6; -if (delta 0x8000) { -delta |= ~0x; +switch (*(d+1)) { +case '1': +d++; +delta = l ((1 18) - 1); +if (delta 0x2) { +delta |= ~0x1; +} +break; +case '2': +d++; +delta = l ((1 19) - 1); +if (delta 0x4) { +delta |= ~0x3; +} +break; +default: +delta = (l OP_SH_DELTA_R6) OP_MASK_DELTA_R6; +if (delta 0x8000) { +delta |= ~0x; +} } + (*info-fprintf_func) (info-stream, %d, delta); break; diff --git a/target-mips/translate.c b/target-mips/translate.c index 06ececb..6f64c47 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -75,6 +75,7 @@ enum { OPC_BGTZ = (0x07 26), OPC_BGTZL= (0x17 26), OPC_JALX = (0x1D 26), /* MIPS 16 only */ +OPC_DAUI = (0x1D 26), OPC_JALXS= OPC_JALX | 0x5, /* Load and stores */ OPC_LDL = (0x1A 26), @@ -141,8 +142,25 @@ enum { /* Cache and prefetch */ OPC_CACHE= (0x2F 26), OPC_PREF = (0x33 26), -/* Reserved major opcode */ -OPC_MAJOR3B_RESERVED = (0x3B 26), +/* PC-relative address computation / loads */ +OPC_PCREL= (0x3B 26), +}; + +/* PC-relative address computation / loads */ +#define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op (3 19))) +#define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op (0x1f 16))) +enum { +
[Qemu-devel] [PATCH v4 06/21] target-mips: split decode_opc_special* into *_r6 and *_legacy
For better code readability and to avoid 'if' statements for all R6 and preR6 instructions whose opcodes are the same - decode_opc_special* functions are split into functions with _r6 and _legacy suffixes. *_r6 functions will contain instructions which were introduced in R6. *_legacy functions will contain instructions which were removed in R6. Signed-off-by: Leon Alrae leon.al...@imgtec.com Reviewed-by: Aurelien Jarno aurel...@aurel32.net --- v2: * imm contains shifted value --- target-mips/translate.c | 228 +--- 1 file changed, 160 insertions(+), 68 deletions(-) diff --git a/target-mips/translate.c b/target-mips/translate.c index 5b8f762..0c64aeb 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -14482,6 +14482,70 @@ static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2, /* End MIPSDSP functions. */ +static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx) +{ +int rs, rt, rd; +uint32_t op1; + +rs = (ctx-opcode 21) 0x1f; +rt = (ctx-opcode 16) 0x1f; +rd = (ctx-opcode 11) 0x1f; + +op1 = MASK_SPECIAL(ctx-opcode); +switch (op1) { +case OPC_SELEQZ: +case OPC_SELNEZ: +gen_cond_move(ctx, op1, rd, rs, rt); +break; +default:/* Invalid */ +MIPS_INVAL(special_r6); +generate_exception(ctx, EXCP_RI); +break; +} +} + +static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx) +{ +int rs, rt, rd; +uint32_t op1; + +rs = (ctx-opcode 21) 0x1f; +rt = (ctx-opcode 16) 0x1f; +rd = (ctx-opcode 11) 0x1f; + +op1 = MASK_SPECIAL(ctx-opcode); +switch (op1) { +case OPC_MOVN: /* Conditional move */ +case OPC_MOVZ: +check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 | + INSN_LOONGSON2E | INSN_LOONGSON2F); +gen_cond_move(ctx, op1, rd, rs, rt); +break; +case OPC_MFHI: /* Move from HI/LO */ +case OPC_MFLO: +gen_HILO(ctx, op1, rs 3, rd); +break; +case OPC_MTHI: +case OPC_MTLO: /* Move to HI/LO */ +gen_HILO(ctx, op1, rd 3, rs); +break; +case OPC_MOVCI: +check_insn(ctx, ISA_MIPS4 | ISA_MIPS32); +if (env-CP0_Config1 (1 CP0C1_FP)) { +check_cp1_enabled(ctx); +gen_movci(ctx, rd, rs, (ctx-opcode 18) 0x7, + (ctx-opcode 16) 1); +} else { +generate_exception_err(ctx, EXCP_CpU, 1); +} +break; +default:/* Invalid */ +MIPS_INVAL(special_legacy); +generate_exception(ctx, EXCP_RI); +break; +} +} + static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) { int rs, rt, rd, sa; @@ -14514,18 +14578,6 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) break; } break; -case OPC_MOVN: /* Conditional move */ -case OPC_MOVZ: -check_insn_opc_removed(ctx, ISA_MIPS32R6); -check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 | - INSN_LOONGSON2E | INSN_LOONGSON2F); -gen_cond_move(ctx, op1, rd, rs, rt); -break; -case OPC_SELEQZ: -case OPC_SELNEZ: -check_insn(ctx, ISA_MIPS32R6); -gen_cond_move(ctx, op1, rd, rs, rt); -break; case OPC_ADD ... OPC_SUBU: gen_arith(ctx, op1, rd, rs, rt); break; @@ -14580,16 +14632,6 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) case OPC_TNE: gen_trap(ctx, op1, rs, rt, -1); break; -case OPC_MFHI: /* Move from HI/LO */ -case OPC_MFLO: -check_insn_opc_removed(ctx, ISA_MIPS32R6); -gen_HILO(ctx, op1, rs 3, rd); -break; -case OPC_MTHI: -case OPC_MTLO: /* Move to HI/LO */ -check_insn_opc_removed(ctx, ISA_MIPS32R6); -gen_HILO(ctx, op1, rd 3, rs); -break; case OPC_PMON: /* Pmon entry point, also R4010 selsl */ #ifdef MIPS_STRICT_STANDARD MIPS_INVAL(PMON / selsl); @@ -14619,18 +14661,6 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) /* Treat as NOP. */ break; -case OPC_MOVCI: -check_insn_opc_removed(ctx, ISA_MIPS32R6); -check_insn(ctx, ISA_MIPS4 | ISA_MIPS32); -if (ctx-CP0_Config1 (1 CP0C1_FP)) { -check_cp1_enabled(ctx); -gen_movci(ctx, rd, rs, (ctx-opcode 18) 0x7, - (ctx-opcode 16) 1); -} else { -generate_exception_err(ctx, EXCP_CpU, 1); -} -break; - #if defined(TARGET_MIPS64) /* MIPS64 specific opcodes */ case OPC_DSLL: @@ -14712,14 +14742,29 @@ static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx) gen_muldiv(ctx, op1, 0, rs, rt); break; #endif +default: +if (ctx-insn_flags
[Qemu-devel] [PATCH v4 18/21] target-mips: do not allow Status.FR=0 mode in 64-bit FPU
Status.FR bit must be ignored on write and read as 1 when an implementation of Release 6 of the Architecture in which a 64-bit floating point unit is implemented. Signed-off-by: Leon Alrae leon.al...@imgtec.com Reviewed-by: Yongbok Kim yongbok@imgtec.com --- v3: * remove line modifying CP0_Status_rw_bitmask as this is done while defining CPU --- target-mips/translate.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/target-mips/translate.c b/target-mips/translate.c index 2edd36e..e5ae6b4 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -17951,6 +17951,12 @@ void cpu_state_reset(CPUMIPSState *env) } } #endif +if ((env-insn_flags ISA_MIPS32R6) +(env-active_fpu.fcr0 (1 FCR0_F64))) { +/* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */ +env-CP0_Status |= (1 CP0St_FR); +} + compute_hflags(env); cs-exception_index = EXCP_NONE; } -- 2.1.0
[Qemu-devel] [PATCH v4 21/21] target-mips: define a new generic CPU supporting MIPS64 Release 6 ISA
Signed-off-by: Leon Alrae leon.al...@imgtec.com --- v3: * add comment to make it clear that the current definition of MIPS64R6-generic CPU does not contain support for all MIPS64R6 features yet. --- target-mips/translate_init.c | 30 ++ 1 file changed, 30 insertions(+) diff --git a/target-mips/translate_init.c b/target-mips/translate_init.c index 29dc2ef..67b7837 100644 --- a/target-mips/translate_init.c +++ b/target-mips/translate_init.c @@ -516,6 +516,36 @@ static const mips_def_t mips_defs[] = .mmu_type = MMU_TYPE_R4000, }, { +/* A generic CPU supporting MIPS64 Release 6 ISA. + FIXME: It does not support all the MIPS64R6 features yet. + Eventually this should be replaced by a real CPU model. */ +.name = MIPS64R6-generic, +.CP0_PRid = 0x0001, +.CP0_Config0 = MIPS_CONFIG0 | (0x2 CP0C0_AR) | (0x2 CP0C0_AT) | + (MMU_TYPE_R4000 CP0C0_MT), +.CP0_Config1 = MIPS_CONFIG1 | (1 CP0C1_FP) | (63 CP0C1_MMU) | + (2 CP0C1_IS) | (4 CP0C1_IL) | (3 CP0C1_IA) | + (2 CP0C1_DS) | (4 CP0C1_DL) | (3 CP0C1_DA) | + (0 CP0C1_PC) | (1 CP0C1_WR) | (1 CP0C1_EP), +.CP0_Config2 = MIPS_CONFIG2, +.CP0_Config3 = MIPS_CONFIG3, +.CP0_LLAddr_rw_bitmask = 0, +.CP0_LLAddr_shift = 0, +.SYNCI_Step = 32, +.CCRes = 2, +.CP0_Status_rw_bitmask = 0x30D8, +.CP1_fcr0 = (1 FCR0_F64) | (1 FCR0_L) | (1 FCR0_W) | +(1 FCR0_D) | (1 FCR0_S) | (0x00 FCR0_PRID) | +(0x0 FCR0_REV), +.SEGBITS = 42, +/* The architectural limit is 59, but we have hardcoded 36 bit + in some places... +.PABITS = 59, */ /* the architectural limit */ +.PABITS = 36, +.insn_flags = CPU_MIPS64R6, +.mmu_type = MMU_TYPE_R4000, +}, +{ .name = Loongson-2E, .CP0_PRid = 0x6302, /*64KB I-cache and d-cache. 4 way with 32 bit cache line size*/ -- 2.1.0
[Qemu-devel] [PATCH v4 20/21] mips_malta: update malta's pseudo-bootloader - replace JR with JALR
JR has been removed in R6 and now this instruction will cause Reserved Instruction Exception. Therefore use JALR with rd=0 which is equivalent to JR. Signed-off-by: Leon Alrae leon.al...@imgtec.com Reviewed-by: Aurelien Jarno aurel...@aurel32.net --- hw/mips/mips_malta.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c index b20807c..e8e075c 100644 --- a/hw/mips/mips_malta.c +++ b/hw/mips/mips_malta.c @@ -697,12 +697,12 @@ static void write_bootloader (CPUMIPSState *env, uint8_t *base, /* Jump to kernel code */ stl_p(p++, 0x3c1f | ((kernel_entry 16) 0x));/* lui ra, high(kernel_entry) */ stl_p(p++, 0x37ff | (kernel_entry 0x));/* ori ra, ra, low(kernel_entry) */ -stl_p(p++, 0x03e8); /* jr ra */ +stl_p(p++, 0x03e9); /* jalr ra */ stl_p(p++, 0x); /* nop */ /* YAMON subroutines */ p = (uint32_t *) (base + 0x800); -stl_p(p++, 0x03e8); /* jr ra */ +stl_p(p++, 0x03e9); /* jalr ra */ stl_p(p++, 0x2402); /* li v0,0 */ /* 808 YAMON print */ stl_p(p++, 0x03e06821); /* move t5,ra */ @@ -716,7 +716,7 @@ static void write_bootloader (CPUMIPSState *env, uint8_t *base, stl_p(p++, 0x); /* nop */ stl_p(p++, 0x08000205); /* j 814 */ stl_p(p++, 0x); /* nop */ -stl_p(p++, 0x01a8); /* jr t5 */ +stl_p(p++, 0x01a9); /* jalr t5 */ stl_p(p++, 0x01602021); /* move a0,t3 */ /* 0x83c YAMON print_count */ stl_p(p++, 0x03e06821); /* move t5,ra */ @@ -730,7 +730,7 @@ static void write_bootloader (CPUMIPSState *env, uint8_t *base, stl_p(p++, 0x258c); /* addiu t4,t4,-1 */ stl_p(p++, 0x1580fffa); /* bnez t4,84c */ stl_p(p++, 0x); /* nop */ -stl_p(p++, 0x01a8); /* jr t5 */ +stl_p(p++, 0x01a9); /* jalr t5 */ stl_p(p++, 0x01602021); /* move a0,t3 */ /* 0x870 */ stl_p(p++, 0x3c08b800); /* lui t0,0xb400 */ @@ -740,7 +740,7 @@ static void write_bootloader (CPUMIPSState *env, uint8_t *base, stl_p(p++, 0x31290040); /* andi t1,t1,0x40 */ stl_p(p++, 0x1120fffc); /* beqz t1,878 outch+0x8 */ stl_p(p++, 0x); /* nop */ -stl_p(p++, 0x03e8); /* jr ra */ +stl_p(p++, 0x03e9); /* jalr ra */ stl_p(p++, 0xa104); /* sb a0,0(t0) */ } -- 2.1.0
Re: [Qemu-devel] [QA-virtio]:Why vring size is limited to 1024?
On 10/08/2014 01:55 PM, Michael S. Tsirkin wrote: Even more useful is getting rid of the desc array and instead passing descs inline in avail and used. You expect this to improve performance? Quite possibly but this will have to be demonstrated. The top vhost function in small packet workloads is vhost_get_vq_desc, and the top instruction within that (50%) is the one that reads the first 8 bytes of desc. It's a guaranteed cache line miss (and again on the guest side when it's time to reuse). OK so basically what you are pointing out is that we get 5 accesses: read of available head, read of available ring, read of descriptor, write of used ring, write of used ring head. Right. And only read of descriptor is not amortized. If processing is in-order, we could build a much simpler design, with a valid bit in the descriptor, cleared by host as descriptors are consumed. Basically get rid of both used and available ring. That only works if you don't allow reordering, which is never the case for block, and not the case for zero-copy net. It also has writers on both side of the ring. The right design is to keep avail and used, but instead of making them rings of pointers to descs, make them rings of descs. The host reads descs from avail, processes them, then writes them back on used (possibly out-of-order). The guest writes descs to avail and reads them back from used. You'll probably have to add a 64-bit cookie to desc so you can complete without an additional lookup. Sounds good in theory. Inline descriptors will amortize the cache miss over 4 descriptors, and will allow the hardware to prefetch, since the descriptors are linear in memory. If descriptors are used in order (as they are with current qemu) then aren't they amortized already?
[Qemu-devel] [PATCH v4 13/21] target-mips: add compact and CP1 branches
From: Yongbok Kim yongbok@imgtec.com Introduce MIPS32R6 Compact Branch instructions which do not have delay slot - they have forbidden slot instead. However, current implementation does not support forbidden slot yet. Add also BC1EQZ and BC1NEZ instructions. Signed-off-by: Yongbok Kim yongbok@imgtec.com Signed-off-by: Leon Alrae leon.al...@imgtec.com --- v3: * do not use setcond but generate conditional compact branch immediately * remove useless compact branch hflag as well as tcg_gen_mov_i64(t0, t0) * signal RI if new BC1* instructions are in delay slot * use sextract32 instead of SIMM macro v2: * rename handle_delay_slot to gen_branch * Compact branches generate branch straightaway * improve BOVC/BNVC, BC1EQZ, BC1NEZ implementation --- disas/mips.c| 67 ++- target-mips/translate.c | 473 ++-- 2 files changed, 523 insertions(+), 17 deletions(-) diff --git a/disas/mips.c b/disas/mips.c index 61313f4..8234369 100644 --- a/disas/mips.c +++ b/disas/mips.c @@ -1250,6 +1250,34 @@ const struct mips_opcode mips_builtin_opcodes[] = {dalign, d,v,t,0x7c000224, 0xfc00063f, WR_d|RD_s|RD_t, 0, I64R6}, {bitswap, d,w, 0x7c20, 0xffe007ff, WR_d|RD_t,0, I32R6}, {dbitswap,d,w, 0x7c24, 0xffe007ff, WR_d|RD_t,0, I64R6}, +{balc,+p, 0xe800, 0xfc00, UBD|WR_31,0, I32R6}, +{bc, +p, 0xc800, 0xfc00, UBD|WR_31,0, I32R6}, +{jic, t,o, 0xd800, 0xffe0, UBD|RD_t, 0, I32R6}, +{beqzc, s,+p, 0xd800, 0xfc00, CBD|RD_s, 0, I32R6}, +{jialc, t,o, 0xf800, 0xffe0, UBD|RD_t, 0, I32R6}, +{bnezc, s,+p, 0xf800, 0xfc00, CBD|RD_s, 0, I32R6}, +{beqzalc, s,t,p,0x2000, 0xffe0, CBD|RD_s|RD_t,0, I32R6}, +{bovc,s,t,p,0x2000, 0xfc00, CBD|RD_s|RD_t,0, I32R6}, +{beqc,s,t,p,0x2000, 0xfc00, CBD|RD_s|RD_t,0, I32R6}, +{bnezalc, s,t,p,0x6000, 0xffe0, CBD|RD_s|RD_t,0, I32R6}, +{bnvc,s,t,p,0x6000, 0xfc00, CBD|RD_s|RD_t,0, I32R6}, +{bnec,s,t,p,0x6000, 0xfc00, CBD|RD_s|RD_t,0, I32R6}, +{blezc, s,t,p,0x5800, 0xffe0, CBD|RD_s|RD_t,0, I32R6}, +{bgezc, s,t,p,0x5800, 0xfc00, CBD|RD_s|RD_t,0, I32R6}, +{bgec,s,t,p,0x5800, 0xfc00, CBD|RD_s|RD_t,0, I32R6}, +{bgtzc, s,t,p,0x5c00, 0xffe0, CBD|RD_s|RD_t,0, I32R6}, +{bltzc, s,t,p,0x5c00, 0xfc00, CBD|RD_s|RD_t,0, I32R6}, +{bltc,s,t,p,0x5c00, 0xfc00, CBD|RD_s|RD_t,0, I32R6}, +{blezalc, s,t,p,0x1800, 0xffe0, CBD|RD_s|RD_t,0, I32R6}, +{bgezalc, s,t,p,0x1800, 0xfc00, CBD|RD_s|RD_t,0, I32R6}, +{bgeuc, s,t,p,0x1800, 0xfc00, CBD|RD_s|RD_t,0, I32R6}, +{bgtzalc, s,t,p,0x1c00, 0xffe0, CBD|RD_s|RD_t,0, I32R6}, +{bltzalc, s,t,p,0x1c00, 0xfc00, CBD|RD_s|RD_t,0, I32R6}, +{bltuc, s,t,p,0x1c00, 0xfc00, CBD|RD_s|RD_t,0, I32R6}, +{bc1eqz, T,p, 0x4520, 0xffe0, CBD|RD_T|FP_S|FP_D, 0, I32R6}, +{bc1nez, T,p, 0x45a0, 0xffe0, CBD|RD_T|FP_S|FP_D, 0, I32R6}, +{bc2eqz, E,p, 0x4920, 0xffe0, CBD|RD_C2,0, I32R6}, +{bc2nez, E,p, 0x49a0, 0xffe0, CBD|RD_C2,0, I32R6}, {pref,k,o(b), 0xcc00, 0xfc00, RD_b, 0, I4|I32|G3 }, {prefx, h,t(b), 0x4c0f, 0xfc0007ff, RD_b|RD_t, 0, I4|I33 }, {nop, , 0x, 0x, 0, INSN2_ALIAS,I1 }, /* sll */ @@ -3616,6 +3644,24 @@ print_insn_args (const char *d, (*info-fprintf_func) (info-stream, 0x%x, msbd + 1); break; +case 'o': +delta = (l OP_SH_DELTA_R6) OP_MASK_DELTA_R6; +if (delta 0x8000) { +delta |= ~0x; +} +(*info-fprintf_func) (info-stream, %d, delta); +break; + +case 'p': +/* Sign extend the displacement with 26 bits. */ +delta = (l OP_SH_DELTA) OP_MASK_TARGET; +if (delta 0x200) { +delta |= ~0x3FF; +} +info-target = (delta 2) + pc + INSNLEN; +(*info-print_address_func) (info-target, info); +break; + case 't': /* Coprocessor 0 reg name */ (*info-fprintf_func) (info-stream, %s, mips_cp0_names[(l OP_SH_RT) @@ -3767,9 +3813,7 @@ print_insn_args (const char *d, case 'j': /* Same as i, but sign-extended. */ case 'o': -
Re: [Qemu-devel] [QA-virtio]:Why vring size is limited to 1024?
On 10/08/2014 01:55 PM, Michael S. Tsirkin wrote: Inline descriptors will amortize the cache miss over 4 descriptors, and will allow the hardware to prefetch, since the descriptors are linear in memory. If descriptors are used in order (as they are with current qemu) then aren't they amortized already? The descriptors are only in-order for non-zero-copy net. They are out of order for block and zero-copy net. (also, the guest has to be careful in how it allocates descriptors).
Re: [Qemu-devel] [PATCH v1 7/8] throttle: Add throttle group support
On Wed, Oct 08, 2014 at 02:53:38PM +0800, Fam Zheng wrote: Does this mean that after this series, all the throttle_states must be contained inside its own throttle group? If so, we could embed ThrottleGroup fields in ThrottleState. It's weird when a function called throttle_group_compare takes a parameter of ThrottleState pointer, and cast it back to ThrottleGroup with container_of. It's done like this to fullfill a design goal: the throttle should be reusable without the groups and any reference to block related stuff. So it's just a way to split the responsabilities. Best regards Benoît Thanks for reviewing. Fam
[Qemu-devel] [PATCH v4 17/21] target-mips: add new Floating Point Comparison instructions
From: Yongbok Kim yongbok@imgtec.com Signed-off-by: Yongbok Kim yongbok@imgtec.com Signed-off-by: Leon Alrae leon.al...@imgtec.com Reviewed-by: Aurelien Jarno aurel...@aurel32.net --- disas/mips.c| 44 +++ target-mips/helper.h| 27 +++ target-mips/op_helper.c | 111 ++ target-mips/translate.c | 206 +++- 4 files changed, 386 insertions(+), 2 deletions(-) diff --git a/disas/mips.c b/disas/mips.c index e34125c..9d13bc0 100644 --- a/disas/mips.c +++ b/disas/mips.c @@ -1317,6 +1317,50 @@ const struct mips_opcode mips_builtin_opcodes[] = {bc1nez, T,p, 0x45a0, 0xffe0, CBD|RD_T|FP_S|FP_D, 0, I32R6}, {bc2eqz, E,p, 0x4920, 0xffe0, CBD|RD_C2,0, I32R6}, {bc2nez, E,p, 0x49a0, 0xffe0, CBD|RD_C2,0, I32R6}, +{cmp.af.s, D,S,T, 0x4680, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6}, +{cmp.un.s, D,S,T, 0x4681, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6}, +{cmp.eq.s, D,S,T, 0x4682, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6}, +{cmp.ueq.s, D,S,T, 0x4683, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6}, +{cmp.lt.s, D,S,T, 0x4684, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6}, +{cmp.ult.s, D,S,T, 0x4685, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6}, +{cmp.le.s, D,S,T, 0x4686, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6}, +{cmp.ule.s, D,S,T, 0x4687, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6}, +{cmp.saf.s, D,S,T, 0x4688, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6}, +{cmp.sun.s, D,S,T, 0x4689, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6}, +{cmp.seq.s, D,S,T, 0x468a, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6}, +{cmp.sueq.s, D,S,T, 0x468b, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6}, +{cmp.slt.s, D,S,T, 0x468c, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6}, +{cmp.sult.s, D,S,T, 0x468d, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6}, +{cmp.sle.s, D,S,T, 0x468e, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6}, +{cmp.sule.s, D,S,T, 0x468f, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6}, +{cmp.or.s, D,S,T, 0x46800011, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6}, +{cmp.une.s, D,S,T, 0x46800012, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6}, +{cmp.ne.s, D,S,T, 0x46800013, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6}, +{cmp.sor.s, D,S,T, 0x46800019, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6}, +{cmp.sune.s, D,S,T, 0x4680001a, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6}, +{cmp.sne.s, D,S,T, 0x4680001b, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, I32R6}, +{cmp.af.d, D,S,T, 0x46a0, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6}, +{cmp.un.d, D,S,T, 0x46a1, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6}, +{cmp.eq.d, D,S,T, 0x46a2, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6}, +{cmp.ueq.d, D,S,T, 0x46a3, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6}, +{cmp.lt.d, D,S,T, 0x46a4, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6}, +{cmp.ult.d, D,S,T, 0x46a5, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6}, +{cmp.le.d, D,S,T, 0x46a6, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6}, +{cmp.ule.d, D,S,T, 0x46a7, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6}, +{cmp.saf.d, D,S,T, 0x46a8, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6}, +{cmp.sun.d, D,S,T, 0x46a9, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6}, +{cmp.seq.d, D,S,T, 0x46aa, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6}, +{cmp.sueq.d, D,S,T, 0x46ab, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6}, +{cmp.slt.d, D,S,T, 0x46ac, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6}, +{cmp.sult.d, D,S,T, 0x46ad, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6}, +{cmp.sle.d, D,S,T, 0x46ae, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6}, +{cmp.sule.d, D,S,T, 0x46af, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6}, +{cmp.or.d, D,S,T, 0x46a00011, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6}, +{cmp.une.d, D,S,T, 0x46a00012, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6}, +{cmp.ne.d, D,S,T, 0x46a00013, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6}, +{cmp.sor.d, D,S,T, 0x46a00019, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6}, +{cmp.sune.d, D,S,T, 0x46a0001a, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6}, +{cmp.sne.d, D,S,T, 0x46a0001b, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, I32R6}, {pref,k,o(b), 0xcc00, 0xfc00, RD_b, 0, I4|I32|G3 }, {prefx, h,t(b), 0x4c0f, 0xfc0007ff, RD_b|RD_t, 0, I4|I33 }, {nop, , 0x, 0x, 0, INSN2_ALIAS,I1 }, /* sll */ diff --git a/target-mips/helper.h b/target-mips/helper.h index 9020c7b..a127db5 100644 --- a/target-mips/helper.h +++ b/target-mips/helper.h @@ -304,6 +304,33 @@ FOP_PROTO(le) FOP_PROTO(ngt) #undef FOP_PROTO +#define FOP_PROTO(op) \ +DEF_HELPER_3(r6_cmp_d_ ## op, i64, env, i64, i64) \ +DEF_HELPER_3(r6_cmp_s_ ## op, i32, env,
Re: [Qemu-devel] [PATCH v11 00/34] modify boot order of guest, and take effect after rebooting
On 2014/10/7 16:00, Gonglei (Arei) wrote: From: Gonglei arei.gong...@huawei.com Changes since v10: 1. add handler for virtio-blk-pci/s390/ccw in PATCH 28. 2. add especial bootidnex setter/getter functions for usb-storage device in PATCH 29. 3. add bootindex qom property for nvma and ne2k_isa devices, avoid regrassion in PATCH 30. 4. change fprintf to error_report in bootdevice.c in PATCH 34. 5. rebase on the latest qemu master tree. 6. add 'Reviewed-by' in other patches. (Thanks, Gerd) Hi, Gerd Could you please review the v11 and consider to merge this series in your tree? I have no idea which maintainer can apply this series. It seems that only you and Eduardo interested in and reviewed this patch series at present. :( Any help will be appreciated! This patch series has crossed two versions of QEMU, now is the soft freeze period of qemu-2.2 again. Best regards, -Gonglei Changes since v9: - rework del_boot_device_path() for code sharing more better.(Gerd) Now, it has only one delete funciton, which work for update fw_cfg list both setting bootindex and hot-unplugging devices. Changes since v8: - fix wrong rebase on PATCH 14/30 and 15/30. Changes since v7: - IDE unit's value is set too later, so change IDE to not use device_add_bootindex_property(). IDE has its own getter/setter and a call to add_boot_device_path() on realize(). PATCH 25/30, 28/30 (Eduardo) - rewrite PATCH 5/30 using g_strcmp0. (Eduardo) - set 'ide_device_type_info.instance_init = ide_dev_instance_init' for all ide devices. PATCH 25/30 (Eduardo) - set 'scsi_device_type_info.instance_init = scsi_dev_instance_init' for all scsi devices. PATCH 24/30 - initialize bootindex property to -1 in device_add_bootindex_property, so there is no need to duplicate the call to init bootindex with -1 in all devices. (Gerd) Thanks for review! Changes since v6: - move all bootindex/boot-device code to a new file, named bootdevice.c. - introduce a getter/setter wrapper for all device. - call add_boot_device_path in setter bootindx callback function. - call del_boot_device_path in finalize bootindex qom callback function. - other bugfixes. Thanks for Eduardo's good suggestion! And other guys, thanks too! Changes since v5: rework by Gerd and Markus's suggestion(Thanks a lot): - Set/update bootindex on reset instead of realize/init. - Switch the property from qdev to qom, then use the set callback to also update the fw_cfg file. - using qom-set instead of 'set-bootindex' qmp interface, remove it. This is a huge change relative to the previous version. Changes since v4: - using error_setg() instead of qerror_report() in patch 1/8. - call del_boot_device_path() from device_finalize() instead of placing it into each individual device in patch 4/8. Changes since v3: - rework del_* and modify_* function, because of virtio devices' specialation. For example, virtio-net's id is NULL, and its parent virtio-net-pci's id was assigned. Though the global fw_boot_order stored the virtio-net device. - call dell_boot_device_path in each individual device avoiding waste resouce. - introduce qmp query-bootindex command - introcude hmp info bootindex command - Fixes by Eric's reviewing comments, thanks. Changes since v2: *address Gerd's reviewing suggestion: - use the old entry's suffix, if the caller do not pass it in. - call del_boot_device_path() from device_finalize() instead of placing it into each individual device. Changes since v1: *rework by Gerd's suggestion: - split modify and del fw_boot_order for single function. - change modify bootindex's realization which simply lookup the device and modify the bootindex. if the new bootindex has already used by another device just throw an error. - change to del_boot_device_path(DeviceState *dev) and simply delete all entries belonging to the device. Sometimes, we want to modify boot order of a guest, but no need to shutdown it. We can call dynamic changing bootindex of a guest, which can be assured taking effect just after the guest rebooting. For example, in P2V scene, we boot a guest and then attach a new system disk, for copying some thing. We want to assign the new disk as the booting disk, which means its bootindex=1. Different nics can be assigen different bootindex dynamically also make sense. This patch series do belows works: 1. add an fw_cfg_machine_reset() assure re-read global fw_boot_order list during vm rebooting. 2. switch the property from qdev to qom, then use the set callback to also update the fw_cfg file. Note: - Do not support change pci option rom's bootindex. For Convenience of testing, my test case based on Andreas's patch series: [PATCH qom-next 0/4] qom: HMP commands to replace info qtree http://thread.gmane.org/gmane.comp.emulators.qemu/271513 However,
[Qemu-devel] qemu drive-mirror to rbd storage : no sparse rbd image
Hi, I'm currently planning to migrate our storage to ceph/rbd through qemu drive-mirror and It seem that drive-mirror with rbd block driver, don't create a sparse image. (all zeros are copied to the target rbd). Also note, that it's working fine with qemu-img convert , the rbd volume is sparse after conversion. Could it be related to the bdrv_co_write_zeroes missing features in block/rbd.c ? (It's available in other block drivers (scsi,gluster,raw-aio) , and I don't have this problem with theses block drivers). Regards, Alexandre Derumier
[Qemu-devel] [PATCH 3/3] qemu-sockets: Add error to non-blocking connect handler
From: Corey Minyard cminy...@mvista.com An error value here would be quite handy and more consistent with the rest of the code. Corey Minyard cminy...@mvista.com --- include/qemu/sockets.h | 2 +- migration-tcp.c| 4 ++-- migration-unix.c | 4 ++-- qemu-char.c| 6 +++--- util/qemu-sockets.c| 19 ++- 5 files changed, 22 insertions(+), 13 deletions(-) diff --git a/include/qemu/sockets.h b/include/qemu/sockets.h index fdbb196..f47dae6 100644 --- a/include/qemu/sockets.h +++ b/include/qemu/sockets.h @@ -47,7 +47,7 @@ int recv_all(int fd, void *buf, int len1, bool single_read); /* callback function for nonblocking connect * valid fd on success, negative error code on failure */ -typedef void NonBlockingConnectHandler(int fd, void *opaque); +typedef void NonBlockingConnectHandler(int fd, Error *errp, void *opaque); InetSocketAddress *inet_parse(const char *str, Error **errp); int inet_listen_opts(QemuOpts *opts, int port_offset, Error **errp); diff --git a/migration-tcp.c b/migration-tcp.c index 2e34517..91c9cf3 100644 --- a/migration-tcp.c +++ b/migration-tcp.c @@ -33,12 +33,12 @@ do { } while (0) #endif -static void tcp_wait_for_connect(int fd, void *opaque) +static void tcp_wait_for_connect(int fd, Error *err, void *opaque) { MigrationState *s = opaque; if (fd 0) { -DPRINTF(migrate connect error\n); +DPRINTF(migrate connect error: %s\n, error_get_pretty(err)); s-file = NULL; migrate_fd_error(s); } else { diff --git a/migration-unix.c b/migration-unix.c index 0a5f8a1..1cdadfb 100644 --- a/migration-unix.c +++ b/migration-unix.c @@ -33,12 +33,12 @@ do { } while (0) #endif -static void unix_wait_for_connect(int fd, void *opaque) +static void unix_wait_for_connect(int fd, Error *err, void *opaque) { MigrationState *s = opaque; if (fd 0) { -DPRINTF(migrate connect error\n); +DPRINTF(migrate connect error: %s\n, error_get_pretty(err)); s-file = NULL; migrate_fd_error(s); } else { diff --git a/qemu-char.c b/qemu-char.c index 83ff458..8f3af06 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -3061,14 +3061,14 @@ static void qemu_chr_finish_socket_connection(CharDriverState *chr, int fd) } } -static void qemu_chr_socket_connected(int fd, void *opaque) +static void qemu_chr_socket_connected(int fd, Error *err, void *opaque) { CharDriverState *chr = opaque; TCPCharDriver *s = chr-opaque; if (fd 0) { -check_report_connect_error(chr, Unable to connect to socket %s, - chr-label); +check_report_connect_error(chr, Unable to connect to socket %s: %s, + chr-label, error_get_pretty(err)); return; } diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c index 1eef590..e6a9644 100644 --- a/util/qemu-sockets.c +++ b/util/qemu-sockets.c @@ -234,6 +234,7 @@ static void wait_for_connect(void *opaque) int val = 0, rc = 0; socklen_t valsize = sizeof(val); bool in_progress; +Error *err = NULL; qemu_set_fd_handler2(s-fd, NULL, NULL, NULL, NULL); @@ -248,6 +249,7 @@ static void wait_for_connect(void *opaque) /* connect error */ if (rc 0) { +error_setg_errno(err, errno, Error connecting to socket); closesocket(s-fd); s-fd = rc; } @@ -257,9 +259,14 @@ static void wait_for_connect(void *opaque) while (s-current_addr-ai_next != NULL s-fd 0) { s-current_addr = s-current_addr-ai_next; s-fd = inet_connect_addr(s-current_addr, in_progress, s, NULL); +if (s-fd 0) { +error_free(err); +err = NULL; +error_setg_errno(err, errno, Unable to start socket connect); +} /* connect in progress */ if (in_progress) { -return; +goto out; } } @@ -267,9 +274,11 @@ static void wait_for_connect(void *opaque) } if (s-callback) { -s-callback(s-fd, s-opaque); +s-callback(s-fd, err, s-opaque); } g_free(s); +out: +error_free(err); } static int inet_connect_addr(struct addrinfo *addr, bool *in_progress, @@ -401,7 +410,7 @@ int inet_connect_opts(QemuOpts *opts, Error **errp, return sock; } else { if (callback) { -callback(sock, opaque); +callback(sock, NULL, opaque); } } g_free(connect_state); @@ -769,7 +778,7 @@ int unix_connect_opts(QemuOpts *opts, Error **errp, } else if (rc = 0) { /* non blocking socket immediate success, call callback */ if (callback != NULL) { -callback(sock, opaque); +callback(sock, NULL, opaque); } } @@ -919,7 +928,7 @@ int socket_connect(SocketAddress *addr, Error **errp, fd = monitor_get_fd(cur_mon,
[Qemu-devel] [PATCH 1/3] qemu-error: Add error_vreport()
From: Corey Minyard cminy...@mvista.com Needed to nicely print socket error reports. Signed-off-by: Corey Minyard cminy...@mvista.com --- include/qemu/error-report.h | 1 + util/qemu-error.c | 23 ++- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/include/qemu/error-report.h b/include/qemu/error-report.h index 000eae3..7ab2355 100644 --- a/include/qemu/error-report.h +++ b/include/qemu/error-report.h @@ -38,6 +38,7 @@ void error_vprintf(const char *fmt, va_list ap) GCC_FMT_ATTR(1, 0); void error_printf(const char *fmt, ...) GCC_FMT_ATTR(1, 2); void error_printf_unless_qmp(const char *fmt, ...) GCC_FMT_ATTR(1, 2); void error_set_progname(const char *argv0); +void error_vreport(const char *fmt, va_list ap) GCC_FMT_ATTR(1, 0); void error_report(const char *fmt, ...) GCC_FMT_ATTR(1, 2); const char *error_get_progname(void); extern bool enable_timestamp_msg; diff --git a/util/qemu-error.c b/util/qemu-error.c index 7b167fd..9bba5f5 100644 --- a/util/qemu-error.c +++ b/util/qemu-error.c @@ -199,14 +199,13 @@ static void error_print_loc(void) bool enable_timestamp_msg; /* * Print an error message to current monitor if we have one, else to stderr. - * Format arguments like sprintf(). The result should not contain + * Format arguments like vsprintf(). The result should not contain * newlines. * Prepend the current location and append a newline. * It's wrong to call this in a QMP monitor. Use qerror_report() there. */ -void error_report(const char *fmt, ...) +void error_vreport(const char *fmt, va_list ap) { -va_list ap; GTimeVal tv; gchar *timestr; @@ -218,8 +217,22 @@ void error_report(const char *fmt, ...) } error_print_loc(); -va_start(ap, fmt); error_vprintf(fmt, ap); -va_end(ap); error_printf(\n); } + +/* + * Print an error message to current monitor if we have one, else to stderr. + * Format arguments like sprintf(). The result should not contain + * newlines. + * Prepend the current location and append a newline. + * It's wrong to call this in a QMP monitor. Use qerror_report() there. + */ +void error_report(const char *fmt, ...) +{ +va_list ap; + +va_start(ap, fmt); +error_vreport(fmt, ap); +va_end(ap); +} -- 1.8.3.1
[Qemu-devel] [PATCH 2/3] qemu-char: Fix reconnect socket error reporting
From: Corey Minyard cminy...@mvista.com If reconnect was set, errors wouldn't always be reported. Fix that and also only report a connect error once until a connection has been made. The primary purpose of this is to tell the user that a connection failed so they can know they need to figure out what went wrong. So we don't want to spew too much out here, just enough so they know. Signed-off-by: Corey Minyard cminy...@mvista.com --- qemu-char.c | 57 ++--- 1 file changed, 42 insertions(+), 15 deletions(-) diff --git a/qemu-char.c b/qemu-char.c index 62af0ef..83ff458 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -2509,6 +2509,7 @@ typedef struct { guint reconnect_timer; int64_t reconnect_time; +bool connect_err_reported; } TCPCharDriver; static gboolean socket_reconnect_timeout(gpointer opaque); @@ -2521,6 +2522,24 @@ static void qemu_chr_socket_restart_timer(CharDriverState *chr) socket_reconnect_timeout, chr); } +static void check_report_connect_error(CharDriverState *chr, + const char *fmt, ...) GCC_FMT_ATTR(2, 3); + +static void check_report_connect_error(CharDriverState *chr, + const char *fmt, ...) +{ +TCPCharDriver *s = chr-opaque; + +if (!s-connect_err_reported) { +va_list ap; +va_start(ap, fmt); +error_vreport(fmt, ap); +va_end(ap); +s-connect_err_reported = true; +} +qemu_chr_socket_restart_timer(chr); +} + static gboolean tcp_chr_accept(GIOChannel *chan, GIOCondition cond, void *opaque); #ifndef _WIN32 @@ -3045,12 +3064,15 @@ static void qemu_chr_finish_socket_connection(CharDriverState *chr, int fd) static void qemu_chr_socket_connected(int fd, void *opaque) { CharDriverState *chr = opaque; +TCPCharDriver *s = chr-opaque; if (fd 0) { -qemu_chr_socket_restart_timer(chr); +check_report_connect_error(chr, Unable to connect to socket %s, + chr-label); return; } +s-connect_err_reported = false; qemu_chr_finish_socket_connection(chr, fd); } @@ -4066,11 +4088,21 @@ static CharDriverState *qmp_chardev_open_parallel(ChardevHostdev *parallel, #endif /* WIN32 */ +static void socket_try_connect(CharDriverState *chr) +{ +Error *err = NULL; + +if (!qemu_chr_open_socket_fd(chr, err)) { +check_report_connect_error(chr, + Unable to start connect to socket %s: %s, + chr-label, error_get_pretty(err)); +} +} + static gboolean socket_reconnect_timeout(gpointer opaque) { CharDriverState *chr = opaque; TCPCharDriver *s = chr-opaque; -Error *err; s-reconnect_timer = 0; @@ -4078,10 +4110,7 @@ static gboolean socket_reconnect_timeout(gpointer opaque) return false; } -if (!qemu_chr_open_socket_fd(chr, err)) { -error_report(Unable to connect to char device %s\n, chr-label); -qemu_chr_socket_restart_timer(chr); -} +socket_try_connect(chr); return false; } @@ -4133,15 +4162,13 @@ static CharDriverState *qmp_chardev_open_socket(ChardevSocket *sock, s-reconnect_time = reconnect; } -if (!qemu_chr_open_socket_fd(chr, errp)) { -if (s-reconnect_time) { -qemu_chr_socket_restart_timer(chr); -} else { -g_free(s); -g_free(chr-filename); -g_free(chr); -return NULL; -} +if (s-reconnect_time) { +socket_try_connect(chr); +} else if (!qemu_chr_open_socket_fd(chr, errp)) { +g_free(s); +g_free(chr-filename); +g_free(chr); +return NULL; } if (is_listen is_waitconnect) { -- 1.8.3.1
Re: [Qemu-devel] [PATCH v3] pc-dimm/numa: Fix stat of memory size in node when hotplug memory
On Wed, 8 Oct 2014 16:36:25 +0800 zhanghailiang zhang.zhanghaili...@huawei.com wrote: On 2014/10/8 15:28, zhanghailiang wrote: Hi Igor, On 2014/9/26 19:53, Igor Mammedov wrote: On Tue, 23 Sep 2014 16:11:25 +0800 zhanghailiang zhang.zhanghaili...@huawei.com wrote: When do memory hotplug, if there is numa node, we should add the memory size to the corresponding node memory size. For now, it mainly affects the result of hmp command info numa. Signed-off-by: zhanghailiang zhang.zhanghaili...@huawei.com please make sure that this doesn't breaks other targets. PS: to make test builds you can use travis-ci.org+github service Sorry for the delayed response.;) I have test the build as you suggested, and yes, it will break other targets. The main reason here is, there is a compile switch for memory hotplug (CONFIG_MEM_HOTPLUG), which is off for other targets, and pc-dimm.c is not include when compile. Here i also use the compile switch to fix this problem, and will send V4. ): Actually this macro (CONFIG_MEM_HOTPLUG) can't be automatically generated like CONFIG_KVM in config-target.h, so i can't use this compile macro. What's your suggestion? Thanks! typically we add stab function in such cases. However looking at pc_dimm_stat_node_mem() it does nothing that requires access to PCDIMMDevice, i.e. size and node could be accessed as properties of Device/Object. I'd suggest to generalize pc_dimm_stat_node_mem() so it could in future handle other types of memory devices and place it in numa.c, but for now looking only for TYPE_PC_DIMM devices. PS: s/pc_dimm_stat_node_mem/numa_stat_memory_devices/ zhanghailiang --- v3: - cold-plugged memory should not be excluded when stat memory size (Igor Mammedov) v2: - Don't modify the numa_info.node_mem directly when treating hotplug memory, fix the info numa instead (suggested by Igor Mammedov) --- hw/mem/pc-dimm.c | 30 ++ include/hw/mem/pc-dimm.h | 2 ++ include/sysemu/sysemu.h | 1 + monitor.c| 6 +- numa.c | 15 +++ 5 files changed, 53 insertions(+), 1 deletion(-) diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c index 5bfc5b7..8e80d74 100644 --- a/hw/mem/pc-dimm.c +++ b/hw/mem/pc-dimm.c @@ -195,6 +195,36 @@ out: return ret; } +static int pc_dimm_stat_mem_size(Object *obj, void *opaque) +{ +uint64_t *node_mem = opaque; +int ret; + +if (object_dynamic_cast(obj, TYPE_PC_DIMM)) { +DeviceState *dev = DEVICE(obj); + +if (dev-realized) { +PCDIMMDevice *dimm = PC_DIMM(obj); +int size; + +size = object_property_get_int(OBJECT(dimm), PC_DIMM_SIZE_PROP, + NULL); +if (size 0) { +return -1; +} +node_mem[dimm-node] += size; +} +} + +ret = object_child_foreach(obj, pc_dimm_stat_mem_size, opaque); +return ret; +} + +void pc_dimm_stat_node_mem(uint64_t *node_mem) +{ +object_child_foreach(qdev_get_machine(), pc_dimm_stat_mem_size, node_mem); +} + static Property pc_dimm_properties[] = { DEFINE_PROP_UINT64(PC_DIMM_ADDR_PROP, PCDIMMDevice, addr, 0), DEFINE_PROP_UINT32(PC_DIMM_NODE_PROP, PCDIMMDevice, node, 0), diff --git a/include/hw/mem/pc-dimm.h b/include/hw/mem/pc-dimm.h index 761eeef..0c9a8eb 100644 --- a/include/hw/mem/pc-dimm.h +++ b/include/hw/mem/pc-dimm.h @@ -78,4 +78,6 @@ uint64_t pc_dimm_get_free_addr(uint64_t address_space_start, int pc_dimm_get_free_slot(const int *hint, int max_slots, Error **errp); int qmp_pc_dimm_device_list(Object *obj, void *opaque); + +void pc_dimm_stat_node_mem(uint64_t *node_mem); #endif diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h index d8539fd..cfc1592 100644 --- a/include/sysemu/sysemu.h +++ b/include/sysemu/sysemu.h @@ -160,6 +160,7 @@ typedef struct node_info { extern NodeInfo numa_info[MAX_NODES]; void set_numa_nodes(void); void set_numa_modes(void); +int query_numa_node_mem(uint64_t *node_mem); extern QemuOptsList qemu_numa_opts; int numa_init_func(QemuOpts *opts, void *opaque); diff --git a/monitor.c b/monitor.c index 7467521..c8c812f 100644 --- a/monitor.c +++ b/monitor.c @@ -1948,7 +1948,10 @@ static void do_info_numa(Monitor *mon, const QDict *qdict) { int i; CPUState *cpu; +uint64_t *node_mem; +node_mem = g_new0(uint64_t, nb_numa_nodes); +query_numa_node_mem(node_mem); monitor_printf(mon, %d nodes\n, nb_numa_nodes); for (i = 0; i nb_numa_nodes; i++) { monitor_printf(mon, node %d cpus:, i); @@ -1959,8 +1962,9 @@ static void do_info_numa(Monitor *mon, const QDict *qdict) }
Re: [Qemu-devel] [QA-virtio]:Why vring size is limited to 1024?
On Wed, Oct 08, 2014 at 01:59:13PM +0300, Avi Kivity wrote: On 10/08/2014 01:55 PM, Michael S. Tsirkin wrote: Even more useful is getting rid of the desc array and instead passing descs inline in avail and used. You expect this to improve performance? Quite possibly but this will have to be demonstrated. The top vhost function in small packet workloads is vhost_get_vq_desc, and the top instruction within that (50%) is the one that reads the first 8 bytes of desc. It's a guaranteed cache line miss (and again on the guest side when it's time to reuse). OK so basically what you are pointing out is that we get 5 accesses: read of available head, read of available ring, read of descriptor, write of used ring, write of used ring head. Right. And only read of descriptor is not amortized. If processing is in-order, we could build a much simpler design, with a valid bit in the descriptor, cleared by host as descriptors are consumed. Basically get rid of both used and available ring. That only works if you don't allow reordering, which is never the case for block, and not the case for zero-copy net. It also has writers on both side of the ring. The right design is to keep avail and used, but instead of making them rings of pointers to descs, make them rings of descs. The host reads descs from avail, processes them, then writes them back on used (possibly out-of-order). The guest writes descs to avail and reads them back from used. You'll probably have to add a 64-bit cookie to desc so you can complete without an additional lookup. My old presentation from 2012 or so suggested something like this. We don't need a 64 bit cookie I think - a small 16 bit one should be enough. Sounds good in theory. Inline descriptors will amortize the cache miss over 4 descriptors, and will allow the hardware to prefetch, since the descriptors are linear in memory. If descriptors are used in order (as they are with current qemu) then aren't they amortized already?
Re: [Qemu-devel] [PATCH V4 5/8] pc: Update rtc_cmos in pc_cpu_plug
On Wed, 8 Oct 2014 09:12:11 +0800 Gu Zheng guz.f...@cn.fujitsu.com wrote: Hi Igor, On 10/07/2014 09:01 PM, Igor Mammedov wrote: On Mon, 29 Sep 2014 18:52:34 +0800 Gu Zheng guz.f...@cn.fujitsu.com wrote: Update rtc_cmos in pc_cpu_plug directly instead of the notifier. v4: -Make linkrtc property in PCMachine rather than the global variables. -Split out the removal of unused notifier into separate patch. Signed-off-by: Gu Zheng guz.f...@cn.fujitsu.com --- hw/i386/pc.c | 37 - hw/i386/pc_piix.c|2 +- hw/i386/pc_q35.c |2 +- include/hw/i386/pc.h |3 ++- qom/cpu.c|1 - 5 files changed, 20 insertions(+), 25 deletions(-) diff --git a/hw/i386/pc.c b/hw/i386/pc.c index dcb9332..301e704 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -355,30 +355,15 @@ static void pc_cmos_init_late(void *opaque) qemu_unregister_reset(pc_cmos_init_late, opaque); } -typedef struct RTCCPUHotplugArg { -Notifier cpu_added_notifier; -ISADevice *rtc_state; -} RTCCPUHotplugArg; - -static void rtc_notify_cpu_added(Notifier *notifier, void *data) -{ -RTCCPUHotplugArg *arg = container_of(notifier, RTCCPUHotplugArg, - cpu_added_notifier); -ISADevice *s = arg-rtc_state; - -/* increment the number of CPUs */ -rtc_set_memory(s, 0x5f, rtc_get_memory(s, 0x5f) + 1); -} - void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size, - const char *boot_device, + const char *boot_device, MachineState *machine, ISADevice *floppy, BusState *idebus0, BusState *idebus1, ISADevice *s) { int val, nb, i; FDriveType fd_type[2] = { FDRIVE_DRV_NONE, FDRIVE_DRV_NONE }; static pc_cmos_init_late_arg arg; -static RTCCPUHotplugArg cpu_hotplug_cb; +PCMachineState *pc_machine = PC_MACHINE(machine); /* various important CMOS locations needed by PC/Bochs bios */ @@ -417,10 +402,14 @@ void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size, /* set the number of CPU */ rtc_set_memory(s, 0x5f, smp_cpus - 1); -/* init CPU hotplug notifier */ -cpu_hotplug_cb.rtc_state = s; -cpu_hotplug_cb.cpu_added_notifier.notify = rtc_notify_cpu_added; -qemu_register_cpu_added_notifier(cpu_hotplug_cb.cpu_added_notifier); + +object_property_add_link(OBJECT(machine), rtc_state, + TYPE_ISA_DEVICE, + (Object **)pc_machine-rtc, + object_property_allow_set_link, + OBJ_PROP_LINK_UNREF_ON_RELEASE, error_abort); +object_property_set_link(OBJECT(machine), OBJECT(s), + rtc_state, error_abort); if (set_boot_dev(s, boot_device)) { exit(1); @@ -1633,6 +1622,12 @@ static void pc_cpu_plug(HotplugHandler *hotplug_dev, hhc = HOTPLUG_HANDLER_GET_CLASS(pcms-acpi_dev); hhc-plug(HOTPLUG_HANDLER(pcms-acpi_dev), dev, local_err); +if (local_err) { +goto out; +} + +/* increment the number of CPUs */ +rtc_set_memory(pcms-rtc, 0x5f, rtc_get_memory(pcms-rtc, 0x5f) + 1); out: error_propagate(errp, local_err); } diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index 103d756..2c8d4dc 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -266,7 +266,7 @@ static void pc_init1(MachineState *machine, } pc_cmos_init(below_4g_mem_size, above_4g_mem_size, machine-boot_order, - floppy, idebus[0], idebus[1], rtc_state); + machine, floppy, idebus[0], idebus[1], rtc_state); if (pci_enabled usb_enabled(false)) { pci_create_simple(pci_bus, piix3_devfn + 2, piix3-usb-uhci); diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index d4a907c..94ba98d 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -266,7 +266,7 @@ static void pc_q35_init(MachineState *machine) 8, NULL, 0); pc_cmos_init(below_4g_mem_size, above_4g_mem_size, machine-boot_order, - floppy, idebus[0], idebus[1], rtc_state); + machine, floppy, idebus[0], idebus[1], rtc_state); /* the rest devices to which pci devfn is automatically assigned */ pc_vga_init(isa_bus, host_bus); diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 77316d5..7a4bff4 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -33,6 +33,7 @@ struct PCMachineState { MemoryRegion hotplug_memory; HotplugHandler *acpi_dev; +ISADevice *rtc; uint64_t max_ram_below_4g; }; @@ -210,7 +211,7 @@ void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi,
Re: [Qemu-devel] Memory hotplug and ancient kernels
On Thu, 2 Oct 2014 18:38:33 +0400 Andrey Korolyov and...@xdel.ru wrote: Hi, with kernel with an obsolete version ( 3.8) DIMM configuration is not working as defined in a boot-up values, though it is possible to add dimm during runtime and it will be recognized just well. ACPI tables and the of DMI for kernels which are recognizing on-boot modules and for ones which are not are the same and I am barely remembering that some changes related to memory hotplug mechanism was landed in 3.8. Given following configuration, dimm2 is plugged during current boot cycle of Centos 2.6.32 kernel: '{ execute: query-memory-devices}' {return:[{type:dimm,data:{memdev:/objects/mem0,hotplugged:false,addr:4294967296,hotpluggable:true,size:134217728,slot:0,node:0,id:dimm0}},{type:dimm,data:{memdev:/objects/mem1,hotplugged:true,addr:4429185024,hotpluggable:true,size:134217728,slot:1,node:0,id:dimm1}},{type:dimm,data:{memdev:/objects/mem2,hotplugged:true,addr:4563402752,hotpluggable:true,size:134217728,slot:2,node:0,id:dimm2}}],id:libvirt-16} Hotplug Mem Device init_memory_mapping: 00011000-00011800 011000 - 011800 page 2M [ea0003b8-ea0003d7] PMD - [88001d60-88001d7f] on node 0 Built 1 zonelists in Node order, mobility grouping on. Total pages: 160734 Policy zone: Normal ls /sys/devices/system/memory/| grep mem memory0 memory1 memory2 memory3 memory34 Looks like a bug. I've just opened RHBZ 1150510 for tracking it. ..Rebooting to 3.10.. ls /sys/devices/system/memory/| grep mem memory0 memory1 memory2 memory3 memory32 memory33 memory34 The results are based on tag-2.1.2 without any modifications.
Re: [Qemu-devel] [QA-virtio]:Why vring size is limited to 1024?
On 10/08/2014 03:22 PM, Michael S. Tsirkin wrote: On Wed, Oct 08, 2014 at 01:59:13PM +0300, Avi Kivity wrote: On 10/08/2014 01:55 PM, Michael S. Tsirkin wrote: Even more useful is getting rid of the desc array and instead passing descs inline in avail and used. You expect this to improve performance? Quite possibly but this will have to be demonstrated. The top vhost function in small packet workloads is vhost_get_vq_desc, and the top instruction within that (50%) is the one that reads the first 8 bytes of desc. It's a guaranteed cache line miss (and again on the guest side when it's time to reuse). OK so basically what you are pointing out is that we get 5 accesses: read of available head, read of available ring, read of descriptor, write of used ring, write of used ring head. Right. And only read of descriptor is not amortized. If processing is in-order, we could build a much simpler design, with a valid bit in the descriptor, cleared by host as descriptors are consumed. Basically get rid of both used and available ring. That only works if you don't allow reordering, which is never the case for block, and not the case for zero-copy net. It also has writers on both side of the ring. The right design is to keep avail and used, but instead of making them rings of pointers to descs, make them rings of descs. The host reads descs from avail, processes them, then writes them back on used (possibly out-of-order). The guest writes descs to avail and reads them back from used. You'll probably have to add a 64-bit cookie to desc so you can complete without an additional lookup. My old presentation from 2012 or so suggested something like this. We don't need a 64 bit cookie I think - a small 16 bit one should be enough. A 16 bit cookie means you need an extra table to hold the real request pointers. With a 64-bit cookie you can store a pointer to the skbuff or bio in the ring itself, and avoid the extra lookup. The extra lookup isn't the end of the world, since doesn't cross core boundaries, but it's worth avoiding.
Re: [Qemu-devel] [PATCH V4 8/8] acpi/cpu-hotplug: introduce help function to keep bit setting in one place
On Mon, 29 Sep 2014 18:52:37 +0800 Gu Zheng guz.f...@cn.fujitsu.com wrote: Introduce help function acpi_set_local_sts() to simplify acpi_cpu_plug_cb s/help/helper/ and acpi_cpu_hotplug_init, so that we can keep bit setting in one place. Signed-off-by: Gu Zheng guz.f...@cn.fujitsu.com --- hw/acpi/cpu_hotplug.c | 23 +++ 1 files changed, 15 insertions(+), 8 deletions(-) diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c index ae48b63..8ff8c4d 100644 --- a/hw/acpi/cpu_hotplug.c +++ b/hw/acpi/cpu_hotplug.c @@ -36,10 +36,9 @@ static const MemoryRegionOps AcpiCpuHotplug_ops = { }, }; -void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq, - AcpiCpuHotplug *g, DeviceState *dev, Error **errp) +static void acpi_set_local_sts(AcpiCpuHotplug *g, CPUState *cpu, + Error **errp) Maybe better would be: s/acpi_set_local_sts/acpi_set_cpu_present_bit/ { -CPUState *cpu = CPU(dev); CPUClass *k = CPU_GET_CLASS(cpu); int64_t cpu_id; @@ -49,9 +48,18 @@ void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq, return; } -ar-gpe.sts[0] |= ACPI_CPU_HOTPLUG_STATUS; g-sts[cpu_id / 8] |= (1 (cpu_id % 8)); +} +void acpi_cpu_plug_cb(ACPIREGS *ar, qemu_irq irq, + AcpiCpuHotplug *g, DeviceState *dev, Error **errp) +{ +acpi_set_local_sts(g, CPU(dev), errp); +if (*errp != NULL) { +return; +} + +ar-gpe.sts[0] |= ACPI_CPU_HOTPLUG_STATUS; acpi_update_sci(ar, irq); } @@ -61,11 +69,10 @@ void acpi_cpu_hotplug_init(MemoryRegion *parent, Object *owner, CPUState *cpu; CPU_FOREACH(cpu) { -CPUClass *cc = CPU_GET_CLASS(cpu); -int64_t id = cc-get_arch_id(cpu); +Error *local_err = NULL; -g_assert((id / 8) ACPI_GPE_PROC_LEN); -gpe_cpu-sts[id / 8] |= (1 (id % 8)); +acpi_set_local_sts(gpe_cpu, cpu, local_err); +g_assert(local_err == NULL); } memory_region_init_io(gpe_cpu-io, owner, AcpiCpuHotplug_ops, gpe_cpu, acpi-cpu-hotplug, ACPI_GPE_PROC_LEN);
Re: [Qemu-devel] [QA-virtio]:Why vring size is limited to 1024?
On 10/08/2014 03:28 PM, Avi Kivity wrote: My old presentation from 2012 or so suggested something like this. We don't need a 64 bit cookie I think - a small 16 bit one should be enough. A 16 bit cookie means you need an extra table to hold the real request pointers. With a 64-bit cookie you can store a pointer to the skbuff or bio in the ring itself, and avoid the extra lookup. The extra lookup isn't the end of the world, since doesn't cross core boundaries, but it's worth avoiding. What you can do is have two types of descriptors: head and fragment union desc { struct head { u16 nfrags u16 flags u64 cookie } struct frag { u64 paddr u16 flen u16 flags } } so now a request length is 12*(nfrags+1). You can be evil and steal some bits from paddr/cookie, and have each descriptor 8 bytes long. btw, I also recommend storing things like vnet_hdr in the ring itself, instead of out-of-line in memory. Maybe the ring should just transport bytes and let the upper layer decide how it's formatted.
[Qemu-devel] [PATCH v5] Support vhd type VHD_DIFFERENCING
Now qemu only supports vhd type VHD_FIXED and VHD_DYNAMIC, so qemu can't read snapshot volume of vhd, and can't support other storage features of vhd file. This patch add read parent information in function vpc_open, read bitmap in vpc_read, and change bitmap in vpc_write. Signed-off-by: Xiaodong Gong gordongong0...@gmail.com Reviewed-by: Ding xiao ssdx...@163.com --- block/vpc.c | 428 ++-- 1 file changed, 357 insertions(+), 71 deletions(-) diff --git a/block/vpc.c b/block/vpc.c index 4947369..1210542 100644 --- a/block/vpc.c +++ b/block/vpc.c @@ -29,17 +29,27 @@ #if defined(CONFIG_UUID) #include uuid/uuid.h #endif +#include iconv.h /**/ #define HEADER_SIZE 512 +#define DYNAMIC_HEADER_SIZE 1024 +#define PARENT_LOCATOR_NUM 8 +#define MACX_PREFIX_LEN 7 /* file:// */ +#define TBBATMAP_HEAD_SIZE 28 + +#define PLATFORM_MACX 0x5863614d /* big endian */ +#define PLATFORM_W2RU 0x75723257 + +#define VHD_VERSION(major, minor) (((major) 16) | ((minor) 0x)) //#define CACHE enum vhd_type { VHD_FIXED = 2, VHD_DYNAMIC = 3, -VHD_DIFFERENCING= 4, +VHD_DIFF= 4, }; // Seconds since Jan 1, 2000 0:00:00 (UTC) @@ -138,6 +148,15 @@ typedef struct BDRVVPCState { Error *migration_blocker; } BDRVVPCState; +typedef struct vhd_tdbatmap_header { +char magic[8]; /* always tdbatmap */ + +uint64_t batmap_offset; +uint32_t batmap_size; +uint32_t batmap_version; +uint32_t checksum; +} QEMU_PACKED VHDTdBatmapHeader; + static uint32_t vpc_checksum(uint8_t* buf, size_t size) { uint32_t res = 0; @@ -153,10 +172,107 @@ static uint32_t vpc_checksum(uint8_t* buf, size_t size) static int vpc_probe(const uint8_t *buf, int buf_size, const char *filename) { if (buf_size = 8 !strncmp((char *)buf, conectix, 8)) - return 100; +return 100; return 0; } +static int vpc_read_backing_loc(VHDDynDiskHeader *dyndisk_header, +BlockDriverState *bs, +Error **errp) +{ +BDRVVPCState *s = bs-opaque; +int64_t data_offset = 0; +int data_length = 0; +uint32_t platform; +bool done = false; +int parent_locator_offset = 0; +int i; +int ret = 0; + +for (i = 0; i PARENT_LOCATOR_NUM; i++) { +data_offset = +be64_to_cpu(dyndisk_header-parent_locator[i].data_offset); +data_length = +be32_to_cpu(dyndisk_header-parent_locator[i].data_length); +platform = dyndisk_header-parent_locator[i].platform; + +/* Extend the location offset */ +if (parent_locator_offset data_offset) { +parent_locator_offset = data_offset; +} + +if (done) { +continue; +} + +/* Skip file:// in MacX platform */ +if (platform == PLATFORM_MACX) { +data_offset += MACX_PREFIX_LEN; +data_length -= MACX_PREFIX_LEN; +} + +/* Read location of backing file */ +if (platform == PLATFORM_MACX || platform == PLATFORM_W2RU) { +if (data_offset s-max_table_entries * s-block_size) { +return -1; +} +if (data_length BDRV_SECTOR_SIZE) { +return -1; +} +ret = bdrv_pread(bs-file, data_offset, bs-backing_file, +data_length); +if (ret 0) { +return ret; +} +bs-backing_file[data_length] = '\0'; +} + +/* Convert location to ACSII string */ +if (platform == PLATFORM_MACX) { +done = true; + +} else if (platform == PLATFORM_W2RU) { +/* Must be UTF16-LE to ASCII */ +char *out, *optr; +int j; + +optr = out = (char *) malloc(data_length + 1); +if (out == NULL) { +ret = -1; +return ret; +} +memset(out, 0, data_length + 1); + +for (j = 0; j data_length + 1; j++) { +out[j] = bs-backing_file[2*j]; +} +out[data_length + 1] = '\0'; + +while (*optr != '\0') { +if (*optr == '\\') { +*optr = '/'; +} +optr++; +} + +strncpy(bs-backing_file, out, data_length + 1); + +out = NULL; +free(out); + +done = true; +} +} + +if (bs-backing_file[0] == '\0') { +error_setg(errp, block-vpc: differencing is not support in w2ku); +ret = -EINVAL; +return ret; +} + +return parent_locator_offset; +} + static int vpc_open(BlockDriverState *bs, QDict *options, int flags, Error **errp) { @@ -164,11 +280,14 @@ static int vpc_open(BlockDriverState *bs, QDict *options,
Re: [Qemu-devel] [PATCH v5] Support vhd type VHD_DIFFERENCING
A little bit late for the 7 days of Nation's day, Ding xiao will review my patch. It looks like qcow2 is too popular. :) On Thu, Oct 2, 2014 at 11:36 PM, Stefan Hajnoczi stefa...@gmail.com wrote: On Fri, Sep 26, 2014 at 09:43:18PM +0800, Xiaodong Gong wrote: Now qemu only supports vhd type VHD_FIXED and VHD_DYNAMIC, so qemu can't read snapshot volume of vhd, and can't support other storage features of vhd file. This patch add read parent information in function vpc_open, read bitmap in vpc_read, and change bitmap in vpc_write. Signed-off-by: Xiaodong Gong gordongong0...@gmail.com --- block/vpc.c | 428 ++-- 1 file changed, 357 insertions(+), 71 deletions(-) Waiting for code review. I only consider patches for the block branch that have at least 1 Reviewed-by from another contributor. Anyone? diff --git a/block/vpc.c b/block/vpc.c index 4947369..1210542 100644 --- a/block/vpc.c +++ b/block/vpc.c @@ -29,17 +29,27 @@ #if defined(CONFIG_UUID) #include uuid/uuid.h #endif +#include iconv.h /**/ #define HEADER_SIZE 512 +#define DYNAMIC_HEADER_SIZE 1024 +#define PARENT_LOCATOR_NUM 8 +#define MACX_PREFIX_LEN 7 /* file:// */ +#define TBBATMAP_HEAD_SIZE 28 + +#define PLATFORM_MACX 0x5863614d /* big endian */ +#define PLATFORM_W2RU 0x75723257 + +#define VHD_VERSION(major, minor) (((major) 16) | ((minor) 0x)) //#define CACHE enum vhd_type { VHD_FIXED = 2, VHD_DYNAMIC = 3, -VHD_DIFFERENCING= 4, +VHD_DIFF= 4, }; // Seconds since Jan 1, 2000 0:00:00 (UTC) @@ -138,6 +148,15 @@ typedef struct BDRVVPCState { Error *migration_blocker; } BDRVVPCState; +typedef struct vhd_tdbatmap_header { +char magic[8]; /* always tdbatmap */ + +uint64_t batmap_offset; +uint32_t batmap_size; +uint32_t batmap_version; +uint32_t checksum; +} QEMU_PACKED VHDTdBatmapHeader; + static uint32_t vpc_checksum(uint8_t* buf, size_t size) { uint32_t res = 0; @@ -153,10 +172,107 @@ static uint32_t vpc_checksum(uint8_t* buf, size_t size) static int vpc_probe(const uint8_t *buf, int buf_size, const char *filename) { if (buf_size = 8 !strncmp((char *)buf, conectix, 8)) - return 100; +return 100; return 0; } +static int vpc_read_backing_loc(VHDDynDiskHeader *dyndisk_header, +BlockDriverState *bs, +Error **errp) +{ +BDRVVPCState *s = bs-opaque; +int64_t data_offset = 0; +int data_length = 0; +uint32_t platform; +bool done = false; +int parent_locator_offset = 0; +int i; +int ret = 0; + +for (i = 0; i PARENT_LOCATOR_NUM; i++) { +data_offset = +be64_to_cpu(dyndisk_header-parent_locator[i].data_offset); +data_length = +be32_to_cpu(dyndisk_header-parent_locator[i].data_length); +platform = dyndisk_header-parent_locator[i].platform; + +/* Extend the location offset */ +if (parent_locator_offset data_offset) { +parent_locator_offset = data_offset; +} + +if (done) { +continue; +} + +/* Skip file:// in MacX platform */ +if (platform == PLATFORM_MACX) { +data_offset += MACX_PREFIX_LEN; +data_length -= MACX_PREFIX_LEN; +} + +/* Read location of backing file */ +if (platform == PLATFORM_MACX || platform == PLATFORM_W2RU) { +if (data_offset s-max_table_entries * s-block_size) { +return -1; +} +if (data_length BDRV_SECTOR_SIZE) { +return -1; +} +ret = bdrv_pread(bs-file, data_offset, bs-backing_file, +data_length); +if (ret 0) { +return ret; +} +bs-backing_file[data_length] = '\0'; +} + +/* Convert location to ACSII string */ +if (platform == PLATFORM_MACX) { +done = true; + +} else if (platform == PLATFORM_W2RU) { +/* Must be UTF16-LE to ASCII */ +char *out, *optr; +int j; + +optr = out = (char *) malloc(data_length + 1); +if (out == NULL) { +ret = -1; +return ret; +} +memset(out, 0, data_length + 1); + +for (j = 0; j data_length + 1; j++) { +out[j] = bs-backing_file[2*j]; +} +out[data_length + 1] = '\0'; + +while (*optr != '\0') { +if (*optr == '\\') { +
Re: [Qemu-devel] [PATCH v2 0/3] Clean up non-blocking error reporting
Il 08/10/2014 14:11, miny...@acm.org ha scritto: This version makes the error message reporting more sane and adds a error_vreport() to make that easier. It also cleans up the bool handling. This depends on the previos non-blocking socket changes, which should hopefully be in qemu soon. Looks good, but let's unify the error message like this: +static void check_report_connect_error(CharDriverState *chr, + Error *err) +{ +TCPCharDriver *s = chr-opaque; + +if (!s-connect_err_reported) { +error_report(Unable to connect character device %s: %s, + chr-label, error_get_pretty(err)); +s-connect_err_reported = true; +} +qemu_chr_socket_restart_timer(chr); +} + This is an error on connecting the character device to the backend. The error on the socket is already detailed after the colon, thanks to your patch 2. I'll send a pull request today or tomorrow. Thanks, Paolo
[Qemu-devel] [Bug 498035] Re: qemu hangs on shutdown or reboot (XP guest)
Hi, I have the same problem, or at least seems related. I just opened an issue on https://sourceforge.net/p/kvm/bugs/555, if needed I can post here all the details too. -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/498035 Title: qemu hangs on shutdown or reboot (XP guest) Status in QEMU: Incomplete Bug description: When I shut down or reboot my Windows XP guest, about half the time, it hangs at the point where it says Windows is shutting down At that point qemu is using 100% of one host CPU, about 85% user, 15% system. (Core 2 Quad 2.66GHz) This is the command line I use to start qemu: qemu-system-x86_64 -hda winxp.img -k en-us -m 2048 -smp 2 -vnc :3100 -usbdevice tablet -boot c -enable-kvm To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/498035/+subscriptions
Re: [Qemu-devel] [RFC PATCH v2 13/23] COLO ctl: implement colo save
Hi, I tried and executed this exciting patches named colo. However this patch causes abnormal termination in my environment. Although I think it's a known issue, the details and a presumed origin is described below: On 2014/09/23 18:23, Yang Hongyang wrote: implement colo save Signed-off-by: Yang Hongyang yan...@cn.fujitsu.com --- migration-colo.c | 60 +--- 1 file changed, 53 insertions(+), 7 deletions(-) diff --git a/migration-colo.c b/migration-colo.c index 2e478e9..d99342a 100644 --- a/migration-colo.c +++ b/migration-colo.c @@ -13,6 +13,7 @@ #include block/coroutine.h #include hw/qdev-core.h #include qemu/timer.h +#include sysemu/sysemu.h #include migration/migration-colo.h #include sys/ioctl.h #include qemu/error-report.h @@ -106,12 +107,12 @@ static int colo_compare(void) return ioctl(comp_fd, COMP_IOCTWAIT, 250); } -static __attribute__((unused)) int colo_compare_flush(void) +static int colo_compare_flush(void) { return ioctl(comp_fd, COMP_IOCTFLUSH, 1); } -static __attribute__((unused)) int colo_compare_resume(void) +static int colo_compare_resume(void) { return ioctl(comp_fd, COMP_IOCTRESUME, 1); } @@ -200,6 +201,9 @@ static bool colo_is_master(void) static int do_colo_transaction(MigrationState *s, QEMUFile *control) { int ret; +uint8_t *buf; +size_t size; +QEMUFile *trans = NULL; ret = colo_ctl_put(s-file, COLO_CHECKPOINT_NEW); if (ret) { @@ -211,30 +215,73 @@ static int do_colo_transaction(MigrationState *s, QEMUFile *control) goto out; } -/* TODO: suspend and save vm state to colo buffer */ +/* open colo buffer for write */ +trans = qemu_bufopen(w, NULL); +if (!trans) { +error_report(Open colo buffer for write failed); +goto out; +} + +/* suspend and save vm state to colo buffer */ +qemu_mutex_lock_iothread(); +vm_stop_force_state(RUN_STATE_COLO); +qemu_mutex_unlock_iothread(); +/* Disable block migration */ +s-params.blk = 0; +s-params.shared = 0; +qemu_savevm_state_begin(trans, s-params); +qemu_savevm_state_complete(trans); This line causes aborting Qemu immediately after starting a colo's migration process. If I'm not mistaken, the cause of aborting is not getting mutex lock when calling qemu_savevm_state_complete(). The aborting was resolved by getting mutex lock chen calling qemu_save_state_complete(). Thanks, Shunsuke + +qemu_fflush(trans); ret = colo_ctl_put(s-file, COLO_CHECKPOINT_SEND); if (ret) { goto out; } -/* TODO: send vmstate to slave */ +/* send vmstate to slave */ + +/* we send the total size of the vmstate first */ +size = qsb_get_length(qemu_buf_get(trans)); +ret = colo_ctl_put(s-file, size); +if (ret) { +goto out; +} + +buf = g_malloc(size); +qsb_get_buffer(qemu_buf_get(trans), 0, size, buf); +qemu_put_buffer(s-file, buf, size); +g_free(buf); +ret = qemu_file_get_error(s-file); +if (ret 0) { +goto out; +} +qemu_fflush(s-file); ret = colo_ctl_get(control, COLO_CHECKPOINT_RECEIVED); if (ret) { goto out; } -/* TODO: Flush network etc. */ +/* Flush network etc. */ +colo_compare_flush(); ret = colo_ctl_get(control, COLO_CHECKPOINT_LOADED); if (ret) { goto out; } -/* TODO: resume master */ +colo_compare_resume(); +ret = 0; out: +if (trans) +qemu_fclose(trans); +/* resume master */ +qemu_mutex_lock_iothread(); +vm_start(); +qemu_mutex_unlock_iothread(); + return ret; } @@ -289,7 +336,6 @@ static void *colo_thread(void *opaque) } /* start a colo checkpoint */ - if (do_colo_transaction(s, colo_control)) { goto out; }
[Qemu-devel] [PATCH] Let user specify random seed for linux-user
linux-user uses the rand function for generating the value of the AT_RANDOM elf aux vector entry, and explicitly seeds the random number generator with the current time. This makes it impossible to reproduce runs that use the AT_RANDOM bytes. This patch adds a command line option and a matching environment variable for setting the random seed, so that the AT_RANDOM values can be predictable when the user chooses. The default is still to seed the random number generator with the current time.
[Qemu-devel] [PATCH] linux-user: Let user specify random seed
This patch introduces the -seed command line option and the QEMU_RAND_SEED environment variable for setting the random seed, which is used for the AT_RANDOM ELF aux entry. Signed-off-by: Magnus Reftel ref...@spotify.com --- linux-user/elfload.c | 1 - linux-user/main.c| 21 + 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 1c04fcf..f2e2197 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -1539,7 +1539,6 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc, * Generate 16 random bytes for userspace PRNG seeding (not * cryptically secure but it's not the aim of QEMU). */ -srand((unsigned int) time(NULL)); for (i = 0; i 16; i++) { k_rand_bytes[i] = rand(); } diff --git a/linux-user/main.c b/linux-user/main.c index 483eb3f..57cd721 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -46,6 +46,8 @@ unsigned long mmap_min_addr; #if defined(CONFIG_USE_GUEST_BASE) unsigned long guest_base; int have_guest_base; +static bool have_rand_seed = false; +static int rand_seed; #if (TARGET_LONG_BITS == 32) (HOST_LONG_BITS == 64) /* * When running 32-on-64 we should make sure we can fit all of the possible @@ -3546,6 +3548,12 @@ static void handle_arg_pagesize(const char *arg) } } +static void handle_arg_randseed(const char *arg) +{ +have_rand_seed = true; +rand_seed = atoi(arg); +} + static void handle_arg_gdb(const char *arg) { gdbstub_port = atoi(arg); @@ -3674,6 +3682,8 @@ static const struct qemu_argument arg_table[] = { , run in singlestep mode}, {strace, QEMU_STRACE, false, handle_arg_strace, , log system calls}, +{seed, QEMU_RAND_SEED, true, handle_arg_randseed, + , Seed for pseudo-random number generator}, {version,QEMU_VERSION, false, handle_arg_version, , display version information and exit}, {NULL, NULL, false, NULL, NULL, NULL} @@ -3926,6 +3936,17 @@ int main(int argc, char **argv, char **envp) do_strace = 1; } +if (getenv(QEMU_RAND_SEED)) { +have_rand_seed = true; +rand_seed = atoi(getenv(QEMU_RAND_SEED)); +} + +if (have_rand_seed) { +srand(rand_seed); +} else { +srand((int)time(NULL)); +} + target_environ = envlist_to_environ(envlist, NULL); envlist_free(envlist); -- 1.9.1
Re: [Qemu-devel] [PATCH 2/2] xenfb: Add comment documentation
On Mon, 22 Sep 2014, Owen smith wrote: Add documentation for page-ref, page-gref and event-channel. Signed-off-by: Owen smith owen.sm...@citrix.com thanks for the patch xen/include/public/io/fbif.h | 25 + 1 file changed, 25 insertions(+) diff --git a/xen/include/public/io/fbif.h b/xen/include/public/io/fbif.h index cc25aab..ba3f524 100644 --- a/xen/include/public/io/fbif.h +++ b/xen/include/public/io/fbif.h @@ -26,6 +26,31 @@ #ifndef __XEN_PUBLIC_IO_FBIF_H__ #define __XEN_PUBLIC_IO_FBIF_H__ +/* + * Frontend XenStore Nodes + * --- + * + * page-ref + * Values: uint64_t + * Optional, page-gref is used if page-ref is not set. + * + * The MFN of a page of memory for the shared ring structures. If not + * present, page-gref must be set.page-ref overrides page-gref. + * + * page-gref + * Values: uint32_t + * Only required if page-ref is NOT set. + * + * A grant reference to the memory page to be mapped for the shared ring + * structures. Must be present if page-ref is not present. + * + * event-channel + * Values: uint32_t + * + * An event channel identifier, which is triggered when the shared page + * is updated. + */ You are missing videoram, feature-update, feature-resize and request-update. /* Out events (frontend - backend) */ /* -- 2.1.0
Re: [Qemu-devel] [PATCH 1/2] xenfb: Add comment documentation
On Mon, 22 Sep 2014, Owen smith wrote: Add documentation for feature-abs-pointer, feature-no-abs-rescale, feature-no-console, page-ref, page-gref and event-channel Signed-off-by: Owen smith owen.sm...@citrix.com I would suggest resending this patch series removing the new options you are introducing with 1410964242-3341-1-git-send-email-owen.sm...@citrix.com. This series should be a precursor and could go in the 4.5 release. xen/include/public/io/kbdif.h | 74 +++ 1 file changed, 74 insertions(+) diff --git a/xen/include/public/io/kbdif.h b/xen/include/public/io/kbdif.h index 2d2aebd..b29bc12 100644 --- a/xen/include/public/io/kbdif.h +++ b/xen/include/public/io/kbdif.h @@ -26,6 +26,80 @@ #ifndef __XEN_PUBLIC_IO_KBDIF_H__ #define __XEN_PUBLIC_IO_KBDIF_H__ +/* + * Backend Xenstore Nodes + * -- + * + * feature-abs-pointer + * Values: 0/1 (boolean) + * Default: 0 + * + * When set to 1, backend supports supplying absolute coordinates via + * XENKBD_TYPE_POS messages. When set to 0, backend can only supply + * relative movements via XENKBD_TYPE_MOTION messages. + * + * feature-no-abs-rescale + * Values: 0/1 (boolean) + * Default: 0 + * + * When set to 1, backend supports unscaled absolute coordinates. Unscaled + * coordinates are in the range [0, 0x7fff]. When set to 0, backend can + * only supply scaled coordinates. Scaled coordinates are scaled to the + * 'screen size' of the console. If feature-abs-pointer is 0, this value + * has no effect. + * + * feature-no-console + * Values: 0/1 (boolean) + * Default: 0 + * + * When set to 1, backend supports connection without a console. When + * running without a console, scaled values maximum is undefined. When + * set to 0, backend will wait for a console before connecting. + * + * Frontend XenStore Nodes + * --- + * + * request-abs-pointer + * Values: 0/1 (boolean) + * Default: 0 + * + * When set to 1, frontend wants absolute coordinates delivered with the + * XENKBD_TYPE_POS message. + * + * request-no-abs-rescale + * Values: 0/1 (boolean) + * Default: 0 + * + * When set to 1, frontend wants unscaled absolute coordinates. If + * request-abs-pointer is 0, this value has no effect. + * + * request-no-console + * Values: 0/1 (boolean) + * Default: 0 + * + * When set to 1, frontend does not require a console for connection. + * + * page-ref + * Values: uint64_t + * Optional, page-gref is used if page-ref is not set. + * + * The MFN of a page of memory for the shared ring structures. If not + * present, page-gref must be set. page-ref overrides page-gref. + * + * page-gref + * Values: uint32_t + * Only required if page-ref is NOT set. + * + * A grant reference to the memory page to be mapped for the shared ring + * structures. Must be present if page-ref is not present. + * + * event-channel + * Values: uint32_t + * + * An event channel identifier, which is triggered when the shared page + * is updated. + */ + /* In events (backend - frontend) */ /* -- 2.1.0
Re: [Qemu-devel] [PULL 12/51] target-arm: A64: Implement DC ZVA
Hi Peter, On 04/17/2014 06:33 AM, Peter Maydell wrote: Implement the DC ZVA instruction, which clears a block of memory. The fast path obtains a pointer to the underlying RAM via the TCG TLB data structure so we can do a direct memset(), with fallback to a simple byte-store loop in the slow path. diff --git a/target-arm/helper.c b/target-arm/helper.c index 62f7fd3..2ffc588 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c +static uint64_t aa64_dczid_read(CPUARMState *env, const ARMCPRegInfo *ri) +{ +ARMCPU *cpu = arm_env_get_cpu(env); +int dzp_bit = 1 4; + +/* DZP indicates whether DC ZVA access is allowed */ +if (aa64_zva_access(env, NULL) != CP_ACCESS_OK) { I believe this logic for the Data Zero Prohibited field is inverted, causing eglibc to use STP rather than DC ZVA for __memset. +dzp_bit = 0; +} +return cpu-dcz_blocksize | dzp_bit; +} Thanks, Christopher -- Employee of Qualcomm Innovation Center, Inc. Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by the Linux Foundation.
[Qemu-devel] [PATCH][SPARC] LEON3: Add emulation of AMBA plugplay
From: Jiri Gaisler j...@gaisler.se AMBA plugplay is used by kernels to probe available devices (Timers, UART, etc...). This is a static declaration of devices implemented in QEMU. In the future, a more advanced version could compute those information directly from the device tree. Signed-off-by: Fabien Chouteau chout...@adacore.com --- hw/sparc/Makefile.objs |1 + hw/sparc/grlib_ambapnp.c | 206 ++ hw/sparc/leon3.c |6 ++ include/hw/sparc/grlib.h | 36 4 files changed, 249 insertions(+) create mode 100644 hw/sparc/grlib_ambapnp.c diff --git a/hw/sparc/Makefile.objs b/hw/sparc/Makefile.objs index c987b5b..e763701 100644 --- a/hw/sparc/Makefile.objs +++ b/hw/sparc/Makefile.objs @@ -1 +1,2 @@ obj-y += sun4m.o leon3.o +obj-$(CONFIG_GRLIB) += grlib_ambapnp.o diff --git a/hw/sparc/grlib_ambapnp.c b/hw/sparc/grlib_ambapnp.c new file mode 100644 index 000..dfadd5c --- /dev/null +++ b/hw/sparc/grlib_ambapnp.c @@ -0,0 +1,206 @@ +/* + * QEMU GRLIB AMBA PlugPlay Emulator + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the Software), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include hw/sysbus.h + +#define APBPNP_REG_SIZE 4096 /* Size of memory mapped registers */ + +#define TYPE_GRLIB_APB_PNP grlib,apbpnp +#define GRLIB_APB_PNP(obj) \ +OBJECT_CHECK(APBPNP, (obj), TYPE_GRLIB_APB_PNP) + +typedef struct APBPNP { +SysBusDevice parent_obj; +MemoryRegion iomem; +} APBPNP; + +static uint64_t grlib_apbpnp_read(void *opaque, hwaddr addr, + unsigned size) +{ +uint64_t read_data; +addr = 0xfff; + +/* Unit registers */ +switch (addr 0xffc) { +case 0x00: +read_data = 0x0400f000; /* Memory controller */ +break; +case 0x04: +read_data = 0xfff1; +break; +case 0x08: +read_data = 0x0100c023; /* APBUART */ +break; +case 0x0C: +read_data = 0x0010fff1; +break; +case 0x10: +read_data = 0x0100d040; /* IRQMP */ +break; +case 0x14: +read_data = 0x0020fff1; +break; +case 0x18: +read_data = 0x01011006; /* GPTIMER */ +break; +case 0x1C: +read_data = 0x0030fff1; +break; + +default: +read_data = 0; +} +if (size == 1) { +read_data = (24 - (addr 3) * 8); +read_data = 0x0ff; +} +return read_data; +} + +static void grlib_apbpnp_write(void *opaque, hwaddr addr, +uint64_t value, unsigned size) +{ +} + +static const MemoryRegionOps grlib_apbpnp_ops = { +.write = grlib_apbpnp_write, +.read = grlib_apbpnp_read, +.endianness = DEVICE_NATIVE_ENDIAN, +}; + +static int grlib_apbpnp_init(SysBusDevice *dev) +{ +APBPNP *pnp = GRLIB_APB_PNP(dev); + +memory_region_init_io(pnp-iomem, OBJECT(pnp), grlib_apbpnp_ops, pnp, + apbpnp, APBPNP_REG_SIZE); + +sysbus_init_mmio(dev, pnp-iomem); + +return 0; +} + +static void grlib_apbpnp_class_init(ObjectClass *klass, void *data) +{ +SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); + +k-init = grlib_apbpnp_init; +} + +static const TypeInfo grlib_apbpnp_info = { +.name = TYPE_GRLIB_APB_PNP, +.parent= TYPE_SYS_BUS_DEVICE, +.instance_size = sizeof(APBPNP), +.class_init= grlib_apbpnp_class_init, +}; + +static void grlib_apbpnp_register_types(void) +{ +type_register_static(grlib_apbpnp_info); +} + +type_init(grlib_apbpnp_register_types) + + +/* AHB PNP */ + +#define AHBPNP_REG_SIZE (4096 - 8) /* Size of memory mapped registers */ + +#define TYPE_GRLIB_AHB_PNP grlib,ahbpnp +#define GRLIB_AHB_PNP(obj) \ +OBJECT_CHECK(AHBPNP, (obj), TYPE_GRLIB_AHB_PNP) + +typedef struct AHBPNP { +SysBusDevice parent_obj; +MemoryRegion iomem; +} AHBPNP; + +static uint64_t grlib_ahbpnp_read(void *opaque, hwaddr addr, + unsigned size)
Re: [Qemu-devel] [PATCH 1/3] qemu-error: Add error_vreport()
On 10/08/2014 06:11 AM, miny...@acm.org wrote: From: Corey Minyard cminy...@mvista.com Needed to nicely print socket error reports. Signed-off-by: Corey Minyard cminy...@mvista.com --- include/qemu/error-report.h | 1 + util/qemu-error.c | 23 ++- 2 files changed, 19 insertions(+), 5 deletions(-) Reviewed-by: Eric Blake ebl...@redhat.com -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature
Re: [Qemu-devel] [PATCH] linux-user: Let user specify random seed
On 10/08/2014 06:13 AM, Magnus Reftel wrote: This patch introduces the -seed command line option and the QEMU_RAND_SEED environment variable for setting the random seed, which is used for the AT_RANDOM ELF aux entry. Signed-off-by: Magnus Reftel ref...@spotify.com --- linux-user/elfload.c | 1 - linux-user/main.c| 21 + 2 files changed, 21 insertions(+), 1 deletion(-) +++ b/linux-user/main.c @@ -46,6 +46,8 @@ unsigned long mmap_min_addr; #if defined(CONFIG_USE_GUEST_BASE) unsigned long guest_base; int have_guest_base; +static bool have_rand_seed = false; static variables are automatically 0-initialized without needing an explicit initializer. +static int rand_seed; #if (TARGET_LONG_BITS == 32) (HOST_LONG_BITS == 64) /* * When running 32-on-64 we should make sure we can fit all of the possible @@ -3546,6 +3548,12 @@ static void handle_arg_pagesize(const char *arg) } } +static void handle_arg_randseed(const char *arg) +{ +have_rand_seed = true; +rand_seed = atoi(arg); +} atoi() is trash when compared to strtol() - it doesn't diagnose overflow, trailing garbage, or empty input. @@ -3926,6 +3936,17 @@ int main(int argc, char **argv, char **envp) do_strace = 1; } +if (getenv(QEMU_RAND_SEED)) { +have_rand_seed = true; +rand_seed = atoi(getenv(QEMU_RAND_SEED)); +} why not call handle_arg_randseed(getenv(QEMU_RAND_SEED)) here? + +if (have_rand_seed) { +srand(rand_seed); +} else { +srand((int)time(NULL)); The cast is pointless. This is C. +} Do you even need have_rand_seed? Why not just pre-initialize rand_seed=time(NULL) and then overwrite rand_seed if the environment variable is present? -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature
Re: [Qemu-devel] [PATCH v7 1/2] dump: Propagate errors into qmp_dump_guest_memory()
On 09/30/2014 03:20 AM, zhanghailiang wrote: The code calls dump_error() on error, and even passes it a suitable message. However, the message is thrown away, and its callers pass up only success/failure. All qmp_dump_guest_memory() can do is set a generic error. Propagate the errors properly, so qmp_dump_guest_memory() can return a more useful error. Reviewed-by: Markus Armbruster arm...@redhat.com Signed-off-by: zhanghailiang zhang.zhanghaili...@huawei.com --- dump.c | 165 - 1 file changed, 82 insertions(+), 83 deletions(-) Reviewed-by: Eric Blake ebl...@redhat.com -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature
Re: [Qemu-devel] [PATCH v7 2/2] dump: Turn some functions to void to make code cleaner
On 09/30/2014 03:20 AM, zhanghailiang wrote: Functions shouldn't return an error code and an Error object at the same time. Turn all these functions that returning Error object to void. We also judge if a function success or fail by reference to the local_err. Signed-off-by: zhanghailiang zhang.zhanghaili...@huawei.com --- dump.c | 313 ++--- 1 file changed, 143 insertions(+), 170 deletions(-) @@ -348,49 +326,45 @@ static int write_elf_section(DumpState *s, int type, Error **errp) ret = fd_write_vmcore(shdr, shdr_size, s); if (ret 0) { dump_error(s, dump: failed to write section header table, errp); -return -1; +return; } - -return 0; } The 'return' here is not in a loop, and therefore not necessary. -static int write_data(DumpState *s, void *buf, int length, Error **errp) +static void write_data(DumpState *s, void *buf, int length, Error **errp) { int ret; ret = fd_write_vmcore(buf, length, s); if (ret 0) { dump_error(s, dump: failed to save memory, errp); -return -1; +return; } - -return 0; } and again. /* write the memroy to vmcore. 1 page per I/O. */ Please s/memroy/memory/ while touching this :) @@ -1706,7 +1680,6 @@ void qmp_dump_guest_memory(bool paging, const char *file, bool has_begin, } else { create_vmcore(s, errp); } - g_free(s); } Looks a bit like a spurious line deletion in this hunk. Findings are minor, so I'm fine if you add: Reviewed-by: Eric Blake ebl...@redhat.com -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature
Re: [Qemu-devel] [RFC PATCH v2 03/23] COLO: introduce an api colo_supported() to indicate COLO support
On 09/23/2014 03:23 AM, Yang Hongyang wrote: introduce an api colo_supported() to indicate COLO support, returns true if colo supported (configured with --enable-colo). Signed-off-by: Yang Hongyang yan...@cn.fujitsu.com --- +++ b/include/migration/migration-colo.h @@ -0,0 +1,18 @@ +/* + * COarse-grain LOck-stepping Virtual Machines for Non-stop Service (COLO) + * (a.k.a. Fault Tolerance or Continuous Replication) + * + * Copyright (C) 2014 FUJITSU LIMITED + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. Is there any reason you are forbidding the use of this file in a GPLv3 project? We prefer new files to be GPLv2+, not GPLv2-only (by the use of the or later clause), unless there is strong reason why it is not possible. +++ b/migration-colo.c @@ -0,0 +1,16 @@ +/* + * COarse-grain LOck-stepping Virtual Machines for Non-stop Service (COLO) + * (a.k.a. Fault Tolerance or Continuous Replication) + * + * Copyright (C) 2014 FUJITSU LIMITED + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. Same comment for all new files. -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature
Re: [Qemu-devel] [PATCH v1 1/8] throttle: Extract timers from ThrottleState into a separate ThrottleTimers structure
On 10/07/2014 07:24 AM, Benoît Canet wrote: Group throttling will share ThrottleState between multiple bs. As a consequence the ThrottleState will be accessed by multiple aio context. Timers are tied to their aio context so they must go out of the ThrottleState structure. This commit pave the way for each bs of a common ThrottleState to have it's own s/it's/its/ (remember, it's is only acceptable if you can say it is in its place) timer. Signed-off-by: Benoit Canet benoit.ca...@nodalink.com --- -- Eric Blake eblake redhat com+1-919-301-3266 Libvirt virtualization library http://libvirt.org signature.asc Description: OpenPGP digital signature
Re: [Qemu-devel] [PATCH][SPARC] LEON3: Add emulation of AMBA plugplay
Hi, Am 08.10.2014 um 16:19 schrieb Fabien Chouteau: From: Jiri Gaisler j...@gaisler.se AMBA plugplay is used by kernels to probe available devices (Timers, UART, etc...). This is a static declaration of devices implemented in QEMU. In the future, a more advanced version could compute those information directly from the device tree. Interesting. There's quite some magic numbers in the read functions; I wonder if you could read them via QOM if you actually give the devices a canonical path or search by type? You may want to peek at ACPI code. Signed-off-by: Fabien Chouteau chout...@adacore.com --- hw/sparc/Makefile.objs |1 + hw/sparc/grlib_ambapnp.c | 206 ++ hw/sparc/leon3.c |6 ++ include/hw/sparc/grlib.h | 36 4 files changed, 249 insertions(+) create mode 100644 hw/sparc/grlib_ambapnp.c diff --git a/hw/sparc/Makefile.objs b/hw/sparc/Makefile.objs index c987b5b..e763701 100644 --- a/hw/sparc/Makefile.objs +++ b/hw/sparc/Makefile.objs @@ -1 +1,2 @@ obj-y += sun4m.o leon3.o +obj-$(CONFIG_GRLIB) += grlib_ambapnp.o diff --git a/hw/sparc/grlib_ambapnp.c b/hw/sparc/grlib_ambapnp.c new file mode 100644 index 000..dfadd5c --- /dev/null +++ b/hw/sparc/grlib_ambapnp.c @@ -0,0 +1,206 @@ +/* + * QEMU GRLIB AMBA PlugPlay Emulator + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the Software), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include hw/sysbus.h + +#define APBPNP_REG_SIZE 4096 /* Size of memory mapped registers */ + +#define TYPE_GRLIB_APB_PNP grlib,apbpnp If you move the two TYPE_* constants to grlib.h, you can reuse them. +#define GRLIB_APB_PNP(obj) \ +OBJECT_CHECK(APBPNP, (obj), TYPE_GRLIB_APB_PNP) + +typedef struct APBPNP { +SysBusDevice parent_obj; +MemoryRegion iomem; +} APBPNP; + +static uint64_t grlib_apbpnp_read(void *opaque, hwaddr addr, + unsigned size) Indentation is off by one for all read/write functions. +{ +uint64_t read_data; +addr = 0xfff; + +/* Unit registers */ +switch (addr 0xffc) { +case 0x00: +read_data = 0x0400f000; /* Memory controller */ +break; +case 0x04: +read_data = 0xfff1; +break; +case 0x08: +read_data = 0x0100c023; /* APBUART */ +break; +case 0x0C: +read_data = 0x0010fff1; +break; +case 0x10: +read_data = 0x0100d040; /* IRQMP */ +break; +case 0x14: +read_data = 0x0020fff1; +break; +case 0x18: +read_data = 0x01011006; /* GPTIMER */ +break; +case 0x1C: +read_data = 0x0030fff1; +break; + +default: +read_data = 0; +} +if (size == 1) { +read_data = (24 - (addr 3) * 8); +read_data = 0x0ff; +} +return read_data; +} + +static void grlib_apbpnp_write(void *opaque, hwaddr addr, +uint64_t value, unsigned size) +{ +} + +static const MemoryRegionOps grlib_apbpnp_ops = { +.write = grlib_apbpnp_write, +.read = grlib_apbpnp_read, +.endianness = DEVICE_NATIVE_ENDIAN, +}; + +static int grlib_apbpnp_init(SysBusDevice *dev) +{ +APBPNP *pnp = GRLIB_APB_PNP(dev); + +memory_region_init_io(pnp-iomem, OBJECT(pnp), grlib_apbpnp_ops, pnp, + apbpnp, APBPNP_REG_SIZE); + +sysbus_init_mmio(dev, pnp-iomem); APBPNP_REG_SIZE seems constant, so you could move both lines into an instance_init function. + +return 0; +} + +static void grlib_apbpnp_class_init(ObjectClass *klass, void *data) s/klass/oc/g +{ +SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); sdc? + +k-init = grlib_apbpnp_init; +} + +static const TypeInfo grlib_apbpnp_info = { +.name = TYPE_GRLIB_APB_PNP, +.parent= TYPE_SYS_BUS_DEVICE,
[Qemu-devel] [Bug 1336192] Re: delvm does not delete snapshots on every disks
fixed by af957387547b05ed6dc4d84c10cca42700a7aeda ** Changed in: qemu Status: New = Fix Committed -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1336192 Title: delvm does not delete snapshots on every disks Status in QEMU: Fix Committed Bug description: Using more than one block device, using delvm does remove snapshot from the first block device, but does not remove snapshots from other blockdevs (complains about not finding snapshot on 1st blockdev). Attached patch fixes that. To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1336192/+subscriptions
[Qemu-devel] [PATCH v1.5] nbd: Fix filename generation
Export names may be used with nbd+unix, too, fix nbd_refresh_filename() accordingly. Also, for nbd+tcp, the documented path schema is nbd://host[:port]/export, so use it. Furthermore, as can be seen from that schema, the port is optional. That makes six single cases for how the filename can be formatted; it is not easy to generalize these cases without the resulting statement being completely unreadable, thus there is simply one snprintf() per case. Finally, taking the options from BDRVNBDState::socket_opts is wrong, because those will not contain the export name. Just use BlockDriverState::options instead. Reported-by: Stefan Hajnoczi stefa...@redhat.com Signed-off-by: Max Reitz mre...@redhat.com Reviewed-by: Paolo Bonzini pbonz...@redhat.com --- This is exactly the same patch as patch 1 from my series [PATCH 0/3] block: Fix filename generation for blkdebug and nbd, except I added Paolo's R-b. The reason I split it off from the series is that is an actual bug fix and therefore I want to get it merged regardless of when the blkdebug patches are getting reviewed. --- block/nbd.c | 44 +--- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/block/nbd.c b/block/nbd.c index 89775e1..04cc845 100644 --- a/block/nbd.c +++ b/block/nbd.c @@ -342,30 +342,44 @@ static void nbd_attach_aio_context(BlockDriverState *bs, static void nbd_refresh_filename(BlockDriverState *bs) { -BDRVNBDState *s = bs-opaque; QDict *opts = qdict_new(); -const char *path = qemu_opt_get(s-socket_opts, path); -const char *host = qemu_opt_get(s-socket_opts, host); -const char *port = qemu_opt_get(s-socket_opts, port); -const char *export = qemu_opt_get(s-socket_opts, export); +const char *path = qdict_get_try_str(bs-options, path); +const char *host = qdict_get_try_str(bs-options, host); +const char *port = qdict_get_try_str(bs-options, port); +const char *export = qdict_get_try_str(bs-options, export); qdict_put_obj(opts, driver, QOBJECT(qstring_from_str(nbd))); -if (path) { +if (path export) { snprintf(bs-exact_filename, sizeof(bs-exact_filename), - nbd+unix:%s, path); -qdict_put_obj(opts, path, QOBJECT(qstring_from_str(path))); -} else if (export) { + nbd+unix:///%s?socket=%s, export, path); +} else if (path !export) { snprintf(bs-exact_filename, sizeof(bs-exact_filename), - nbd:%s:%s/%s, host, port, export); -qdict_put_obj(opts, host, QOBJECT(qstring_from_str(host))); -qdict_put_obj(opts, port, QOBJECT(qstring_from_str(port))); -qdict_put_obj(opts, export, QOBJECT(qstring_from_str(export))); -} else { + nbd+unix://?socket=%s, path); +} else if (!path export port) { +snprintf(bs-exact_filename, sizeof(bs-exact_filename), + nbd://%s:%s/%s, host, port, export); +} else if (!path export !port) { +snprintf(bs-exact_filename, sizeof(bs-exact_filename), + nbd://%s/%s, host, export); +} else if (!path !export port) { +snprintf(bs-exact_filename, sizeof(bs-exact_filename), + nbd://%s:%s, host, port); +} else if (!path !export !port) { snprintf(bs-exact_filename, sizeof(bs-exact_filename), - nbd:%s:%s, host, port); + nbd://%s, host); +} + +if (path) { +qdict_put_obj(opts, path, QOBJECT(qstring_from_str(path))); +} else if (port) { qdict_put_obj(opts, host, QOBJECT(qstring_from_str(host))); qdict_put_obj(opts, port, QOBJECT(qstring_from_str(port))); +} else { +qdict_put_obj(opts, host, QOBJECT(qstring_from_str(host))); +} +if (export) { +qdict_put_obj(opts, export, QOBJECT(qstring_from_str(export))); } bs-full_open_options = opts; -- 2.1.2
[Qemu-devel] [PATCH] target-arm: add second UART to virt
This minor patch adds a second uart to the QEMU virt machine type. This patch is needed for separating the console output between normal and secure world environments. Greg Bellows (1): target-arm: add second UART to virt hw/arm/virt.c | 24 ++-- 1 file changed, 14 insertions(+), 10 deletions(-) -- 1.8.3.2
[Qemu-devel] [PATCH] target-arm: add second UART to virt
Added UART1 to virt to enable separate UARTs for secure/nonsecure worlds. Signed-off-by: Greg Bellows greg.bell...@linaro.org --- hw/arm/virt.c | 24 ++-- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 8c6b171..0740cdc 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -64,7 +64,8 @@ enum { VIRT_CPUPERIPHS, VIRT_GIC_DIST, VIRT_GIC_CPU, -VIRT_UART, +VIRT_UART0, +VIRT_UART1, VIRT_MMIO, VIRT_RTC, }; @@ -104,8 +105,9 @@ static const MemMapEntry a15memmap[] = { /* GIC distributor and CPU interfaces sit inside the CPU peripheral space */ [VIRT_GIC_DIST] = { 0x0800, 0x0001 }, [VIRT_GIC_CPU] ={ 0x0801, 0x0001 }, -[VIRT_UART] = { 0x0900, 0x1000 }, -[VIRT_RTC] ={ 0x0901, 0x1000 }, +[VIRT_UART0] = { 0x0900, 0x1000 }, +[VIRT_UART1] = { 0x0901, 0x1000 }, +[VIRT_RTC] ={ 0x0902, 0x1000 }, [VIRT_MMIO] = { 0x0a00, 0x0200 }, /* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */ /* 0x1000 .. 0x4000 reserved for PCI */ @@ -113,8 +115,9 @@ static const MemMapEntry a15memmap[] = { }; static const int a15irqmap[] = { -[VIRT_UART] = 1, -[VIRT_RTC] = 2, +[VIRT_UART0] = 1, +[VIRT_UART1] = 2, +[VIRT_RTC] = 3, [VIRT_MMIO] = 16, /* ...to 16 + NUM_VIRTIO_TRANSPORTS - 1 */ }; @@ -352,12 +355,12 @@ static void create_gic(const VirtBoardInfo *vbi, qemu_irq *pic) fdt_add_gic_node(vbi); } -static void create_uart(const VirtBoardInfo *vbi, qemu_irq *pic) +static void create_uart(const VirtBoardInfo *vbi, qemu_irq *pic, int uart) { char *nodename; -hwaddr base = vbi-memmap[VIRT_UART].base; -hwaddr size = vbi-memmap[VIRT_UART].size; -int irq = vbi-irqmap[VIRT_UART]; +hwaddr base = vbi-memmap[uart].base; +hwaddr size = vbi-memmap[uart].size; +int irq = vbi-irqmap[uart]; const char compat[] = arm,pl011\0arm,primecell; const char clocknames[] = uartclk\0apb_pclk; @@ -589,7 +592,8 @@ static void machvirt_init(MachineState *machine) create_gic(vbi, pic); -create_uart(vbi, pic); +create_uart(vbi, pic, VIRT_UART0); +create_uart(vbi, pic, VIRT_UART1); create_rtc(vbi, pic); -- 1.8.3.2
Re: [Qemu-devel] [PATCH v5 00/11] qcow2: Fix image repairing
On 29.08.2014 23:40, Max Reitz wrote: As can be seen in the final patch of this series, there are certain cases where the current repair implementation of qcow2 actually damages the image further because it allocates new clusters for the refcount structure which overlap with existing but according to the on-disk refcounts (which are assumed to be wrong to begin with) unallocated clusters. This series fixes this by completely recreating the refcount structure based on the in-memory information calculated during the check operation if the possibility of damaging the image while repairing the refcount structures in-place exists. v5: - Added patch 1 which adds two helper variables to BDRVQcowState reflecting the number of entries per refcount block; in contrast to v4, we don't need to clamp the refcount order against sub-byte widths, because sub-byte widths are actually correct (that means, I dropped the MAX() around refcount_order - 3) - Patch 8 (prev. 7): - Use these new variables [Benoît] - Use a struct for rt_offset_and_clusters [Benoît] git-backport-diff against v4: Key: [] : patches are identical [] : number of functional differences between upstream/downstream patch [down] : patch is downstream-only The flags [FC] indicate (F)unctional and (C)ontextual differences, respectively 001/11:[down] 'qcow2: Calculate refcount block entry count' 002/11:[] [--] 'qcow2: Fix leaks in dirty images' 003/11:[] [--] 'qcow2: Split qcow2_check_refcounts()' 004/11:[] [--] 'qcow2: Pull check_refblocks() up' 005/11:[] [--] 'qcow2: Reuse refcount table in calculate_refcounts()' 006/11:[] [--] 'qcow2: Fix refcount blocks beyond image end' 007/11:[] [--] 'qcow2: Do not perform potentially damaging repairs' 008/11:[0025] [FC] 'qcow2: Rebuild refcount structure during check' 009/11:[] [--] 'qcow2: Clean up after refcount rebuild' 010/11:[] [--] 'iotests: Fix test outputs' 011/11:[] [-C] 'iotests: Add test for potentially damaging repairs' Max Reitz (11): qcow2: Calculate refcount block entry count qcow2: Fix leaks in dirty images qcow2: Split qcow2_check_refcounts() qcow2: Pull check_refblocks() up qcow2: Reuse refcount table in calculate_refcounts() qcow2: Fix refcount blocks beyond image end qcow2: Do not perform potentially damaging repairs qcow2: Rebuild refcount structure during check qcow2: Clean up after refcount rebuild iotests: Fix test outputs iotests: Add test for potentially damaging repairs block/qcow2-refcount.c | 677 - block/qcow2.c | 4 +- block/qcow2.h | 2 + tests/qemu-iotests/039.out | 10 +- tests/qemu-iotests/060.out | 10 +- tests/qemu-iotests/061.out | 18 +- tests/qemu-iotests/104 | 141 ++ tests/qemu-iotests/104.out | 110 tests/qemu-iotests/group | 1 + 9 files changed, 767 insertions(+), 206 deletions(-) create mode 100755 tests/qemu-iotests/104 create mode 100644 tests/qemu-iotests/104.out Ping. Patch 8 still requires a review. I know it's probably the hardest patch of the series, but well... Max
Re: [Qemu-devel] [PATCH v12 00/14] qemu-img: Implement commit like QMP
On 26.08.2014 23:36, Max Reitz wrote: qemu-img should use QMP commands whenever possible in order to ensure feature completeness of both online and offline image operations. For the commit command, this is relatively easy, so implement it first (in the hope that indeed others will follow). As qemu-img does not have access to QMP (due to QMP being intertwined with basically everything in qemu), we cannot directly use QMP, but at least use the functions the corresponding QMP commands are using (which would be block-commit, in this case). As of this version, this series depends on my series '[PATCH v3 00/10] qcow2: Fix image repairing' (or on any later version). Patches without a Reviewed-by: 3 and 14 Ping. I kind of want to make Kevin responsible for the state in which patch 3 is now, so I'm hoping he'll review it despite of the now official reviewer policy. ;-) Although everyone is welcome; patch 3 is now much more simple than in previous versions, so don't be afraid. Max v12: - Rewrote patch 3 according to Kevin's proposal (in reply to v8): Instead of keeping the image constantly clean and recreating a new refcount structure in unallocated clusters, just mark the image dirty, overwrite the beginning of the image with zeroes, place the reftable and the L1 table there and go from there. This is much easier than the previous version but was not possible like this before, because qcow2's repair function could not repair images with completely lost refcount information. This is now possible which makes this variant feasible. - Pulled patch 14 before patch 6; therefore, patch 14 is now patch 6 and patches 6 to 13 are now patches 7 to 14, respectively. I did this because patches 7 and 8 break several tests which are fixed by patch 14, so it makes sense to apply the fix before breaking the tests. - Adjusted patch 14 (previously 13) according to the changes to patch 3. In particular, images do not leak clusters when the emptying process fails, but are dirty (their refcount structure is broken) and need to be repaired (which is done automatically when they are opened). git-backport-diff output against v11: Key: [] : patches are identical [] : number of functional differences between upstream/downstream patch [down] : patch is downstream-only The flags [FC] indicate (F)unctional and (C)ontextual differences, respectively 001/14:[] [--] 'qcow2: Allow full discard' 002/14:[] [--] 'qcow2: Implement bdrv_make_empty()' 003/14:[0430] [FC] 'qcow2: Optimize bdrv_make_empty()' 004/14:[] [--] 'blockjob: Introduce block_job_complete_sync()' 005/14:[] [--] 'blockjob: Add ready field' 006/14:[] [--] 'iotests: Omit length/offset test in 040 and 041' 007/14:[] [--] 'block/mirror: Improve progress report' 008/14:[] [--] 'qemu-img: Implement commit like QMP' 009/14:[] [-C] 'qemu-img: Empty image after commit' 010/14:[] [--] 'qemu-img: Enable progress output for commit' 011/14:[] [-C] 'qemu-img: Specify backing file for commit' 012/14:[] [--] 'iotests: Add _filter_qemu_img_map' 013/14:[] [-C] 'iotests: Add test for backing-chain commits' 014/14:[0046] [FC] 'iotests: Add test for qcow2's bdrv_make_empty' Max Reitz (14): qcow2: Allow full discard qcow2: Implement bdrv_make_empty() qcow2: Optimize bdrv_make_empty() blockjob: Introduce block_job_complete_sync() blockjob: Add ready field iotests: Omit length/offset test in 040 and 041 block/mirror: Improve progress report qemu-img: Implement commit like QMP qemu-img: Empty image after commit qemu-img: Enable progress output for commit qemu-img: Specify backing file for commit iotests: Add _filter_qemu_img_map iotests: Add test for backing-chain commits iotests: Add test for qcow2's bdrv_make_empty block/Makefile.objs | 2 +- block/blkdebug.c | 2 + block/mirror.c | 34 + block/qcow2-cluster.c| 27 --- block/qcow2-snapshot.c | 2 +- block/qcow2.c| 136 ++- block/qcow2.h| 2 +- blockjob.c | 42 +-- include/block/block.h| 2 + include/block/blockjob.h | 20 ++ qapi/block-core.json | 4 +- qemu-img-cmds.hx | 4 +- qemu-img.c | 149 +-- qemu-img.texi| 13 +++- tests/qemu-iotests/040 | 4 +- tests/qemu-iotests/041 | 3 +- tests/qemu-iotests/097 | 122 tests/qemu-iotests/097.out | 119 +++ tests/qemu-iotests/098 | 78 tests/qemu-iotests/098.out | 45 tests/qemu-iotests/common.filter | 7 ++ tests/qemu-iotests/group | 2 +
Re: [Qemu-devel] [PATCH 0/3] block: Fix is_allocated() for truncated images
On 16.08.2014 20:54, Max Reitz wrote: Patch 2: The bdrv_is_allocated() functions may return a number of zero sectors e.g. if a sector beyond the image end has been queried. Respect this case in qemu-io's map implementation so it doesn't run into an infinite loop (https://bugs.launchpad.net/qemu/+bug/1356969). Patch 1: In that bug report, bdrv_co_get_block_status() fell through to the underlying file to get additional information (whether the sectors are zeroed). However, the offset reported by the image format (qcow2) was beyond the size of the underlying file and so this second query returned only zero clusters which replaced the actual number of sectors queried in the formatted (on qcow2 level) image. But because errors from this second call are ignored, the number of sector queried successfully should be ignored as well, which makes qemu-io -c map actually work for that bug report. Patch 3 adds a test for patch 1; I could not conceive a test for patch 2 which patch 1 would not already catch, but patch 2 should be simple enough not to require a test anyway. Thanks to patch 3, this series depends on my previous series [PATCH v10 00/14] qemu-img: Implement commit like QMP (strictly speaking only on patch 11 of that series which adds _filter_qemu_img_map() to tests/qemu-iotests/common.filter). Max Reitz (3): block: Ignore allocation size in underlying file qemu-io: Respect early image end for map iotests: Add test for map commands block.c| 6 +++-- qemu-io-cmds.c | 5 +++- tests/qemu-iotests/102 | 64 ++ tests/qemu-iotests/102.out | 11 tests/qemu-iotests/group | 1 + 5 files changed, 84 insertions(+), 3 deletions(-) create mode 100755 tests/qemu-iotests/102 create mode 100644 tests/qemu-iotests/102.out Ping.
Re: [Qemu-devel] [PATCH v5 02/33] target-arm: add arm_is_secure() function
Unfortunately, the arm_is_secure*() functions cannot be moved either as they are used within cpu.h. Greg On 6 October 2014 16:07, Peter Maydell peter.mayd...@linaro.org wrote: On 6 October 2014 21:47, Greg Bellows greg.bell...@linaro.org wrote: On 6 October 2014 15:07, Peter Maydell peter.mayd...@linaro.org wrote: You should use is_a64() rather than directly looking at env-aarch64, incidentally. Since I am touching arm_current_el(), should I go ahead and fix it to use is_a64() as well? Optional. I'll move in v6. Should I also go ahead and move arm_current_el() to internals.h as well since I am touching it? No. Let's try to keep the scope of this patchset under control. -- PMM
Re: [Qemu-devel] [PATCH v2 0/2] raw-posix: Fix raw_co_get_block_status()
On 22.09.2014 17:36, Max Reitz wrote: raw_co_get_block_status() should return 0 and set *pnum to 0 after the EOF; currently it does this merely by accident, so implement it directly. Also, nb_sectors should be clamped against the image end. While doing that, centralize the generation of raw_co_get_block_status()'s return value along the way. v2: - Patch 1: Clamp nb_sectors against image end - Patch 2: Fix alignment issue Max Reitz (2): raw-posix: Fix raw_co_get_block_status() after EOF raw-posix: raw_co_get_block_status() return value block/raw-posix.c | 36 ++-- 1 file changed, 22 insertions(+), 14 deletions(-) Ping. (This should be rather simple to review)
Re: [Qemu-devel] [PATCH v3 0/7] block/qcow2: Improve zero cluster expansion
On 15.08.2014 17:47, Max Reitz wrote: The main purpose of this series is to add a progress report to qemu-img amend. This is achieved by adding a callback function to bdrv_amend_options() - the reasons for this choice are explained in patch 1. While adapting qcow2's expand_zero_clusters_in_l1() accordingly, I noticed a way to simplify it and get rid of the rather ugly bitmap used there (patch 6). This series depends on v2 of my qemu-img: Allow source cache mode specification series. Changes from v2: - Patch 1: Fixed misspelling in the commit message [Eric] git-backport-diff against v2: Key: [] : patches are identical [] : number of functional differences between upstream/downstream patch [down] : patch is downstream-only The flags [FC] indicate (F)unctional and (C)ontextual differences, respectively 001/7:[] [--] 'block: Add status callback to bdrv_amend_options()' 002/7:[] [--] 'qemu-img: Add progress output for amend' 003/7:[] [--] 'qemu-img: Fix insignificant memleak' 004/7:[] [--] 'block/qcow2: Implement status CB for amend' 005/7:[] [--] 'block/qcow2: Make get_refcount() global' 006/7:[] [--] 'block/qcow2: Simplify shared L2 handling in amend' 007/7:[] [--] 'iotests: Expand test 061' Max Reitz (7): block: Add status callback to bdrv_amend_options() qemu-img: Add progress output for amend qemu-img: Fix insignificant memleak block/qcow2: Implement status CB for amend block/qcow2: Make get_refcount() global block/qcow2: Simplify shared L2 handling in amend iotests: Expand test 061 block.c| 5 +- block/qcow2-cluster.c | 115 ++--- block/qcow2-refcount.c | 26 +- block/qcow2.c | 10 ++-- block/qcow2.h | 5 +- include/block/block.h | 8 +++- include/block/block_int.h | 3 +- qemu-img-cmds.hx | 4 +- qemu-img.c | 29 ++-- qemu-img.texi | 2 +- tests/qemu-iotests/061 | 25 ++ tests/qemu-iotests/061.out | 30 tests/qemu-iotests/group | 2 +- 13 files changed, 174 insertions(+), 90 deletions(-) Ping. All patches have been reviewed by Eric and Benoît. Max
Re: [Qemu-devel] [PATCH][SPARC] LEON3: Add emulation of AMBA plugplay
On 10/08/2014 05:38 PM, Andreas Färber wrote: Hi, Am 08.10.2014 um 16:19 schrieb Fabien Chouteau: From: Jiri Gaisler j...@gaisler.se AMBA plugplay is used by kernels to probe available devices (Timers, UART, etc...). This is a static declaration of devices implemented in QEMU. In the future, a more advanced version could compute those information directly from the device tree. Interesting. There's quite some magic numbers in the read functions; I wonder if you could read them via QOM if you actually give the devices a canonical path or search by type? You may want to peek at ACPI code. The plugplay area is similar in function to the PCI configuration space, indicating vendor/device ID's, address range, interrupt number etc. of on-chip IP cores. The 'magic' numbers could be generated by generic functions taking these parameters as inputs. This would certainly make the code more readable, and easily extended in the future. Would such a solution be acceptable? Signed-off-by: Fabien Chouteau chout...@adacore.com --- hw/sparc/Makefile.objs |1 + hw/sparc/grlib_ambapnp.c | 206 ++ hw/sparc/leon3.c |6 ++ include/hw/sparc/grlib.h | 36 4 files changed, 249 insertions(+) create mode 100644 hw/sparc/grlib_ambapnp.c diff --git a/hw/sparc/Makefile.objs b/hw/sparc/Makefile.objs index c987b5b..e763701 100644 --- a/hw/sparc/Makefile.objs +++ b/hw/sparc/Makefile.objs @@ -1 +1,2 @@ obj-y += sun4m.o leon3.o +obj-$(CONFIG_GRLIB) += grlib_ambapnp.o diff --git a/hw/sparc/grlib_ambapnp.c b/hw/sparc/grlib_ambapnp.c new file mode 100644 index 000..dfadd5c --- /dev/null +++ b/hw/sparc/grlib_ambapnp.c @@ -0,0 +1,206 @@ +/* + * QEMU GRLIB AMBA PlugPlay Emulator + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the Software), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include hw/sysbus.h + +#define APBPNP_REG_SIZE 4096 /* Size of memory mapped registers */ + +#define TYPE_GRLIB_APB_PNP grlib,apbpnp If you move the two TYPE_* constants to grlib.h, you can reuse them. +#define GRLIB_APB_PNP(obj) \ +OBJECT_CHECK(APBPNP, (obj), TYPE_GRLIB_APB_PNP) + +typedef struct APBPNP { +SysBusDevice parent_obj; +MemoryRegion iomem; +} APBPNP; + +static uint64_t grlib_apbpnp_read(void *opaque, hwaddr addr, + unsigned size) Indentation is off by one for all read/write functions. +{ +uint64_t read_data; +addr = 0xfff; + +/* Unit registers */ +switch (addr 0xffc) { +case 0x00: +read_data = 0x0400f000; /* Memory controller */ +break; +case 0x04: +read_data = 0xfff1; +break; +case 0x08: +read_data = 0x0100c023; /* APBUART */ +break; +case 0x0C: +read_data = 0x0010fff1; +break; +case 0x10: +read_data = 0x0100d040; /* IRQMP */ +break; +case 0x14: +read_data = 0x0020fff1; +break; +case 0x18: +read_data = 0x01011006; /* GPTIMER */ +break; +case 0x1C: +read_data = 0x0030fff1; +break; + +default: +read_data = 0; +} +if (size == 1) { +read_data = (24 - (addr 3) * 8); +read_data = 0x0ff; +} +return read_data; +} + +static void grlib_apbpnp_write(void *opaque, hwaddr addr, +uint64_t value, unsigned size) +{ +} + +static const MemoryRegionOps grlib_apbpnp_ops = { +.write = grlib_apbpnp_write, +.read = grlib_apbpnp_read, +.endianness = DEVICE_NATIVE_ENDIAN, +}; + +static int grlib_apbpnp_init(SysBusDevice *dev) +{ +APBPNP *pnp = GRLIB_APB_PNP(dev); + +memory_region_init_io(pnp-iomem, OBJECT(pnp), grlib_apbpnp_ops, pnp, + apbpnp, APBPNP_REG_SIZE); + +sysbus_init_mmio(dev, pnp-iomem);