Compare commits
	
		
			57 Commits
		
	
	
		
			v2.4.0-rc0
			...
			pull-input
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 562f93754b | ||
|  | e2f6bac301 | ||
| 2a19b229f6 | |||
|  | 2d5ee9e7a7 | ||
|  | 3749c11a72 | ||
|  | be0df8cd1e | ||
|  | 3046bb5deb | ||
|  | d461a44ca4 | ||
|  | 672558d2ea | ||
|  | 7692401a08 | ||
|  | 76e2aef392 | ||
|  | e46e1a74ef | ||
|  | 711dc6f36b | ||
|  | 908680c644 | ||
|  | f01a361bfc | ||
|  | 26e7e982b2 | ||
|  | 47ada0ad34 | ||
|  | fe87c2b36a | ||
|  | 6a973e6b65 | ||
|  | 6b9c26fb5e | ||
|  | d4f4f0d5d9 | ||
|  | 4dc89b7820 | ||
|  | f5dec79ee8 | ||
|  | 560d027b54 | ||
|  | 9f5f380b54 | ||
|  | 48212d87d6 | ||
|  | 72e72e1a71 | ||
|  | 4ba4bc5e9b | ||
|  | 172c4356f3 | ||
|  | 796a060bc0 | ||
|  | 48ac0a4df8 | ||
|  | 17d9716d7b | ||
|  | 299bf09737 | ||
|  | 4c0cbd6fec | ||
|  | 661725da09 | ||
|  | 2af9170c8c | ||
|  | 0c7322cfd3 | ||
|  | f3947986d9 | ||
|  | e34d8f297d | ||
|  | 99a3c89d5d | ||
|  | 5a8ac6d9d7 | ||
|  | 3dbf00e058 | ||
|  | 80a1e13091 | ||
|  | 9a7dedbc43 | ||
|  | 33a604075c | ||
|  | b4b059f628 | ||
|  | df58179267 | ||
|  | 30349fd038 | ||
|  | 8b9d74e0ee | ||
|  | 0030ff4047 | ||
|  | a16951375f | ||
|  | f3a1b5068c | ||
|  | 4421c6a38a | ||
|  | 06c4670ff6 | ||
|  | 2a6391232f | ||
|  | 8aedc369c6 | ||
|  | 6e3c0c6edb | 
| @@ -1169,7 +1169,7 @@ S: Supported | ||||
| F: block/vmdk.c | ||||
|  | ||||
| RBD | ||||
| M: Josh Durgin <josh.durgin@inktank.com> | ||||
| M: Josh Durgin <jdurgin@redhat.com> | ||||
| M: Jeff Cody <jcody@redhat.com> | ||||
| L: qemu-block@nongnu.org | ||||
| S: Supported | ||||
|   | ||||
							
								
								
									
										164
									
								
								block.c
									
									
									
									
									
								
							
							
						
						
									
										164
									
								
								block.c
									
									
									
									
									
								
							| @@ -1102,12 +1102,46 @@ static int bdrv_fill_options(QDict **options, const char **pfilename, | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| static BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs, | ||||
|                                     BlockDriverState *child_bs, | ||||
|                                     const BdrvChildRole *child_role) | ||||
| { | ||||
|     BdrvChild *child = g_new(BdrvChild, 1); | ||||
|     *child = (BdrvChild) { | ||||
|         .bs     = child_bs, | ||||
|         .role   = child_role, | ||||
|     }; | ||||
|  | ||||
|     QLIST_INSERT_HEAD(&parent_bs->children, child, next); | ||||
|  | ||||
|     return child; | ||||
| } | ||||
|  | ||||
| static void bdrv_detach_child(BdrvChild *child) | ||||
| { | ||||
|     QLIST_REMOVE(child, next); | ||||
|     g_free(child); | ||||
| } | ||||
|  | ||||
| void bdrv_unref_child(BlockDriverState *parent, BdrvChild *child) | ||||
| { | ||||
|     BlockDriverState *child_bs = child->bs; | ||||
|  | ||||
|     if (child->bs->inherits_from == parent) { | ||||
|         child->bs->inherits_from = NULL; | ||||
|     } | ||||
|  | ||||
|     bdrv_detach_child(child); | ||||
|     bdrv_unref(child_bs); | ||||
| } | ||||
|  | ||||
| void bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd) | ||||
| { | ||||
|  | ||||
|     if (bs->backing_hd) { | ||||
|         assert(bs->backing_blocker); | ||||
|         bdrv_op_unblock_all(bs->backing_hd, bs->backing_blocker); | ||||
|         bdrv_detach_child(bs->backing_child); | ||||
|     } else if (backing_hd) { | ||||
|         error_setg(&bs->backing_blocker, | ||||
|                    "node is used as backing hd of '%s'", | ||||
| @@ -1118,8 +1152,10 @@ void bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd) | ||||
|     if (!backing_hd) { | ||||
|         error_free(bs->backing_blocker); | ||||
|         bs->backing_blocker = NULL; | ||||
|         bs->backing_child = NULL; | ||||
|         goto out; | ||||
|     } | ||||
|     bs->backing_child = bdrv_attach_child(bs, backing_hd, &child_backing); | ||||
|     bs->open_flags &= ~BDRV_O_NO_BACKING; | ||||
|     pstrcpy(bs->backing_file, sizeof(bs->backing_file), backing_hd->filename); | ||||
|     pstrcpy(bs->backing_format, sizeof(bs->backing_format), | ||||
| @@ -1202,6 +1238,7 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp) | ||||
|         error_free(local_err); | ||||
|         goto free_exit; | ||||
|     } | ||||
|  | ||||
|     bdrv_set_backing_hd(bs, backing_hd); | ||||
|  | ||||
| free_exit: | ||||
| @@ -1214,7 +1251,7 @@ free_exit: | ||||
|  * device's options. | ||||
|  * | ||||
|  * If allow_none is true, no image will be opened if filename is false and no | ||||
|  * BlockdevRef is given. *pbs will remain unchanged and 0 will be returned. | ||||
|  * BlockdevRef is given. NULL will be returned, but errp remains unset. | ||||
|  * | ||||
|  * bdrev_key specifies the key for the image's BlockdevRef in the options QDict. | ||||
|  * That QDict has to be flattened; therefore, if the BlockdevRef is a QDict | ||||
| @@ -1222,6 +1259,56 @@ free_exit: | ||||
|  * BlockdevRef. | ||||
|  * | ||||
|  * The BlockdevRef will be removed from the options QDict. | ||||
|  */ | ||||
| BdrvChild *bdrv_open_child(const char *filename, | ||||
|                            QDict *options, const char *bdref_key, | ||||
|                            BlockDriverState* parent, | ||||
|                            const BdrvChildRole *child_role, | ||||
|                            bool allow_none, Error **errp) | ||||
| { | ||||
|     BdrvChild *c = NULL; | ||||
|     BlockDriverState *bs; | ||||
|     QDict *image_options; | ||||
|     int ret; | ||||
|     char *bdref_key_dot; | ||||
|     const char *reference; | ||||
|  | ||||
|     assert(child_role != NULL); | ||||
|  | ||||
|     bdref_key_dot = g_strdup_printf("%s.", bdref_key); | ||||
|     qdict_extract_subqdict(options, &image_options, bdref_key_dot); | ||||
|     g_free(bdref_key_dot); | ||||
|  | ||||
|     reference = qdict_get_try_str(options, bdref_key); | ||||
|     if (!filename && !reference && !qdict_size(image_options)) { | ||||
|         if (!allow_none) { | ||||
|             error_setg(errp, "A block device must be specified for \"%s\"", | ||||
|                        bdref_key); | ||||
|         } | ||||
|         QDECREF(image_options); | ||||
|         goto done; | ||||
|     } | ||||
|  | ||||
|     bs = NULL; | ||||
|     ret = bdrv_open_inherit(&bs, filename, reference, image_options, 0, | ||||
|                             parent, child_role, NULL, errp); | ||||
|     if (ret < 0) { | ||||
|         goto done; | ||||
|     } | ||||
|  | ||||
|     c = bdrv_attach_child(parent, bs, child_role); | ||||
|  | ||||
| done: | ||||
|     qdict_del(options, bdref_key); | ||||
|     return c; | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * This is a version of bdrv_open_child() that returns 0/-EINVAL instead of | ||||
|  * a BdrvChild object. | ||||
|  * | ||||
|  * If allow_none is true, no image will be opened if filename is false and no | ||||
|  * BlockdevRef is given. *pbs will remain unchanged and 0 will be returned. | ||||
|  * | ||||
|  * To conform with the behavior of bdrv_open(), *pbs has to be NULL. | ||||
|  */ | ||||
| @@ -1230,37 +1317,24 @@ int bdrv_open_image(BlockDriverState **pbs, const char *filename, | ||||
|                     BlockDriverState* parent, const BdrvChildRole *child_role, | ||||
|                     bool allow_none, Error **errp) | ||||
| { | ||||
|     QDict *image_options; | ||||
|     int ret; | ||||
|     char *bdref_key_dot; | ||||
|     const char *reference; | ||||
|     Error *local_err = NULL; | ||||
|     BdrvChild *c; | ||||
|  | ||||
|     assert(pbs); | ||||
|     assert(*pbs == NULL); | ||||
|  | ||||
|     bdref_key_dot = g_strdup_printf("%s.", bdref_key); | ||||
|     qdict_extract_subqdict(options, &image_options, bdref_key_dot); | ||||
|     g_free(bdref_key_dot); | ||||
|  | ||||
|     reference = qdict_get_try_str(options, bdref_key); | ||||
|     if (!filename && !reference && !qdict_size(image_options)) { | ||||
|         if (allow_none) { | ||||
|             ret = 0; | ||||
|         } else { | ||||
|             error_setg(errp, "A block device must be specified for \"%s\"", | ||||
|                        bdref_key); | ||||
|             ret = -EINVAL; | ||||
|         } | ||||
|         QDECREF(image_options); | ||||
|         goto done; | ||||
|     c = bdrv_open_child(filename, options, bdref_key, parent, child_role, | ||||
|                         allow_none, &local_err); | ||||
|     if (local_err) { | ||||
|         error_propagate(errp, local_err); | ||||
|         return -EINVAL; | ||||
|     } | ||||
|  | ||||
|     ret = bdrv_open_inherit(pbs, filename, reference, image_options, 0, | ||||
|                             parent, child_role, NULL, errp); | ||||
|     if (c != NULL) { | ||||
|         *pbs = c->bs; | ||||
|     } | ||||
|  | ||||
| done: | ||||
|     qdict_del(options, bdref_key); | ||||
|     return ret; | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| int bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, Error **errp) | ||||
| @@ -1328,19 +1402,6 @@ out: | ||||
|     return ret; | ||||
| } | ||||
|  | ||||
| static void bdrv_attach_child(BlockDriverState *parent_bs, | ||||
|                               BlockDriverState *child_bs, | ||||
|                               const BdrvChildRole *child_role) | ||||
| { | ||||
|     BdrvChild *child = g_new(BdrvChild, 1); | ||||
|     *child = (BdrvChild) { | ||||
|         .bs     = child_bs, | ||||
|         .role   = child_role, | ||||
|     }; | ||||
|  | ||||
|     QLIST_INSERT_HEAD(&parent_bs->children, child, next); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Opens a disk image (raw, qcow2, vmdk, ...) | ||||
|  * | ||||
| @@ -1393,9 +1454,6 @@ static int bdrv_open_inherit(BlockDriverState **pbs, const char *filename, | ||||
|             return -ENODEV; | ||||
|         } | ||||
|         bdrv_ref(bs); | ||||
|         if (child_role) { | ||||
|             bdrv_attach_child(parent, bs, child_role); | ||||
|         } | ||||
|         *pbs = bs; | ||||
|         return 0; | ||||
|     } | ||||
| @@ -1540,10 +1598,6 @@ static int bdrv_open_inherit(BlockDriverState **pbs, const char *filename, | ||||
|         goto close_and_fail; | ||||
|     } | ||||
|  | ||||
|     if (child_role) { | ||||
|         bdrv_attach_child(parent, bs, child_role); | ||||
|     } | ||||
|  | ||||
|     QDECREF(options); | ||||
|     *pbs = bs; | ||||
|     return 0; | ||||
| @@ -1849,20 +1903,23 @@ void bdrv_close(BlockDriverState *bs) | ||||
|     if (bs->drv) { | ||||
|         BdrvChild *child, *next; | ||||
|  | ||||
|         QLIST_FOREACH_SAFE(child, &bs->children, next, next) { | ||||
|             if (child->bs->inherits_from == bs) { | ||||
|                 child->bs->inherits_from = NULL; | ||||
|             } | ||||
|             QLIST_REMOVE(child, next); | ||||
|             g_free(child); | ||||
|         } | ||||
|         bs->drv->bdrv_close(bs); | ||||
|  | ||||
|         if (bs->backing_hd) { | ||||
|             BlockDriverState *backing_hd = bs->backing_hd; | ||||
|             bdrv_set_backing_hd(bs, NULL); | ||||
|             bdrv_unref(backing_hd); | ||||
|         } | ||||
|         bs->drv->bdrv_close(bs); | ||||
|  | ||||
|         QLIST_FOREACH_SAFE(child, &bs->children, next, next) { | ||||
|             /* TODO Remove bdrv_unref() from drivers' close function and use | ||||
|              * bdrv_unref_child() here */ | ||||
|             if (child->bs->inherits_from == bs) { | ||||
|                 child->bs->inherits_from = NULL; | ||||
|             } | ||||
|             bdrv_detach_child(child); | ||||
|         } | ||||
|  | ||||
|         g_free(bs->opaque); | ||||
|         bs->opaque = NULL; | ||||
|         bs->drv = NULL; | ||||
| @@ -2116,7 +2173,6 @@ void bdrv_append(BlockDriverState *bs_new, BlockDriverState *bs_top) | ||||
|     /* The contents of 'tmp' will become bs_top, as we are | ||||
|      * swapping bs_new and bs_top contents. */ | ||||
|     bdrv_set_backing_hd(bs_top, bs_new); | ||||
|     bdrv_attach_child(bs_top, bs_new, &child_backing); | ||||
| } | ||||
|  | ||||
| static void bdrv_delete(BlockDriverState *bs) | ||||
|   | ||||
| @@ -431,7 +431,7 @@ static void coroutine_fn backup_run(void *opaque) | ||||
|  | ||||
|     if (job->sync_bitmap) { | ||||
|         BdrvDirtyBitmap *bm; | ||||
|         if (ret < 0) { | ||||
|         if (ret < 0 || block_job_is_cancelled(&job->common)) { | ||||
|             /* Merge the successor back into the parent, delete nothing. */ | ||||
|             bm = bdrv_reclaim_dirty_bitmap(bs, job->sync_bitmap, NULL); | ||||
|             assert(bm); | ||||
|   | ||||
							
								
								
									
										15
									
								
								block/curl.c
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								block/curl.c
									
									
									
									
									
								
							| @@ -22,6 +22,7 @@ | ||||
|  * THE SOFTWARE. | ||||
|  */ | ||||
| #include "qemu-common.h" | ||||
| #include "qemu/error-report.h" | ||||
| #include "block/block_int.h" | ||||
| #include "qapi/qmp/qbool.h" | ||||
| #include "qapi/qmp/qstring.h" | ||||
| @@ -298,6 +299,18 @@ static void curl_multi_check_completion(BDRVCURLState *s) | ||||
|             /* ACBs for successful messages get completed in curl_read_cb */ | ||||
|             if (msg->data.result != CURLE_OK) { | ||||
|                 int i; | ||||
|                 static int errcount = 100; | ||||
|  | ||||
|                 /* Don't lose the original error message from curl, since | ||||
|                  * it contains extra data. | ||||
|                  */ | ||||
|                 if (errcount > 0) { | ||||
|                     error_report("curl: %s", state->errmsg); | ||||
|                     if (--errcount == 0) { | ||||
|                         error_report("curl: further errors suppressed"); | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 for (i = 0; i < CURL_NUM_ACB; i++) { | ||||
|                     CURLAIOCB *acb = state->acb[i]; | ||||
|  | ||||
| @@ -305,7 +318,7 @@ static void curl_multi_check_completion(BDRVCURLState *s) | ||||
|                         continue; | ||||
|                     } | ||||
|  | ||||
|                     acb->common.cb(acb->common.opaque, -EIO); | ||||
|                     acb->common.cb(acb->common.opaque, -EPROTO); | ||||
|                     qemu_aio_unref(acb); | ||||
|                     state->acb[i] = NULL; | ||||
|                 } | ||||
|   | ||||
| @@ -20,6 +20,7 @@ | ||||
|  | ||||
| #define SLICE_TIME    100000000ULL /* ns */ | ||||
| #define MAX_IN_FLIGHT 16 | ||||
| #define DEFAULT_MIRROR_BUF_SIZE   (10 << 20) | ||||
|  | ||||
| /* The mirroring buffer is a list of granularity-sized chunks. | ||||
|  * Free chunks are organized in a list. | ||||
| @@ -444,11 +445,23 @@ static void coroutine_fn mirror_run(void *opaque) | ||||
|     sectors_per_chunk = s->granularity >> BDRV_SECTOR_BITS; | ||||
|     mirror_free_init(s); | ||||
|  | ||||
|     last_pause_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME); | ||||
|     if (!s->is_none_mode) { | ||||
|         /* First part, loop on the sectors and initialize the dirty bitmap.  */ | ||||
|         BlockDriverState *base = s->base; | ||||
|         for (sector_num = 0; sector_num < end; ) { | ||||
|             int64_t next = (sector_num | (sectors_per_chunk - 1)) + 1; | ||||
|             int64_t now = qemu_clock_get_ns(QEMU_CLOCK_REALTIME); | ||||
|  | ||||
|             if (now - last_pause_ns > SLICE_TIME) { | ||||
|                 last_pause_ns = now; | ||||
|                 block_job_sleep_ns(&s->common, QEMU_CLOCK_REALTIME, 0); | ||||
|             } | ||||
|  | ||||
|             if (block_job_is_cancelled(&s->common)) { | ||||
|                 goto immediate_exit; | ||||
|             } | ||||
|  | ||||
|             ret = bdrv_is_allocated_above(bs, base, | ||||
|                                           sector_num, next - sector_num, &n); | ||||
|  | ||||
| @@ -467,7 +480,6 @@ static void coroutine_fn mirror_run(void *opaque) | ||||
|     } | ||||
|  | ||||
|     bdrv_dirty_iter_init(s->dirty_bitmap, &s->hbi); | ||||
|     last_pause_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME); | ||||
|     for (;;) { | ||||
|         uint64_t delay_ns = 0; | ||||
|         int64_t cnt; | ||||
| @@ -690,6 +702,14 @@ static void mirror_start_job(BlockDriverState *bs, BlockDriverState *target, | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     if (buf_size < 0) { | ||||
|         error_setg(errp, "Invalid parameter 'buf-size'"); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     if (buf_size == 0) { | ||||
|         buf_size = DEFAULT_MIRROR_BUF_SIZE; | ||||
|     } | ||||
|  | ||||
|     s = block_job_create(driver, bs, speed, cb, opaque, errp); | ||||
|     if (!s) { | ||||
| @@ -703,7 +723,7 @@ static void mirror_start_job(BlockDriverState *bs, BlockDriverState *target, | ||||
|     s->is_none_mode = is_none_mode; | ||||
|     s->base = base; | ||||
|     s->granularity = granularity; | ||||
|     s->buf_size = MAX(buf_size, granularity); | ||||
|     s->buf_size = ROUND_UP(buf_size, granularity); | ||||
|     s->unmap = unmap; | ||||
|  | ||||
|     s->dirty_bitmap = bdrv_create_dirty_bitmap(bs, granularity, NULL, errp); | ||||
|   | ||||
							
								
								
									
										64
									
								
								block/rbd.c
									
									
									
									
									
								
							
							
						
						
									
										64
									
								
								block/rbd.c
									
									
									
									
									
								
							| @@ -74,25 +74,18 @@ typedef struct RBDAIOCB { | ||||
|     QEMUIOVector *qiov; | ||||
|     char *bounce; | ||||
|     RBDAIOCmd cmd; | ||||
|     int64_t sector_num; | ||||
|     int error; | ||||
|     struct BDRVRBDState *s; | ||||
|     int status; | ||||
| } RBDAIOCB; | ||||
|  | ||||
| typedef struct RADOSCB { | ||||
|     int rcbid; | ||||
|     RBDAIOCB *acb; | ||||
|     struct BDRVRBDState *s; | ||||
|     int done; | ||||
|     int64_t size; | ||||
|     char *buf; | ||||
|     int64_t ret; | ||||
| } RADOSCB; | ||||
|  | ||||
| #define RBD_FD_READ 0 | ||||
| #define RBD_FD_WRITE 1 | ||||
|  | ||||
| typedef struct BDRVRBDState { | ||||
|     rados_t cluster; | ||||
|     rados_ioctx_t io_ctx; | ||||
| @@ -235,7 +228,9 @@ static char *qemu_rbd_parse_clientname(const char *conf, char *clientname) | ||||
|     return NULL; | ||||
| } | ||||
|  | ||||
| static int qemu_rbd_set_conf(rados_t cluster, const char *conf, Error **errp) | ||||
| static int qemu_rbd_set_conf(rados_t cluster, const char *conf, | ||||
|                              bool only_read_conf_file, | ||||
|                              Error **errp) | ||||
| { | ||||
|     char *p, *buf; | ||||
|     char name[RBD_MAX_CONF_NAME_SIZE]; | ||||
| @@ -267,14 +262,18 @@ static int qemu_rbd_set_conf(rados_t cluster, const char *conf, Error **errp) | ||||
|         qemu_rbd_unescape(value); | ||||
|  | ||||
|         if (strcmp(name, "conf") == 0) { | ||||
|             ret = rados_conf_read_file(cluster, value); | ||||
|             if (ret < 0) { | ||||
|                 error_setg(errp, "error reading conf file %s", value); | ||||
|                 break; | ||||
|             /* read the conf file alone, so it doesn't override more | ||||
|                specific settings for a particular device */ | ||||
|             if (only_read_conf_file) { | ||||
|                 ret = rados_conf_read_file(cluster, value); | ||||
|                 if (ret < 0) { | ||||
|                     error_setg(errp, "error reading conf file %s", value); | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|         } else if (strcmp(name, "id") == 0) { | ||||
|             /* ignore, this is parsed by qemu_rbd_parse_clientname() */ | ||||
|         } else { | ||||
|         } else if (!only_read_conf_file) { | ||||
|             ret = rados_conf_set(cluster, name, value); | ||||
|             if (ret < 0) { | ||||
|                 error_setg(errp, "invalid conf option %s", name); | ||||
| @@ -337,10 +336,15 @@ static int qemu_rbd_create(const char *filename, QemuOpts *opts, Error **errp) | ||||
|     if (strstr(conf, "conf=") == NULL) { | ||||
|         /* try default location, but ignore failure */ | ||||
|         rados_conf_read_file(cluster, NULL); | ||||
|     } else if (conf[0] != '\0' && | ||||
|                qemu_rbd_set_conf(cluster, conf, true, &local_err) < 0) { | ||||
|         rados_shutdown(cluster); | ||||
|         error_propagate(errp, local_err); | ||||
|         return -EIO; | ||||
|     } | ||||
|  | ||||
|     if (conf[0] != '\0' && | ||||
|         qemu_rbd_set_conf(cluster, conf, &local_err) < 0) { | ||||
|         qemu_rbd_set_conf(cluster, conf, false, &local_err) < 0) { | ||||
|         rados_shutdown(cluster); | ||||
|         error_propagate(errp, local_err); | ||||
|         return -EIO; | ||||
| @@ -405,7 +409,6 @@ static void qemu_rbd_complete_aio(RADOSCB *rcb) | ||||
|     } | ||||
|     qemu_vfree(acb->bounce); | ||||
|     acb->common.cb(acb->common.opaque, (acb->ret > 0 ? 0 : acb->ret)); | ||||
|     acb->status = 0; | ||||
|  | ||||
|     qemu_aio_unref(acb); | ||||
| } | ||||
| @@ -468,6 +471,23 @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags, | ||||
|         s->snap = g_strdup(snap_buf); | ||||
|     } | ||||
|  | ||||
|     if (strstr(conf, "conf=") == NULL) { | ||||
|         /* try default location, but ignore failure */ | ||||
|         rados_conf_read_file(s->cluster, NULL); | ||||
|     } else if (conf[0] != '\0') { | ||||
|         r = qemu_rbd_set_conf(s->cluster, conf, true, errp); | ||||
|         if (r < 0) { | ||||
|             goto failed_shutdown; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if (conf[0] != '\0') { | ||||
|         r = qemu_rbd_set_conf(s->cluster, conf, false, errp); | ||||
|         if (r < 0) { | ||||
|             goto failed_shutdown; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /* | ||||
|      * Fallback to more conservative semantics if setting cache | ||||
|      * options fails. Ignore errors from setting rbd_cache because the | ||||
| @@ -481,18 +501,6 @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags, | ||||
|         rados_conf_set(s->cluster, "rbd_cache", "true"); | ||||
|     } | ||||
|  | ||||
|     if (strstr(conf, "conf=") == NULL) { | ||||
|         /* try default location, but ignore failure */ | ||||
|         rados_conf_read_file(s->cluster, NULL); | ||||
|     } | ||||
|  | ||||
|     if (conf[0] != '\0') { | ||||
|         r = qemu_rbd_set_conf(s->cluster, conf, errp); | ||||
|         if (r < 0) { | ||||
|             goto failed_shutdown; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     r = rados_connect(s->cluster); | ||||
|     if (r < 0) { | ||||
|         error_setg(errp, "error connecting"); | ||||
| @@ -621,7 +629,6 @@ static BlockAIOCB *rbd_start_aio(BlockDriverState *bs, | ||||
|     acb->error = 0; | ||||
|     acb->s = s; | ||||
|     acb->bh = NULL; | ||||
|     acb->status = -EINPROGRESS; | ||||
|  | ||||
|     if (cmd == RBD_AIO_WRITE) { | ||||
|         qemu_iovec_to_buf(acb->qiov, 0, acb->bounce, qiov->size); | ||||
| @@ -633,7 +640,6 @@ static BlockAIOCB *rbd_start_aio(BlockDriverState *bs, | ||||
|     size = nb_sectors * BDRV_SECTOR_SIZE; | ||||
|  | ||||
|     rcb = g_new(RADOSCB, 1); | ||||
|     rcb->done = 0; | ||||
|     rcb->acb = acb; | ||||
|     rcb->buf = buf; | ||||
|     rcb->s = acb->s; | ||||
|   | ||||
| @@ -2380,9 +2380,6 @@ void qmp_block_commit(const char *device, | ||||
|     aio_context = bdrv_get_aio_context(bs); | ||||
|     aio_context_acquire(aio_context); | ||||
|  | ||||
|     /* drain all i/o before commits */ | ||||
|     bdrv_drain_all(); | ||||
|  | ||||
|     if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_COMMIT_SOURCE, errp)) { | ||||
|         goto out; | ||||
|     } | ||||
| @@ -2642,8 +2639,6 @@ out: | ||||
|     aio_context_release(aio_context); | ||||
| } | ||||
|  | ||||
| #define DEFAULT_MIRROR_BUF_SIZE   (10 << 20) | ||||
|  | ||||
| void qmp_drive_mirror(const char *device, const char *target, | ||||
|                       bool has_format, const char *format, | ||||
|                       bool has_node_name, const char *node_name, | ||||
| @@ -2685,7 +2680,7 @@ void qmp_drive_mirror(const char *device, const char *target, | ||||
|         granularity = 0; | ||||
|     } | ||||
|     if (!has_buf_size) { | ||||
|         buf_size = DEFAULT_MIRROR_BUF_SIZE; | ||||
|         buf_size = 0; | ||||
|     } | ||||
|     if (!has_unmap) { | ||||
|         unmap = true; | ||||
|   | ||||
							
								
								
									
										12
									
								
								disas/mips.c
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								disas/mips.c
									
									
									
									
									
								
							| @@ -1296,12 +1296,12 @@ const struct mips_opcode mips_builtin_opcodes[] = | ||||
| {"dmod",    "d,s,t",    0x000000de, 0xfc0007ff, WR_d|RD_s|RD_t,       0, I64R6}, | ||||
| {"ddivu",   "d,s,t",    0x0000009f, 0xfc0007ff, WR_d|RD_s|RD_t,       0, I64R6}, | ||||
| {"dmodu",   "d,s,t",    0x000000df, 0xfc0007ff, WR_d|RD_s|RD_t,       0, I64R6}, | ||||
| {"ll",      "t,o(b)",   0x7c000036, 0xfc00007f, LDD|RD_b|WR_t,        0, I32R6}, | ||||
| {"sc",      "t,o(b)",   0x7c000026, 0xfc00007f, LDD|RD_b|WR_t,        0, I32R6}, | ||||
| {"lld",     "t,o(b)",   0x7c000037, 0xfc00007f, LDD|RD_b|WR_t,        0, I64R6}, | ||||
| {"scd",     "t,o(b)",   0x7c000027, 0xfc00007f, LDD|RD_b|WR_t,        0, I64R6}, | ||||
| {"pref",    "h,o(b)",   0x7c000035, 0xfc00007f, RD_b,                 0, I32R6}, | ||||
| {"cache",   "k,o(b)",   0x7c000025, 0xfc00007f, RD_b,                 0, I32R6}, | ||||
| {"ll",      "t,+o(b)",  0x7c000036, 0xfc00007f, LDD|RD_b|WR_t,        0, I32R6}, | ||||
| {"sc",      "t,+o(b)",  0x7c000026, 0xfc00007f, LDD|RD_b|WR_t,        0, I32R6}, | ||||
| {"lld",     "t,+o(b)",  0x7c000037, 0xfc00007f, LDD|RD_b|WR_t,        0, I64R6}, | ||||
| {"scd",     "t,+o(b)",  0x7c000027, 0xfc00007f, LDD|RD_b|WR_t,        0, I64R6}, | ||||
| {"pref",    "h,+o(b)",  0x7c000035, 0xfc00007f, RD_b,                 0, I32R6}, | ||||
| {"cache",   "k,+o(b)",  0x7c000025, 0xfc00007f, RD_b,                 0, I32R6}, | ||||
| {"seleqz",  "d,v,t",    0x00000035, 0xfc0007ff, WR_d|RD_s|RD_t,       0, I32R6}, | ||||
| {"selnez",  "d,v,t",    0x00000037, 0xfc0007ff, WR_d|RD_s|RD_t,       0, I32R6}, | ||||
| {"maddf.s", "D,S,T",    0x46000018, 0xffe0003f, WR_D|RD_S|RD_T|FP_S,  0, I32R6}, | ||||
|   | ||||
| @@ -735,12 +735,28 @@ static void arm_load_kernel_notify(Notifier *notifier, void *data) | ||||
|          * we point to the kernel args. | ||||
|          */ | ||||
|         if (have_dtb(info)) { | ||||
|             /* Place the DTB after the initrd in memory. Note that some | ||||
|              * kernels will trash anything in the 4K page the initrd | ||||
|              * ends in, so make sure the DTB isn't caught up in that. | ||||
|              */ | ||||
|             hwaddr dtb_start = QEMU_ALIGN_UP(info->initrd_start + initrd_size, | ||||
|                                              4096); | ||||
|             hwaddr align; | ||||
|             hwaddr dtb_start; | ||||
|  | ||||
|             if (elf_machine == EM_AARCH64) { | ||||
|                 /* | ||||
|                  * Some AArch64 kernels on early bootup map the fdt region as | ||||
|                  * | ||||
|                  *   [ ALIGN_DOWN(fdt, 2MB) ... ALIGN_DOWN(fdt, 2MB) + 2MB ] | ||||
|                  * | ||||
|                  * Let's play safe and prealign it to 2MB to give us some space. | ||||
|                  */ | ||||
|                 align = 2 * 1024 * 1024; | ||||
|             } else { | ||||
|                 /* | ||||
|                  * Some 32bit kernels will trash anything in the 4K page the | ||||
|                  * initrd ends in, so make sure the DTB isn't caught up in that. | ||||
|                  */ | ||||
|                 align = 4096; | ||||
|             } | ||||
|  | ||||
|             /* Place the DTB after the initrd in memory with alignment. */ | ||||
|             dtb_start = QEMU_ALIGN_UP(info->initrd_start + initrd_size, align); | ||||
|             if (load_dtb(dtb_start, info, 0) < 0) { | ||||
|                 exit(1); | ||||
|             } | ||||
|   | ||||
| @@ -207,11 +207,23 @@ static void nvme_rw_cb(void *opaque, int ret) | ||||
|     } else { | ||||
|         req->status = NVME_INTERNAL_DEV_ERROR; | ||||
|     } | ||||
|  | ||||
|     qemu_sglist_destroy(&req->qsg); | ||||
|     if (req->has_sg) { | ||||
|         qemu_sglist_destroy(&req->qsg); | ||||
|     } | ||||
|     nvme_enqueue_req_completion(cq, req); | ||||
| } | ||||
|  | ||||
| static uint16_t nvme_flush(NvmeCtrl *n, NvmeNamespace *ns, NvmeCmd *cmd, | ||||
|     NvmeRequest *req) | ||||
| { | ||||
|     req->has_sg = false; | ||||
|     block_acct_start(blk_get_stats(n->conf.blk), &req->acct, 0, | ||||
|          BLOCK_ACCT_FLUSH); | ||||
|     req->aiocb = blk_aio_flush(n->conf.blk, nvme_rw_cb, req); | ||||
|  | ||||
|     return NVME_NO_COMPLETE; | ||||
| } | ||||
|  | ||||
| static uint16_t nvme_rw(NvmeCtrl *n, NvmeNamespace *ns, NvmeCmd *cmd, | ||||
|     NvmeRequest *req) | ||||
| { | ||||
| @@ -235,6 +247,7 @@ static uint16_t nvme_rw(NvmeCtrl *n, NvmeNamespace *ns, NvmeCmd *cmd, | ||||
|     } | ||||
|     assert((nlb << data_shift) == req->qsg.size); | ||||
|  | ||||
|     req->has_sg = true; | ||||
|     dma_acct_start(n->conf.blk, &req->acct, &req->qsg, | ||||
|                    is_write ? BLOCK_ACCT_WRITE : BLOCK_ACCT_READ); | ||||
|     req->aiocb = is_write ? | ||||
| @@ -256,7 +269,7 @@ static uint16_t nvme_io_cmd(NvmeCtrl *n, NvmeCmd *cmd, NvmeRequest *req) | ||||
|     ns = &n->namespaces[nsid - 1]; | ||||
|     switch (cmd->opcode) { | ||||
|     case NVME_CMD_FLUSH: | ||||
|         return NVME_SUCCESS; | ||||
|         return nvme_flush(n, ns, cmd, req); | ||||
|     case NVME_CMD_WRITE: | ||||
|     case NVME_CMD_READ: | ||||
|         return nvme_rw(n, ns, cmd, req); | ||||
| @@ -474,26 +487,32 @@ static uint16_t nvme_identify(NvmeCtrl *n, NvmeCmd *cmd) | ||||
| static uint16_t nvme_get_feature(NvmeCtrl *n, NvmeCmd *cmd, NvmeRequest *req) | ||||
| { | ||||
|     uint32_t dw10 = le32_to_cpu(cmd->cdw10); | ||||
|     uint32_t result; | ||||
|  | ||||
|     switch (dw10) { | ||||
|     case NVME_NUMBER_OF_QUEUES: | ||||
|         req->cqe.result = | ||||
|             cpu_to_le32((n->num_queues - 1) | ((n->num_queues - 1) << 16)); | ||||
|         break; | ||||
|     case NVME_VOLATILE_WRITE_CACHE: | ||||
|         req->cqe.result = cpu_to_le32(1); | ||||
|         result = blk_enable_write_cache(n->conf.blk); | ||||
|         break; | ||||
|     case NVME_NUMBER_OF_QUEUES: | ||||
|         result = cpu_to_le32((n->num_queues - 1) | ((n->num_queues - 1) << 16)); | ||||
|         break; | ||||
|     default: | ||||
|         return NVME_INVALID_FIELD | NVME_DNR; | ||||
|     } | ||||
|  | ||||
|     req->cqe.result = result; | ||||
|     return NVME_SUCCESS; | ||||
| } | ||||
|  | ||||
| static uint16_t nvme_set_feature(NvmeCtrl *n, NvmeCmd *cmd, NvmeRequest *req) | ||||
| { | ||||
|     uint32_t dw10 = le32_to_cpu(cmd->cdw10); | ||||
|     uint32_t dw11 = le32_to_cpu(cmd->cdw11); | ||||
|  | ||||
|     switch (dw10) { | ||||
|     case NVME_VOLATILE_WRITE_CACHE: | ||||
|         blk_set_enable_write_cache(n->conf.blk, dw11 & 1); | ||||
|         break; | ||||
|     case NVME_NUMBER_OF_QUEUES: | ||||
|         req->cqe.result = | ||||
|             cpu_to_le32((n->num_queues - 1) | ((n->num_queues - 1) << 16)); | ||||
| @@ -818,6 +837,9 @@ static int nvme_init(PCIDevice *pci_dev) | ||||
|     id->psd[0].mp = cpu_to_le16(0x9c4); | ||||
|     id->psd[0].enlat = cpu_to_le32(0x10); | ||||
|     id->psd[0].exlat = cpu_to_le32(0x4); | ||||
|     if (blk_enable_write_cache(n->conf.blk)) { | ||||
|         id->vwc = 1; | ||||
|     } | ||||
|  | ||||
|     n->bar.cap = 0; | ||||
|     NVME_CAP_SET_MQES(n->bar.cap, 0x7ff); | ||||
|   | ||||
| @@ -638,6 +638,7 @@ typedef struct NvmeRequest { | ||||
|     struct NvmeSQueue       *sq; | ||||
|     BlockAIOCB              *aiocb; | ||||
|     uint16_t                status; | ||||
|     bool                    has_sg; | ||||
|     NvmeCqe                 cqe; | ||||
|     BlockAcctCookie         acct; | ||||
|     QEMUSGList              qsg; | ||||
|   | ||||
| @@ -130,7 +130,7 @@ PropertyInfo qdev_prop_bit = { | ||||
|  | ||||
| static uint64_t qdev_get_prop_mask64(Property *prop) | ||||
| { | ||||
|     assert(prop->info == &qdev_prop_bit); | ||||
|     assert(prop->info == &qdev_prop_bit64); | ||||
|     return 0x1ull << prop->bitnr; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -492,7 +492,7 @@ DEFINE_I440FX_MACHINE(v2_4, "pc-i440fx-2.4", NULL, | ||||
|  | ||||
| static void pc_i440fx_2_3_machine_options(MachineClass *m) | ||||
| { | ||||
|     pc_i440fx_machine_options(m); | ||||
|     pc_i440fx_2_4_machine_options(m); | ||||
|     m->alias = NULL; | ||||
|     m->is_default = 0; | ||||
|     SET_MACHINE_COMPAT(m, PC_COMPAT_2_3); | ||||
|   | ||||
| @@ -239,7 +239,7 @@ static void hid_keyboard_event(DeviceState *dev, QemuConsole *src, | ||||
|  | ||||
| static void hid_keyboard_process_keycode(HIDState *hs) | ||||
| { | ||||
|     uint8_t hid_code, key; | ||||
|     uint8_t hid_code, index, key; | ||||
|     int i, keycode, slot; | ||||
|  | ||||
|     if (hs->n == 0) { | ||||
| @@ -249,7 +249,8 @@ static void hid_keyboard_process_keycode(HIDState *hs) | ||||
|     keycode = hs->kbd.keycodes[slot]; | ||||
|  | ||||
|     key = keycode & 0x7f; | ||||
|     hid_code = hid_usage_keys[key | ((hs->kbd.modifiers >> 1) & (1 << 7))]; | ||||
|     index = key | ((hs->kbd.modifiers & (1 << 8)) >> 1); | ||||
|     hid_code = hid_usage_keys[index]; | ||||
|     hs->kbd.modifiers &= ~(1 << 8); | ||||
|  | ||||
|     switch (hid_code) { | ||||
| @@ -257,18 +258,41 @@ static void hid_keyboard_process_keycode(HIDState *hs) | ||||
|         return; | ||||
|  | ||||
|     case 0xe0: | ||||
|         assert(key == 0x1d); | ||||
|         if (hs->kbd.modifiers & (1 << 9)) { | ||||
|             hs->kbd.modifiers ^= 3 << 8; | ||||
|             /* The hid_codes for the 0xe1/0x1d scancode sequence are 0xe9/0xe0. | ||||
|              * Here we're processing the second hid_code.  By dropping bit 9 | ||||
|              * and setting bit 8, the scancode after 0x1d will access the | ||||
|              * second half of the table. | ||||
|              */ | ||||
|             hs->kbd.modifiers ^= (1 << 8) | (1 << 9); | ||||
|             return; | ||||
|         } | ||||
|         /* fall through to process Ctrl_L */ | ||||
|     case 0xe1 ... 0xe7: | ||||
|         /* Ctrl_L/Ctrl_R, Shift_L/Shift_R, Alt_L/Alt_R, Win_L/Win_R. | ||||
|          * Handle releases here, or fall through to process presses. | ||||
|          */ | ||||
|         if (keycode & (1 << 7)) { | ||||
|             hs->kbd.modifiers &= ~(1 << (hid_code & 0x0f)); | ||||
|             return; | ||||
|         } | ||||
|     case 0xe8 ... 0xef: | ||||
|         /* fall through */ | ||||
|     case 0xe8 ... 0xe9: | ||||
|         /* USB modifiers are just 1 byte long.  Bits 8 and 9 of | ||||
|          * hs->kbd.modifiers implement a state machine that detects the | ||||
|          * 0xe0 and 0xe1/0x1d sequences.  These bits do not follow the | ||||
|          * usual rules where bit 7 marks released keys; they are cleared | ||||
|          * elsewhere in the function as the state machine dictates. | ||||
|          */ | ||||
|         hs->kbd.modifiers |= 1 << (hid_code & 0x0f); | ||||
|         return; | ||||
|  | ||||
|     case 0xea ... 0xef: | ||||
|         abort(); | ||||
|  | ||||
|     default: | ||||
|         break; | ||||
|     } | ||||
|  | ||||
|     if (keycode & (1 << 7)) { | ||||
|   | ||||
| @@ -308,6 +308,7 @@ static void virtio_input_hid_handle_status(VirtIOInput *vinput, | ||||
| static Property virtio_input_hid_properties[] = { | ||||
|     DEFINE_PROP_STRING("display", VirtIOInputHID, display), | ||||
|     DEFINE_PROP_UINT32("head", VirtIOInputHID, head, 0), | ||||
|     DEFINE_PROP_END_OF_LIST(), | ||||
| }; | ||||
|  | ||||
| static void virtio_input_hid_class_init(ObjectClass *klass, void *data) | ||||
|   | ||||
| @@ -11,6 +11,7 @@ | ||||
| #include "hw/virtio/virtio.h" | ||||
| #include "hw/virtio/virtio-input.h" | ||||
|  | ||||
| #include <sys/ioctl.h> | ||||
| #include "standard-headers/linux/input.h" | ||||
|  | ||||
| /* ----------------------------------------------------------------- */ | ||||
|   | ||||
| @@ -466,7 +466,6 @@ static uint64_t virtio_net_get_features(VirtIODevice *vdev, uint64_t features) | ||||
|     } | ||||
|  | ||||
|     if (!get_vhost_net(nc->peer)) { | ||||
|         virtio_add_feature(&features, VIRTIO_F_VERSION_1); | ||||
|         return features; | ||||
|     } | ||||
|     return vhost_net_get_features(get_vhost_net(nc->peer), features); | ||||
|   | ||||
| @@ -36,7 +36,7 @@ typedef struct S390CcwMachineState { | ||||
|  | ||||
| void io_subsystem_reset(void) | ||||
| { | ||||
|     DeviceState *css, *sclp, *flic; | ||||
|     DeviceState *css, *sclp, *flic, *diag288; | ||||
|  | ||||
|     css = DEVICE(object_resolve_path_type("", "virtual-css-bridge", NULL)); | ||||
|     if (css) { | ||||
| @@ -51,6 +51,10 @@ void io_subsystem_reset(void) | ||||
|     if (flic) { | ||||
|         qdev_reset_all(flic); | ||||
|     } | ||||
|     diag288 = DEVICE(object_resolve_path_type("", "diag288", NULL)); | ||||
|     if (diag288) { | ||||
|         qdev_reset_all(diag288); | ||||
|     } | ||||
| } | ||||
|  | ||||
| static int virtio_ccw_hcall_notify(const uint64_t *args) | ||||
|   | ||||
| @@ -1508,12 +1508,12 @@ static int virtio_ccw_load_config(DeviceState *d, QEMUFile *f) | ||||
|     qemu_get_be16s(f, &vdev->config_vector); | ||||
|     dev->routes.adapter.ind_offset = qemu_get_be64(f); | ||||
|     dev->thinint_isc = qemu_get_byte(f); | ||||
|     dev->revision = qemu_get_be32(f); | ||||
|     if (s->thinint_active) { | ||||
|         return css_register_io_adapter(CSS_IO_ADAPTER_VIRTIO, | ||||
|                                        dev->thinint_isc, true, false, | ||||
|                                        &dev->routes.adapter.adapter_id); | ||||
|     } | ||||
|     dev->revision = qemu_get_be32(f); | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|   | ||||
| @@ -546,7 +546,8 @@ static void virtio_write_config(PCIDevice *pci_dev, uint32_t address, | ||||
|         off = le32_to_cpu(cfg->cap.offset); | ||||
|         len = le32_to_cpu(cfg->cap.length); | ||||
|  | ||||
|         if (len <= sizeof cfg->pci_cfg_data) { | ||||
|         if (len == 1 || len == 2 || len == 4) { | ||||
|             assert(len <= sizeof cfg->pci_cfg_data); | ||||
|             virtio_address_space_write(&proxy->modern_as, off, | ||||
|                                        cfg->pci_cfg_data, len); | ||||
|         } | ||||
| @@ -570,7 +571,8 @@ static uint32_t virtio_read_config(PCIDevice *pci_dev, | ||||
|         off = le32_to_cpu(cfg->cap.offset); | ||||
|         len = le32_to_cpu(cfg->cap.length); | ||||
|  | ||||
|         if (len <= sizeof cfg->pci_cfg_data) { | ||||
|         if (len == 1 || len == 2 || len == 4) { | ||||
|             assert(len <= sizeof cfg->pci_cfg_data); | ||||
|             virtio_address_space_read(&proxy->modern_as, off, | ||||
|                                       cfg->pci_cfg_data, len); | ||||
|         } | ||||
|   | ||||
| @@ -40,6 +40,13 @@ static void wdt_diag288_reset(DeviceState *dev) | ||||
|     timer_del(diag288->timer); | ||||
| } | ||||
|  | ||||
| static void diag288_reset(void *opaque) | ||||
| { | ||||
|     DeviceState *diag288 = opaque; | ||||
|  | ||||
|     wdt_diag288_reset(diag288); | ||||
| } | ||||
|  | ||||
| static void diag288_timer_expired(void *dev) | ||||
| { | ||||
|     qemu_log_mask(CPU_LOG_RESET, "Watchdog timer expired.\n"); | ||||
| @@ -80,6 +87,7 @@ static void wdt_diag288_realize(DeviceState *dev, Error **errp) | ||||
| { | ||||
|     DIAG288State *diag288 = DIAG288(dev); | ||||
|  | ||||
|     qemu_register_reset(diag288_reset, diag288); | ||||
|     diag288->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, diag288_timer_expired, | ||||
|                                   dev); | ||||
| } | ||||
|   | ||||
| @@ -12,6 +12,7 @@ | ||||
| /* block.c */ | ||||
| typedef struct BlockDriver BlockDriver; | ||||
| typedef struct BlockJob BlockJob; | ||||
| typedef struct BdrvChild BdrvChild; | ||||
| typedef struct BdrvChildRole BdrvChildRole; | ||||
|  | ||||
| typedef struct BlockDriverInfo { | ||||
| @@ -208,6 +209,11 @@ int bdrv_open_image(BlockDriverState **pbs, const char *filename, | ||||
|                     QDict *options, const char *bdref_key, | ||||
|                     BlockDriverState* parent, const BdrvChildRole *child_role, | ||||
|                     bool allow_none, Error **errp); | ||||
| BdrvChild *bdrv_open_child(const char *filename, | ||||
|                            QDict *options, const char *bdref_key, | ||||
|                            BlockDriverState* parent, | ||||
|                            const BdrvChildRole *child_role, | ||||
|                            bool allow_none, Error **errp); | ||||
| void bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd); | ||||
| int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp); | ||||
| int bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, Error **errp); | ||||
| @@ -507,6 +513,7 @@ void bdrv_disable_copy_on_read(BlockDriverState *bs); | ||||
|  | ||||
| void bdrv_ref(BlockDriverState *bs); | ||||
| void bdrv_unref(BlockDriverState *bs); | ||||
| void bdrv_unref_child(BlockDriverState *parent, BdrvChild *child); | ||||
|  | ||||
| bool bdrv_op_is_blocked(BlockDriverState *bs, BlockOpType op, Error **errp); | ||||
| void bdrv_op_block(BlockDriverState *bs, BlockOpType op, Error *reason); | ||||
|   | ||||
| @@ -335,11 +335,11 @@ struct BdrvChildRole { | ||||
| extern const BdrvChildRole child_file; | ||||
| extern const BdrvChildRole child_format; | ||||
|  | ||||
| typedef struct BdrvChild { | ||||
| struct BdrvChild { | ||||
|     BlockDriverState *bs; | ||||
|     const BdrvChildRole *role; | ||||
|     QLIST_ENTRY(BdrvChild) next; | ||||
| } BdrvChild; | ||||
| }; | ||||
|  | ||||
| /* | ||||
|  * Note: the function bdrv_append() copies and swaps contents of | ||||
| @@ -379,6 +379,7 @@ struct BlockDriverState { | ||||
|     char exact_filename[PATH_MAX]; | ||||
|  | ||||
|     BlockDriverState *backing_hd; | ||||
|     BdrvChild *backing_child; | ||||
|     BlockDriverState *file; | ||||
|  | ||||
|     NotifierList close_notifiers; | ||||
|   | ||||
| @@ -298,6 +298,74 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *); | ||||
|             .driver   = TYPE_X86_CPU,\ | ||||
|             .property = "arat",\ | ||||
|             .value    = "off",\ | ||||
|         },{\ | ||||
|             .driver   = "qemu64" "-" TYPE_X86_CPU,\ | ||||
|             .property = "level",\ | ||||
|             .value    = stringify(4),\ | ||||
|         },{\ | ||||
|             .driver   = "kvm64" "-" TYPE_X86_CPU,\ | ||||
|             .property = "level",\ | ||||
|             .value    = stringify(5),\ | ||||
|         },{\ | ||||
|             .driver   = "pentium3" "-" TYPE_X86_CPU,\ | ||||
|             .property = "level",\ | ||||
|             .value    = stringify(2),\ | ||||
|         },{\ | ||||
|             .driver   = "n270" "-" TYPE_X86_CPU,\ | ||||
|             .property = "level",\ | ||||
|             .value    = stringify(5),\ | ||||
|         },{\ | ||||
|             .driver   = "Conroe" "-" TYPE_X86_CPU,\ | ||||
|             .property = "level",\ | ||||
|             .value    = stringify(4),\ | ||||
|         },{\ | ||||
|             .driver   = "Penryn" "-" TYPE_X86_CPU,\ | ||||
|             .property = "level",\ | ||||
|             .value    = stringify(4),\ | ||||
|         },{\ | ||||
|             .driver   = "Nehalem" "-" TYPE_X86_CPU,\ | ||||
|             .property = "level",\ | ||||
|             .value    = stringify(4),\ | ||||
|         },{\ | ||||
|             .driver   = "n270" "-" TYPE_X86_CPU,\ | ||||
|             .property = "xlevel",\ | ||||
|             .value    = stringify(0x8000000a),\ | ||||
|         },{\ | ||||
|             .driver   = "Penryn" "-" TYPE_X86_CPU,\ | ||||
|             .property = "xlevel",\ | ||||
|             .value    = stringify(0x8000000a),\ | ||||
|         },{\ | ||||
|             .driver   = "Conroe" "-" TYPE_X86_CPU,\ | ||||
|             .property = "xlevel",\ | ||||
|             .value    = stringify(0x8000000a),\ | ||||
|         },{\ | ||||
|             .driver   = "Nehalem" "-" TYPE_X86_CPU,\ | ||||
|             .property = "xlevel",\ | ||||
|             .value    = stringify(0x8000000a),\ | ||||
|         },{\ | ||||
|             .driver   = "Westmere" "-" TYPE_X86_CPU,\ | ||||
|             .property = "xlevel",\ | ||||
|             .value    = stringify(0x8000000a),\ | ||||
|         },{\ | ||||
|             .driver   = "SandyBridge" "-" TYPE_X86_CPU,\ | ||||
|             .property = "xlevel",\ | ||||
|             .value    = stringify(0x8000000a),\ | ||||
|         },{\ | ||||
|             .driver   = "Haswell" "-" TYPE_X86_CPU,\ | ||||
|             .property = "xlevel",\ | ||||
|             .value    = stringify(0x8000000a),\ | ||||
|         },{\ | ||||
|             .driver   = "Haswell-noTSX" "-" TYPE_X86_CPU,\ | ||||
|             .property = "xlevel",\ | ||||
|             .value    = stringify(0x8000000a),\ | ||||
|         },{\ | ||||
|             .driver   = "Broadwell" "-" TYPE_X86_CPU,\ | ||||
|             .property = "xlevel",\ | ||||
|             .value    = stringify(0x8000000a),\ | ||||
|         },{\ | ||||
|             .driver   = "Broadwell-noTSX" "-" TYPE_X86_CPU,\ | ||||
|             .property = "xlevel",\ | ||||
|             .value    = stringify(0x8000000a),\ | ||||
|         }, | ||||
|  | ||||
| #define PC_COMPAT_2_2 \ | ||||
|   | ||||
| @@ -53,7 +53,7 @@ extern PropertyInfo qdev_prop_arraylen; | ||||
|         } | ||||
| #define DEFINE_PROP_BIT64(_name, _state, _field, _bit, _defval) {       \ | ||||
|         .name      = (_name),                                           \ | ||||
|         .info      = &(qdev_prop_bit),                                  \ | ||||
|         .info      = &(qdev_prop_bit64),                                \ | ||||
|         .bitnr    = (_bit),                                             \ | ||||
|         .offset    = offsetof(_state, _field)                           \ | ||||
|             + type_check(uint64_t, typeof_field(_state, _field)),       \ | ||||
|   | ||||
| @@ -202,4 +202,5 @@ void savevm_skip_section_footers(void); | ||||
| void register_global_state(void); | ||||
| void global_state_set_optional(void); | ||||
| void savevm_skip_configuration(void); | ||||
| int global_state_store(void); | ||||
| #endif | ||||
|   | ||||
| @@ -10,7 +10,6 @@ | ||||
|  | ||||
|  | ||||
| #include <sys/time.h> | ||||
| #include <sys/ioctl.h> | ||||
| #include <sys/types.h> | ||||
| #include "standard-headers/linux/types.h" | ||||
|  | ||||
|   | ||||
| @@ -2577,7 +2577,7 @@ done_syscall: | ||||
|                         code = (trap_instr >> 6) & 0x3f; | ||||
|                     } | ||||
|                 } else { | ||||
|                     ret = get_user_ual(trap_instr, env->active_tc.PC); | ||||
|                     ret = get_user_u32(trap_instr, env->active_tc.PC); | ||||
|                     if (ret != 0) { | ||||
|                         goto error; | ||||
|                     } | ||||
| @@ -2611,7 +2611,7 @@ done_syscall: | ||||
|  | ||||
|                     trap_instr = (instr[0] << 16) | instr[1]; | ||||
|                 } else { | ||||
|                     ret = get_user_ual(trap_instr, env->active_tc.PC); | ||||
|                     ret = get_user_u32(trap_instr, env->active_tc.PC); | ||||
|                 } | ||||
|  | ||||
|                 if (ret != 0) { | ||||
|   | ||||
| @@ -104,11 +104,13 @@ typedef struct { | ||||
|     bool optional; | ||||
|     uint32_t size; | ||||
|     uint8_t runstate[100]; | ||||
|     RunState state; | ||||
|     bool received; | ||||
| } GlobalState; | ||||
|  | ||||
| static GlobalState global_state; | ||||
|  | ||||
| static int global_state_store(void) | ||||
| int global_state_store(void) | ||||
| { | ||||
|     if (!runstate_store((char *)global_state.runstate, | ||||
|                         sizeof(global_state.runstate))) { | ||||
| @@ -119,9 +121,14 @@ static int global_state_store(void) | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| static char *global_state_get_runstate(void) | ||||
| static bool global_state_received(void) | ||||
| { | ||||
|     return (char *)global_state.runstate; | ||||
|     return global_state.received; | ||||
| } | ||||
|  | ||||
| static RunState global_state_get_runstate(void) | ||||
| { | ||||
|     return global_state.state; | ||||
| } | ||||
|  | ||||
| void global_state_set_optional(void) | ||||
| @@ -154,26 +161,25 @@ static bool global_state_needed(void *opaque) | ||||
| static int global_state_post_load(void *opaque, int version_id) | ||||
| { | ||||
|     GlobalState *s = opaque; | ||||
|     int ret = 0; | ||||
|     Error *local_err = NULL; | ||||
|     int r; | ||||
|     char *runstate = (char *)s->runstate; | ||||
|  | ||||
|     s->received = true; | ||||
|     trace_migrate_global_state_post_load(runstate); | ||||
|  | ||||
|     if (strcmp(runstate, "running") != 0) { | ||||
|         Error *local_err = NULL; | ||||
|         int r = qapi_enum_parse(RunState_lookup, runstate, RUN_STATE_MAX, | ||||
|     r = qapi_enum_parse(RunState_lookup, runstate, RUN_STATE_MAX, | ||||
|                                 -1, &local_err); | ||||
|  | ||||
|         if (r == -1) { | ||||
|             if (local_err) { | ||||
|                 error_report_err(local_err); | ||||
|             } | ||||
|             return -EINVAL; | ||||
|     if (r == -1) { | ||||
|         if (local_err) { | ||||
|             error_report_err(local_err); | ||||
|         } | ||||
|         ret = vm_stop_force_state(r); | ||||
|         return -EINVAL; | ||||
|     } | ||||
|     s->state = r; | ||||
|  | ||||
|    return ret; | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| static void global_state_pre_save(void *opaque) | ||||
| @@ -202,6 +208,7 @@ void register_global_state(void) | ||||
| { | ||||
|     /* We would use it independently that we receive it */ | ||||
|     strcpy((char *)&global_state.runstate, ""); | ||||
|     global_state.received = false; | ||||
|     vmstate_register(NULL, 0, &vmstate_globalstate, &global_state); | ||||
| } | ||||
|  | ||||
| @@ -209,7 +216,6 @@ static void migrate_generate_event(int new_state) | ||||
| { | ||||
|     if (migrate_use_events()) { | ||||
|         qapi_event_send_migration(new_state, &error_abort); | ||||
|         trace_migrate_set_state(new_state); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -283,20 +289,19 @@ static void process_incoming_migration_co(void *opaque) | ||||
|         exit(EXIT_FAILURE); | ||||
|     } | ||||
|  | ||||
|     /* runstate == "" means that we haven't received it through the | ||||
|      * wire, so we obey autostart.  runstate == runing means that we | ||||
|      * need to run it, we need to make sure that we do it after | ||||
|      * everything else has finished.  Every other state change is done | ||||
|      * at the post_load function */ | ||||
|     /* If global state section was not received or we are in running | ||||
|        state, we need to obey autostart. Any other state is set with | ||||
|        runstate_set. */ | ||||
|  | ||||
|     if (strcmp(global_state_get_runstate(), "running") == 0) { | ||||
|         vm_start(); | ||||
|     } else if (strcmp(global_state_get_runstate(), "") == 0) { | ||||
|     if (!global_state_received() || | ||||
|         global_state_get_runstate() == RUN_STATE_RUNNING) { | ||||
|         if (autostart) { | ||||
|             vm_start(); | ||||
|         } else { | ||||
|             runstate_set(RUN_STATE_PAUSED); | ||||
|         } | ||||
|     } else { | ||||
|         runstate_set(global_state_get_runstate()); | ||||
|     } | ||||
|     migrate_decompress_threads_join(); | ||||
| } | ||||
| @@ -522,6 +527,7 @@ void qmp_migrate_set_parameters(bool has_compress_level, | ||||
| static void migrate_set_state(MigrationState *s, int old_state, int new_state) | ||||
| { | ||||
|     if (atomic_cmpxchg(&s->state, old_state, new_state) == old_state) { | ||||
|         trace_migrate_set_state(new_state); | ||||
|         migrate_generate_event(new_state); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -382,16 +382,16 @@ void migrate_compress_threads_create(void) | ||||
|  */ | ||||
| static size_t save_page_header(QEMUFile *f, RAMBlock *block, ram_addr_t offset) | ||||
| { | ||||
|     size_t size; | ||||
|     size_t size, len; | ||||
|  | ||||
|     qemu_put_be64(f, offset); | ||||
|     size = 8; | ||||
|  | ||||
|     if (!(offset & RAM_SAVE_FLAG_CONTINUE)) { | ||||
|         qemu_put_byte(f, strlen(block->idstr)); | ||||
|         qemu_put_buffer(f, (uint8_t *)block->idstr, | ||||
|                         strlen(block->idstr)); | ||||
|         size += 1 + strlen(block->idstr); | ||||
|         len = strlen(block->idstr); | ||||
|         qemu_put_byte(f, len); | ||||
|         qemu_put_buffer(f, (uint8_t *)block->idstr, len); | ||||
|         size += 1 + len; | ||||
|     } | ||||
|     return size; | ||||
| } | ||||
|   | ||||
| @@ -1315,6 +1315,12 @@ void hmp_savevm(Monitor *mon, const QDict *qdict) | ||||
|     } | ||||
|  | ||||
|     saved_vm_running = runstate_is_running(); | ||||
|  | ||||
|     ret = global_state_store(); | ||||
|     if (ret) { | ||||
|         monitor_printf(mon, "Error saving global state\n"); | ||||
|         return; | ||||
|     } | ||||
|     vm_stop(RUN_STATE_SAVE_VM); | ||||
|  | ||||
|     memset(sn, 0, sizeof(*sn)); | ||||
|   | ||||
							
								
								
									
										3
									
								
								numa.c
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								numa.c
									
									
									
									
									
								
							| @@ -54,7 +54,7 @@ NodeInfo numa_info[MAX_NODES]; | ||||
|  | ||||
| void numa_set_mem_node_id(ram_addr_t addr, uint64_t size, uint32_t node) | ||||
| { | ||||
|     struct numa_addr_range *range = g_malloc0(sizeof(*range)); | ||||
|     struct numa_addr_range *range; | ||||
|  | ||||
|     /* | ||||
|      * Memory-less nodes can come here with 0 size in which case, | ||||
| @@ -64,6 +64,7 @@ void numa_set_mem_node_id(ram_addr_t addr, uint64_t size, uint32_t node) | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     range = g_malloc0(sizeof(*range)); | ||||
|     range->mem_start = addr; | ||||
|     range->mem_end = addr + size - 1; | ||||
|     QLIST_INSERT_HEAD(&numa_info[node].addr, range, entry); | ||||
|   | ||||
| @@ -3406,6 +3406,7 @@ Enable/Disable migration capabilities | ||||
| - "rdma-pin-all": pin all pages when using RDMA during migration | ||||
| - "auto-converge": throttle down guest to help convergence of migration | ||||
| - "zero-blocks": compress zero blocks during block migration | ||||
| - "events": generate events for each migration state change | ||||
|  | ||||
| Arguments: | ||||
|  | ||||
|   | ||||
| @@ -56,6 +56,7 @@ cp_virtio() { | ||||
|                 -e 's/__bitwise__//' \ | ||||
|                 -e 's/__attribute__((packed))/QEMU_PACKED/' \ | ||||
|                 -e 's/__inline__/inline/' \ | ||||
|                 -e '/sys\/ioctl.h/d' \ | ||||
|                 "$f" > "$to/$header"; | ||||
|         done | ||||
|     fi | ||||
|   | ||||
| @@ -2752,6 +2752,7 @@ static const ARMCPRegInfo el3_cp_reginfo[] = { | ||||
|       .access = PL3_RW, .writefn = vbar_write, .resetvalue = 0, | ||||
|       .fieldoffset = offsetof(CPUARMState, cp15.mvbar) }, | ||||
|     { .name = "SCTLR_EL3", .state = ARM_CP_STATE_AA64, | ||||
|       .type = ARM_CP_ALIAS, /* reset handled by AArch32 view */ | ||||
|       .opc0 = 3, .opc1 = 6, .crn = 1, .crm = 0, .opc2 = 0, | ||||
|       .access = PL3_RW, .raw_writefn = raw_write, .writefn = sctlr_write, | ||||
|       .fieldoffset = offsetof(CPUARMState, cp15.sctlr_el[3]) }, | ||||
|   | ||||
| @@ -695,7 +695,7 @@ struct X86CPUDefinition { | ||||
| static X86CPUDefinition builtin_x86_defs[] = { | ||||
|     { | ||||
|         .name = "qemu64", | ||||
|         .level = 4, | ||||
|         .level = 0xd, | ||||
|         .vendor = CPUID_VENDOR_AMD, | ||||
|         .family = 6, | ||||
|         .model = 6, | ||||
| @@ -771,7 +771,7 @@ static X86CPUDefinition builtin_x86_defs[] = { | ||||
|     }, | ||||
|     { | ||||
|         .name = "kvm64", | ||||
|         .level = 5, | ||||
|         .level = 0xd, | ||||
|         .vendor = CPUID_VENDOR_INTEL, | ||||
|         .family = 15, | ||||
|         .model = 6, | ||||
| @@ -882,7 +882,7 @@ static X86CPUDefinition builtin_x86_defs[] = { | ||||
|     }, | ||||
|     { | ||||
|         .name = "pentium3", | ||||
|         .level = 2, | ||||
|         .level = 3, | ||||
|         .vendor = CPUID_VENDOR_INTEL, | ||||
|         .family = 6, | ||||
|         .model = 7, | ||||
| @@ -907,8 +907,7 @@ static X86CPUDefinition builtin_x86_defs[] = { | ||||
|     }, | ||||
|     { | ||||
|         .name = "n270", | ||||
|         /* original is on level 10 */ | ||||
|         .level = 5, | ||||
|         .level = 10, | ||||
|         .vendor = CPUID_VENDOR_INTEL, | ||||
|         .family = 6, | ||||
|         .model = 28, | ||||
| @@ -928,12 +927,12 @@ static X86CPUDefinition builtin_x86_defs[] = { | ||||
|             CPUID_EXT2_NX, | ||||
|         .features[FEAT_8000_0001_ECX] = | ||||
|             CPUID_EXT3_LAHF_LM, | ||||
|         .xlevel = 0x8000000A, | ||||
|         .xlevel = 0x80000008, | ||||
|         .model_id = "Intel(R) Atom(TM) CPU N270   @ 1.60GHz", | ||||
|     }, | ||||
|     { | ||||
|         .name = "Conroe", | ||||
|         .level = 4, | ||||
|         .level = 10, | ||||
|         .vendor = CPUID_VENDOR_INTEL, | ||||
|         .family = 6, | ||||
|         .model = 15, | ||||
| @@ -950,12 +949,12 @@ static X86CPUDefinition builtin_x86_defs[] = { | ||||
|             CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL, | ||||
|         .features[FEAT_8000_0001_ECX] = | ||||
|             CPUID_EXT3_LAHF_LM, | ||||
|         .xlevel = 0x8000000A, | ||||
|         .xlevel = 0x80000008, | ||||
|         .model_id = "Intel Celeron_4x0 (Conroe/Merom Class Core 2)", | ||||
|     }, | ||||
|     { | ||||
|         .name = "Penryn", | ||||
|         .level = 4, | ||||
|         .level = 10, | ||||
|         .vendor = CPUID_VENDOR_INTEL, | ||||
|         .family = 6, | ||||
|         .model = 23, | ||||
| @@ -973,12 +972,12 @@ static X86CPUDefinition builtin_x86_defs[] = { | ||||
|             CPUID_EXT2_LM | CPUID_EXT2_NX | CPUID_EXT2_SYSCALL, | ||||
|         .features[FEAT_8000_0001_ECX] = | ||||
|             CPUID_EXT3_LAHF_LM, | ||||
|         .xlevel = 0x8000000A, | ||||
|         .xlevel = 0x80000008, | ||||
|         .model_id = "Intel Core 2 Duo P9xxx (Penryn Class Core 2)", | ||||
|     }, | ||||
|     { | ||||
|         .name = "Nehalem", | ||||
|         .level = 4, | ||||
|         .level = 11, | ||||
|         .vendor = CPUID_VENDOR_INTEL, | ||||
|         .family = 6, | ||||
|         .model = 26, | ||||
| @@ -996,7 +995,7 @@ static X86CPUDefinition builtin_x86_defs[] = { | ||||
|             CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX, | ||||
|         .features[FEAT_8000_0001_ECX] = | ||||
|             CPUID_EXT3_LAHF_LM, | ||||
|         .xlevel = 0x8000000A, | ||||
|         .xlevel = 0x80000008, | ||||
|         .model_id = "Intel Core i7 9xx (Nehalem Class Core i7)", | ||||
|     }, | ||||
|     { | ||||
| @@ -1022,7 +1021,7 @@ static X86CPUDefinition builtin_x86_defs[] = { | ||||
|             CPUID_EXT3_LAHF_LM, | ||||
|         .features[FEAT_6_EAX] = | ||||
|             CPUID_6_EAX_ARAT, | ||||
|         .xlevel = 0x8000000A, | ||||
|         .xlevel = 0x80000008, | ||||
|         .model_id = "Westmere E56xx/L56xx/X56xx (Nehalem-C)", | ||||
|     }, | ||||
|     { | ||||
| @@ -1053,7 +1052,7 @@ static X86CPUDefinition builtin_x86_defs[] = { | ||||
|             CPUID_XSAVE_XSAVEOPT, | ||||
|         .features[FEAT_6_EAX] = | ||||
|             CPUID_6_EAX_ARAT, | ||||
|         .xlevel = 0x8000000A, | ||||
|         .xlevel = 0x80000008, | ||||
|         .model_id = "Intel Xeon E312xx (Sandy Bridge)", | ||||
|     }, | ||||
|     { | ||||
| @@ -1087,7 +1086,7 @@ static X86CPUDefinition builtin_x86_defs[] = { | ||||
|             CPUID_XSAVE_XSAVEOPT, | ||||
|         .features[FEAT_6_EAX] = | ||||
|             CPUID_6_EAX_ARAT, | ||||
|         .xlevel = 0x8000000A, | ||||
|         .xlevel = 0x80000008, | ||||
|         .model_id = "Intel Xeon E3-12xx v2 (Ivy Bridge)", | ||||
|     }, | ||||
|     { | ||||
| @@ -1123,7 +1122,7 @@ static X86CPUDefinition builtin_x86_defs[] = { | ||||
|             CPUID_XSAVE_XSAVEOPT, | ||||
|         .features[FEAT_6_EAX] = | ||||
|             CPUID_6_EAX_ARAT, | ||||
|         .xlevel = 0x8000000A, | ||||
|         .xlevel = 0x80000008, | ||||
|         .model_id = "Intel Core Processor (Haswell, no TSX)", | ||||
|     },    { | ||||
|         .name = "Haswell", | ||||
| @@ -1159,7 +1158,7 @@ static X86CPUDefinition builtin_x86_defs[] = { | ||||
|             CPUID_XSAVE_XSAVEOPT, | ||||
|         .features[FEAT_6_EAX] = | ||||
|             CPUID_6_EAX_ARAT, | ||||
|         .xlevel = 0x8000000A, | ||||
|         .xlevel = 0x80000008, | ||||
|         .model_id = "Intel Core Processor (Haswell)", | ||||
|     }, | ||||
|     { | ||||
| @@ -1197,7 +1196,7 @@ static X86CPUDefinition builtin_x86_defs[] = { | ||||
|             CPUID_XSAVE_XSAVEOPT, | ||||
|         .features[FEAT_6_EAX] = | ||||
|             CPUID_6_EAX_ARAT, | ||||
|         .xlevel = 0x8000000A, | ||||
|         .xlevel = 0x80000008, | ||||
|         .model_id = "Intel Core Processor (Broadwell, no TSX)", | ||||
|     }, | ||||
|     { | ||||
| @@ -1235,7 +1234,7 @@ static X86CPUDefinition builtin_x86_defs[] = { | ||||
|             CPUID_XSAVE_XSAVEOPT, | ||||
|         .features[FEAT_6_EAX] = | ||||
|             CPUID_6_EAX_ARAT, | ||||
|         .xlevel = 0x8000000A, | ||||
|         .xlevel = 0x80000008, | ||||
|         .model_id = "Intel Core Processor (Broadwell)", | ||||
|     }, | ||||
|     { | ||||
| @@ -3021,7 +3020,7 @@ static void x86_cpu_register_feature_bit_props(X86CPU *cpu, | ||||
|  | ||||
|     for (i = 1; names[i]; i++) { | ||||
|         feat2prop(names[i]); | ||||
|         object_property_add_alias(obj, names[i], obj, g_strdup(names[0]), | ||||
|         object_property_add_alias(obj, names[i], obj, names[0], | ||||
|                                   &error_abort); | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -11,7 +11,7 @@ | ||||
| #if defined(TARGET_MIPS64) | ||||
| #define TARGET_LONG_BITS 64 | ||||
| #define TARGET_PHYS_ADDR_SPACE_BITS 48 | ||||
| #define TARGET_VIRT_ADDR_SPACE_BITS 42 | ||||
| #define TARGET_VIRT_ADDR_SPACE_BITS 48 | ||||
| #else | ||||
| #define TARGET_LONG_BITS 32 | ||||
| #define TARGET_PHYS_ADDR_SPACE_BITS 40 | ||||
|   | ||||
| @@ -220,6 +220,23 @@ static int copy_argn_to_target(CPUMIPSState *env, int arg_num, | ||||
|         }                                       \ | ||||
|     } while (0) | ||||
|  | ||||
| #define GET_TARGET_STRINGS_2(p, addr, p2, addr2)        \ | ||||
|     do {                                                \ | ||||
|         p = lock_user_string(addr);                     \ | ||||
|         if (!p) {                                       \ | ||||
|             gpr[2] = -1;                                \ | ||||
|             gpr[3] = EFAULT;                            \ | ||||
|             goto uhi_done;                              \ | ||||
|         }                                               \ | ||||
|         p2 = lock_user_string(addr2);                   \ | ||||
|         if (!p2) {                                      \ | ||||
|             unlock_user(p, addr, 0);                    \ | ||||
|             gpr[2] = -1;                                \ | ||||
|             gpr[3] = EFAULT;                            \ | ||||
|             goto uhi_done;                              \ | ||||
|         }                                               \ | ||||
|     } while (0) | ||||
|  | ||||
| #define FREE_TARGET_STRING(p, gpr)              \ | ||||
|     do {                                        \ | ||||
|         unlock_user(p, gpr, 0);                 \ | ||||
| @@ -322,8 +339,7 @@ void helper_do_semihosting(CPUMIPSState *env) | ||||
|         FREE_TARGET_STRING(p, gpr[4]); | ||||
|         break; | ||||
|     case UHI_assert: | ||||
|         GET_TARGET_STRING(p, gpr[4]); | ||||
|         GET_TARGET_STRING(p2, gpr[5]); | ||||
|         GET_TARGET_STRINGS_2(p, gpr[4], p2, gpr[5]); | ||||
|         printf("assertion '"); | ||||
|         printf("\"%s\"", p); | ||||
|         printf("': file \"%s\", line %d\n", p2, (int)gpr[6]); | ||||
| @@ -341,8 +357,7 @@ void helper_do_semihosting(CPUMIPSState *env) | ||||
|         break; | ||||
| #ifndef _WIN32 | ||||
|     case UHI_link: | ||||
|         GET_TARGET_STRING(p, gpr[4]); | ||||
|         GET_TARGET_STRING(p2, gpr[5]); | ||||
|         GET_TARGET_STRINGS_2(p, gpr[4], p2, gpr[5]); | ||||
|         gpr[2] = link(p, p2); | ||||
|         gpr[3] = errno_mips(errno); | ||||
|         FREE_TARGET_STRING(p2, gpr[5]); | ||||
|   | ||||
| @@ -2642,6 +2642,8 @@ void helper_msa_fexdo_df(CPUMIPSState *env, uint32_t df, uint32_t wd, | ||||
|     wr_t *pwt = &(env->active_fpu.fpr[wt].wr); | ||||
|     uint32_t i; | ||||
|  | ||||
|     clear_msacsr_cause(env); | ||||
|  | ||||
|     switch (df) { | ||||
|     case DF_WORD: | ||||
|         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) { | ||||
| @@ -3192,6 +3194,8 @@ void helper_msa_fexupl_df(CPUMIPSState *env, uint32_t df, uint32_t wd, | ||||
|     wr_t *pws = &(env->active_fpu.fpr[ws].wr); | ||||
|     uint32_t i; | ||||
|  | ||||
|     clear_msacsr_cause(env); | ||||
|  | ||||
|     switch (df) { | ||||
|     case DF_WORD: | ||||
|         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) { | ||||
| @@ -3224,6 +3228,8 @@ void helper_msa_fexupr_df(CPUMIPSState *env, uint32_t df, uint32_t wd, | ||||
|     wr_t *pws = &(env->active_fpu.fpr[ws].wr); | ||||
|     uint32_t i; | ||||
|  | ||||
|     clear_msacsr_cause(env); | ||||
|  | ||||
|     switch (df) { | ||||
|     case DF_WORD: | ||||
|         for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) { | ||||
|   | ||||
| @@ -661,7 +661,7 @@ static void sync_c0_tcstatus(CPUMIPSState *cpu, int tc, | ||||
|  | ||||
|     /* Sync the TASID with EntryHi.  */ | ||||
|     cpu->CP0_EntryHi &= ~0xff; | ||||
|     cpu->CP0_EntryHi = tasid; | ||||
|     cpu->CP0_EntryHi |= tasid; | ||||
|  | ||||
|     compute_hflags(cpu); | ||||
| } | ||||
| @@ -2154,10 +2154,9 @@ void helper_deret(CPUMIPSState *env) | ||||
|     debug_pre_eret(env); | ||||
|     set_pc(env, env->CP0_DEPC); | ||||
|  | ||||
|     env->hflags &= MIPS_HFLAG_DM; | ||||
|     env->hflags &= ~MIPS_HFLAG_DM; | ||||
|     compute_hflags(env); | ||||
|     debug_post_eret(env); | ||||
|     env->lladdr = 1; | ||||
| } | ||||
| #endif /* !CONFIG_USER_ONLY */ | ||||
|  | ||||
|   | ||||
| @@ -2142,6 +2142,9 @@ static void gen_ld(DisasContext *ctx, uint32_t opc, | ||||
|         break; | ||||
|     case OPC_LDL: | ||||
|         t1 = tcg_temp_new(); | ||||
|         /* Do a byte access to possibly trigger a page | ||||
|            fault with the unaligned address.  */ | ||||
|         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); | ||||
|         tcg_gen_andi_tl(t1, t0, 7); | ||||
| #ifndef TARGET_WORDS_BIGENDIAN | ||||
|         tcg_gen_xori_tl(t1, t1, 7); | ||||
| @@ -2163,6 +2166,9 @@ static void gen_ld(DisasContext *ctx, uint32_t opc, | ||||
|         break; | ||||
|     case OPC_LDR: | ||||
|         t1 = tcg_temp_new(); | ||||
|         /* Do a byte access to possibly trigger a page | ||||
|            fault with the unaligned address.  */ | ||||
|         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); | ||||
|         tcg_gen_andi_tl(t1, t0, 7); | ||||
| #ifdef TARGET_WORDS_BIGENDIAN | ||||
|         tcg_gen_xori_tl(t1, t1, 7); | ||||
| @@ -2229,6 +2235,9 @@ static void gen_ld(DisasContext *ctx, uint32_t opc, | ||||
|         break; | ||||
|     case OPC_LWL: | ||||
|         t1 = tcg_temp_new(); | ||||
|         /* Do a byte access to possibly trigger a page | ||||
|            fault with the unaligned address.  */ | ||||
|         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); | ||||
|         tcg_gen_andi_tl(t1, t0, 3); | ||||
| #ifndef TARGET_WORDS_BIGENDIAN | ||||
|         tcg_gen_xori_tl(t1, t1, 3); | ||||
| @@ -2251,6 +2260,9 @@ static void gen_ld(DisasContext *ctx, uint32_t opc, | ||||
|         break; | ||||
|     case OPC_LWR: | ||||
|         t1 = tcg_temp_new(); | ||||
|         /* Do a byte access to possibly trigger a page | ||||
|            fault with the unaligned address.  */ | ||||
|         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); | ||||
|         tcg_gen_andi_tl(t1, t0, 3); | ||||
| #ifdef TARGET_WORDS_BIGENDIAN | ||||
|         tcg_gen_xori_tl(t1, t1, 3); | ||||
| @@ -9552,6 +9564,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1, | ||||
|             gen_cmp_s(ctx, func-48, ft, fs, cc); | ||||
|             opn = condnames[func-48]; | ||||
|         } | ||||
|         optype = CMPOP; | ||||
|         break; | ||||
|     case OPC_ADD_D: | ||||
|         check_cp1_registers(ctx, fs | ft | fd); | ||||
| @@ -10036,6 +10049,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1, | ||||
|             gen_cmp_d(ctx, func-48, ft, fs, cc); | ||||
|             opn = condnames[func-48]; | ||||
|         } | ||||
|         optype = CMPOP; | ||||
|         break; | ||||
|     case OPC_CVT_S_D: | ||||
|         check_cp1_registers(ctx, fs); | ||||
| @@ -10461,6 +10475,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1, | ||||
|             gen_cmp_ps(ctx, func-48, ft, fs, cc); | ||||
|             opn = condnames[func-48]; | ||||
|         } | ||||
|         optype = CMPOP; | ||||
|         break; | ||||
|     default: | ||||
|         MIPS_INVAL(opn); | ||||
|   | ||||
| @@ -655,14 +655,14 @@ static const mips_def_t mips_defs[] = | ||||
|                        (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 | (1 << CP0C3_RXI) | (1 << CP0C3_BP) | | ||||
|                        (1 << CP0C3_BI) | (1 << CP0C3_ULRI) | (1 << CP0C3_LPA) | | ||||
|                        (1U << CP0C3_M), | ||||
|         .CP0_Config4 = MIPS_CONFIG4 | (0xfc << CP0C4_KScrExist) | | ||||
|                        (3 << CP0C4_IE) | (1 << CP0C4_M), | ||||
|         .CP0_Config3 = MIPS_CONFIG3 | (1U << CP0C3_M) | (1 << CP0C3_MSAP) | | ||||
|                        (1 << CP0C3_BP) | (1 << CP0C3_BI) | (1 << CP0C3_ULRI) | | ||||
|                        (1 << CP0C3_RXI) | (1 << CP0C3_LPA), | ||||
|         .CP0_Config4 = MIPS_CONFIG4 | (1U << CP0C4_M) | (3 << CP0C4_IE) | | ||||
|                        (0xfc << CP0C4_KScrExist), | ||||
|         .CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_LLB), | ||||
|         .CP0_Config5_rw_bitmask = (1 << CP0C5_SBRI) | (1 << CP0C5_FRE) | | ||||
|                                   (1 << CP0C5_UFE), | ||||
|         .CP0_Config5_rw_bitmask = (1 << CP0C5_MSAEn) | (1 << CP0C5_SBRI) | | ||||
|                                   (1 << CP0C5_FRE) | (1 << CP0C5_UFE), | ||||
|         .CP0_LLAddr_rw_bitmask = 0, | ||||
|         .CP0_LLAddr_shift = 0, | ||||
|         .SYNCI_Step = 32, | ||||
| @@ -674,9 +674,9 @@ static const mips_def_t mips_defs[] = | ||||
|         .CP1_fcr0 = (1 << FCR0_FREP) | (1 << FCR0_F64) | (1 << FCR0_L) | | ||||
|                     (1 << FCR0_W) | (1 << FCR0_D) | (1 << FCR0_S) | | ||||
|                     (0x00 << FCR0_PRID) | (0x0 << FCR0_REV), | ||||
|         .SEGBITS = 42, | ||||
|         .SEGBITS = 48, | ||||
|         .PABITS = 48, | ||||
|         .insn_flags = CPU_MIPS64R6, | ||||
|         .insn_flags = CPU_MIPS64R6 | ASE_MSA, | ||||
|         .mmu_type = MMU_TYPE_R4000, | ||||
|     }, | ||||
|     { | ||||
|   | ||||
| @@ -782,9 +782,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args, | ||||
|             tcg_out_r(s, *args++); | ||||
|         } | ||||
|         tcg_out_i(s, *args++); | ||||
| #ifdef CONFIG_SOFTMMU | ||||
|         tcg_out_i(s, *args); | ||||
| #endif | ||||
|         break; | ||||
|     case INDEX_op_qemu_st_i64: | ||||
|         tcg_out_r(s, *args++); | ||||
| @@ -796,9 +793,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args, | ||||
|             tcg_out_r(s, *args++); | ||||
|         } | ||||
|         tcg_out_i(s, *args++); | ||||
| #ifdef CONFIG_SOFTMMU | ||||
|         tcg_out_i(s, *args); | ||||
| #endif | ||||
|         break; | ||||
|     case INDEX_op_mov_i32:  /* Always emitted via tcg_out_mov.  */ | ||||
|     case INDEX_op_mov_i64: | ||||
|   | ||||
							
								
								
									
										2
									
								
								ui/vnc.c
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								ui/vnc.c
									
									
									
									
									
								
							| @@ -2551,7 +2551,7 @@ static int protocol_client_auth_vnc(VncState *vs, uint8_t *data, size_t len) | ||||
|         goto reject; | ||||
|     } | ||||
|  | ||||
|     if (qcrypto_cipher_decrypt(cipher, | ||||
|     if (qcrypto_cipher_encrypt(cipher, | ||||
|                                vs->challenge, | ||||
|                                response, | ||||
|                                VNC_AUTH_CHALLENGE_SIZE, | ||||
|   | ||||
							
								
								
									
										2
									
								
								vl.c
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								vl.c
									
									
									
									
									
								
							| @@ -4615,6 +4615,7 @@ int main(int argc, char **argv, char **envp) | ||||
|     } | ||||
|  | ||||
|     qemu_system_reset(VMRESET_SILENT); | ||||
|     register_global_state(); | ||||
|     if (loadvm) { | ||||
|         if (load_vmstate(loadvm) < 0) { | ||||
|             autostart = 0; | ||||
| @@ -4628,7 +4629,6 @@ int main(int argc, char **argv, char **envp) | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     register_global_state(); | ||||
|     if (incoming) { | ||||
|         Error *local_err = NULL; | ||||
|         qemu_start_incoming_migration(incoming, &local_err); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user