Compare commits
	
		
			51 Commits
		
	
	
		
			pull-input
			...
			release_0_
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					5558e88318 | ||
| 
						 | 
					06b393452f | ||
| 
						 | 
					b7d11af2e0 | ||
| 
						 | 
					8d47bb6162 | ||
| 
						 | 
					80acab6c50 | ||
| 
						 | 
					da0ac2bc13 | ||
| 
						 | 
					d3c2632047 | ||
| 
						 | 
					7cc73776e7 | ||
| 
						 | 
					937e9a1c83 | ||
| 
						 | 
					4498819404 | ||
| 
						 | 
					c61ad61830 | ||
| 
						 | 
					65297bc408 | ||
| 
						 | 
					02d400ead7 | ||
| 
						 | 
					20a9c6ac7f | ||
| 
						 | 
					bd0b264c21 | ||
| 
						 | 
					0f31aac44f | ||
| 
						 | 
					30b15843b2 | ||
| 
						 | 
					04ffdd7f94 | ||
| 
						 | 
					7648bb760d | ||
| 
						 | 
					ebb7184720 | ||
| 
						 | 
					3f546bd0b1 | ||
| 
						 | 
					00614a4cb4 | ||
| 
						 | 
					7c14db42cb | ||
| 
						 | 
					e58843d0f1 | ||
| 
						 | 
					0e39d3f89b | ||
| 
						 | 
					5389a9df53 | ||
| 
						 | 
					21fd832512 | ||
| 
						 | 
					15d4afd55b | ||
| 
						 | 
					3df962a30d | ||
| 
						 | 
					4827c90cef | ||
| 
						 | 
					0f56231dce | ||
| 
						 | 
					523faf1b92 | ||
| 
						 | 
					414c078104 | ||
| 
						 | 
					9cecf0f570 | ||
| 
						 | 
					4ca9f3dd71 | ||
| 
						 | 
					f902c4192e | ||
| 
						 | 
					b96a313d3d | ||
| 
						 | 
					d9aa1fce5a | ||
| 
						 | 
					8a11f5ff08 | ||
| 
						 | 
					b786b7ccbd | ||
| 
						 | 
					d3be2b2f71 | ||
| 
						 | 
					e36fb2a3a2 | ||
| 
						 | 
					4978045781 | ||
| 
						 | 
					cb5745c529 | ||
| 
						 | 
					295b492cfa | ||
| 
						 | 
					af8222c0f8 | ||
| 
						 | 
					249139f4e6 | ||
| 
						 | 
					8ae0978ed5 | ||
| 
						 | 
					c0024a8257 | ||
| 
						 | 
					e9af78a859 | ||
| 
						 | 
					25c4fde177 | 
							
								
								
									
										43
									
								
								Changelog
									
									
									
									
									
								
							
							
						
						
									
										43
									
								
								Changelog
									
									
									
									
									
								
							@@ -1,3 +1,46 @@
 | 
			
		||||
version 0.10.2:
 | 
			
		||||
 | 
			
		||||
  - fix savevm/loadvm (Anthony Liguori)
 | 
			
		||||
  - live migration: fix dirty tracking windows (Glauber Costa)
 | 
			
		||||
  - live migration: improve error propogation (Glauber Costa)
 | 
			
		||||
  - qcow2: fix image creation for > ~2TB images (Chris Wright)
 | 
			
		||||
  - hotplug: fix error handling for if= parameter (Eduardo Habkost)
 | 
			
		||||
  - qcow2: fix data corruption (Nolan Leake)
 | 
			
		||||
  - virtio: fix guest oops with 2.6.25 kernels (Rusty Russell)
 | 
			
		||||
  - SH4: add support for -kernel (Takashi Yoshii, Aurelien Jarno)
 | 
			
		||||
  - hotplug: fix closing of char devices (Jan Kiszka)
 | 
			
		||||
  - hotplug: remove incorrect check for device name (Eduardo Habkost)
 | 
			
		||||
  - enable -k on win32 (Herve Poussineau)
 | 
			
		||||
  - configure: use LANG=C for grep (Andreas Faerber)
 | 
			
		||||
  - fix VGA regression (malc)
 | 
			
		||||
	
 | 
			
		||||
version 0.10.1:
 | 
			
		||||
 | 
			
		||||
  - virtio-net: allow masking of notifications on empty queue (Alex Williamson)
 | 
			
		||||
  - e1000: fix rx descriptor low threshold logic (Alex Willaimson)
 | 
			
		||||
  - x86 tcg: add NULL checks to lsl instruction (Jan Kiszka)
 | 
			
		||||
  - kvm vga: fix screen corruption with -std-vga and Windows (Avi Kivity)
 | 
			
		||||
  - kvm vga: fix screen corruption with Ubuntu installations (Glauber Costa)
 | 
			
		||||
  - virtio-net: check right return size on sg list (Alex Williamson)
 | 
			
		||||
  - Make qemu_announce_self handle holes (live migration after hotplug)
 | 
			
		||||
    (Marcelo Tosatti)
 | 
			
		||||
  - Revert r6804-r6808 (qcow2 allocation info).  This series of changes added
 | 
			
		||||
    a high cost to startup for large qcow2 images (Anthony Liguori)
 | 
			
		||||
  - qemu-img: fix help message (Aurelien Jarno)
 | 
			
		||||
  - Fix build for non-default installs of SDL (Anthony Liguori)
 | 
			
		||||
  - Fix race condition in env->interrupt_request.  When using TCG and a dynticks
 | 
			
		||||
    host timer, this condition could cause TCG to get stuck in an infinite
 | 
			
		||||
    loop (Aurelien Jarno)
 | 
			
		||||
  - Fix reading encrypted hard disk passwords during early startup (Jan Kiszka)
 | 
			
		||||
  - Fix encrypted disk reporting in 'info block' (Jan Kiszka)
 | 
			
		||||
  - Fix console size with tiny displays (MusicPal) (Jan Kiszka)
 | 
			
		||||
  - Improve error handling in bdrv_open2 (Jan Kiszka)
 | 
			
		||||
  - Avoid leaking data in mux'ed character devices (Jan Kiszka)
 | 
			
		||||
  - Fix initial character device reset (no banner in monitor) (Jan Kiszka)
 | 
			
		||||
  - Fix cpuid KVM crash on i386 host (Lubomir Rintel)
 | 
			
		||||
  - Fix SLES10sp2 installation by adding ISTAT1 register to LSI SCSI emulation
 | 
			
		||||
    (Ryan Harper)
 | 
			
		||||
 | 
			
		||||
version 0.10.0:
 | 
			
		||||
 | 
			
		||||
  - TCG support (No longer requires GCC 3.x)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										104
									
								
								block-qcow2.c
									
									
									
									
									
								
							
							
						
						
									
										104
									
								
								block-qcow2.c
									
									
									
									
									
								
							@@ -143,10 +143,6 @@ typedef struct BDRVQcowState {
 | 
			
		||||
    uint32_t crypt_method_header;
 | 
			
		||||
    AES_KEY aes_encrypt_key;
 | 
			
		||||
    AES_KEY aes_decrypt_key;
 | 
			
		||||
 | 
			
		||||
    int64_t highest_alloc; /* highest cluester allocated (in clusters) */
 | 
			
		||||
    int64_t nc_free;       /* num of free clusters below highest_alloc */
 | 
			
		||||
 | 
			
		||||
    uint64_t snapshots_offset;
 | 
			
		||||
    int snapshots_size;
 | 
			
		||||
    int nb_snapshots;
 | 
			
		||||
@@ -174,8 +170,6 @@ static void free_clusters(BlockDriverState *bs,
 | 
			
		||||
#ifdef DEBUG_ALLOC
 | 
			
		||||
static void check_refcounts(BlockDriverState *bs);
 | 
			
		||||
#endif
 | 
			
		||||
static void scan_refcount(BlockDriverState *bs, int64_t *high, int64_t *free);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static int qcow_probe(const uint8_t *buf, int buf_size, const char *filename)
 | 
			
		||||
{
 | 
			
		||||
@@ -276,8 +270,6 @@ static int qcow_open(BlockDriverState *bs, const char *filename, int flags)
 | 
			
		||||
    if (refcount_init(bs) < 0)
 | 
			
		||||
        goto fail;
 | 
			
		||||
 | 
			
		||||
    scan_refcount(bs, &s->highest_alloc, &s->nc_free);
 | 
			
		||||
 | 
			
		||||
    /* read the backing file name */
 | 
			
		||||
    if (header.backing_file_offset != 0) {
 | 
			
		||||
        len = header.backing_file_size;
 | 
			
		||||
@@ -678,6 +670,10 @@ static uint64_t get_cluster_offset(BlockDriverState *bs,
 | 
			
		||||
 | 
			
		||||
    nb_available = (nb_available >> 9) + index_in_cluster;
 | 
			
		||||
 | 
			
		||||
    if (nb_needed > nb_available) {
 | 
			
		||||
        nb_needed = nb_available;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    cluster_offset = 0;
 | 
			
		||||
 | 
			
		||||
    /* seek the the l2 offset in the l1 table */
 | 
			
		||||
@@ -1466,6 +1462,7 @@ static int qcow_create(const char *filename, int64_t total_size,
 | 
			
		||||
                      const char *backing_file, int flags)
 | 
			
		||||
{
 | 
			
		||||
    int fd, header_size, backing_filename_len, l1_size, i, shift, l2_bits;
 | 
			
		||||
    int ref_clusters;
 | 
			
		||||
    QCowHeader header;
 | 
			
		||||
    uint64_t tmp, offset;
 | 
			
		||||
    QCowCreateState s1, *s = &s1;
 | 
			
		||||
@@ -1506,22 +1503,28 @@ static int qcow_create(const char *filename, int64_t total_size,
 | 
			
		||||
    offset += align_offset(l1_size * sizeof(uint64_t), s->cluster_size);
 | 
			
		||||
 | 
			
		||||
    s->refcount_table = qemu_mallocz(s->cluster_size);
 | 
			
		||||
    s->refcount_block = qemu_mallocz(s->cluster_size);
 | 
			
		||||
 | 
			
		||||
    s->refcount_table_offset = offset;
 | 
			
		||||
    header.refcount_table_offset = cpu_to_be64(offset);
 | 
			
		||||
    header.refcount_table_clusters = cpu_to_be32(1);
 | 
			
		||||
    offset += s->cluster_size;
 | 
			
		||||
 | 
			
		||||
    s->refcount_table[0] = cpu_to_be64(offset);
 | 
			
		||||
    s->refcount_block_offset = offset;
 | 
			
		||||
 | 
			
		||||
    /* count how many refcount blocks needed */
 | 
			
		||||
    tmp = offset >> s->cluster_bits;
 | 
			
		||||
    ref_clusters = (tmp >> (s->cluster_bits - REFCOUNT_SHIFT)) + 1;
 | 
			
		||||
    for (i=0; i < ref_clusters; i++) {
 | 
			
		||||
        s->refcount_table[i] = cpu_to_be64(offset);
 | 
			
		||||
        offset += s->cluster_size;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    s->refcount_block = qemu_mallocz(ref_clusters * s->cluster_size);
 | 
			
		||||
 | 
			
		||||
    /* update refcounts */
 | 
			
		||||
    create_refcount_update(s, 0, header_size);
 | 
			
		||||
    create_refcount_update(s, s->l1_table_offset, l1_size * sizeof(uint64_t));
 | 
			
		||||
    create_refcount_update(s, s->refcount_table_offset, s->cluster_size);
 | 
			
		||||
    create_refcount_update(s, s->refcount_block_offset, s->cluster_size);
 | 
			
		||||
    create_refcount_update(s, s->refcount_block_offset, ref_clusters * s->cluster_size);
 | 
			
		||||
 | 
			
		||||
    /* write all the data */
 | 
			
		||||
    write(fd, &header, sizeof(header));
 | 
			
		||||
@@ -1537,7 +1540,7 @@ static int qcow_create(const char *filename, int64_t total_size,
 | 
			
		||||
    write(fd, s->refcount_table, s->cluster_size);
 | 
			
		||||
 | 
			
		||||
    lseek(fd, s->refcount_block_offset, SEEK_SET);
 | 
			
		||||
    write(fd, s->refcount_block, s->cluster_size);
 | 
			
		||||
    write(fd, s->refcount_block, ref_clusters * s->cluster_size);
 | 
			
		||||
 | 
			
		||||
    qemu_free(s->refcount_table);
 | 
			
		||||
    qemu_free(s->refcount_block);
 | 
			
		||||
@@ -1646,8 +1649,6 @@ static int qcow_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
 | 
			
		||||
    bdi->cluster_size = s->cluster_size;
 | 
			
		||||
    bdi->vm_state_offset = (int64_t)s->l1_vm_state_index <<
 | 
			
		||||
        (s->cluster_bits + s->l2_bits);
 | 
			
		||||
    bdi->highest_alloc = s->highest_alloc << s->cluster_bits;
 | 
			
		||||
    bdi->num_free_bytes = s->nc_free  << s->cluster_bits;
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -2166,39 +2167,6 @@ static int load_refcount_block(BlockDriverState *bs,
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void scan_refcount(BlockDriverState *bs, int64_t *high, int64_t *free)
 | 
			
		||||
{
 | 
			
		||||
    BDRVQcowState *s = bs->opaque;
 | 
			
		||||
    int64_t refcnt_index, cluster_index, cluster_end, h = 0, f = 0;
 | 
			
		||||
    int64_t tail = 0; /* do not count last consecutive free entries */
 | 
			
		||||
 | 
			
		||||
    for (refcnt_index=0; refcnt_index < s->refcount_table_size; refcnt_index++){
 | 
			
		||||
        if (s->refcount_table[refcnt_index] == 0) {
 | 
			
		||||
            f += 1 << (s->cluster_bits - REFCOUNT_SHIFT);
 | 
			
		||||
            tail += 1 << (s->cluster_bits - REFCOUNT_SHIFT);
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
        cluster_index = refcnt_index << (s->cluster_bits - REFCOUNT_SHIFT);
 | 
			
		||||
        cluster_end = (refcnt_index + 1) << (s->cluster_bits - REFCOUNT_SHIFT);
 | 
			
		||||
        for ( ; cluster_index < cluster_end; cluster_index++) {
 | 
			
		||||
            if (get_refcount(bs, cluster_index) == 0) {
 | 
			
		||||
                f++;
 | 
			
		||||
                tail++;
 | 
			
		||||
            }
 | 
			
		||||
            else {
 | 
			
		||||
                h = cluster_index;
 | 
			
		||||
                tail = 0;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    f -= tail;
 | 
			
		||||
    if (free)
 | 
			
		||||
        *free = f;
 | 
			
		||||
    if (high)
 | 
			
		||||
        *high = (h+1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int get_refcount(BlockDriverState *bs, int64_t cluster_index)
 | 
			
		||||
{
 | 
			
		||||
    BDRVQcowState *s = bs->opaque;
 | 
			
		||||
@@ -2239,12 +2207,6 @@ retry:
 | 
			
		||||
            size,
 | 
			
		||||
            (s->free_cluster_index - nb_clusters) << s->cluster_bits);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    if (s->highest_alloc < s->free_cluster_index) {
 | 
			
		||||
        s->nc_free += (s->free_cluster_index - s->highest_alloc);
 | 
			
		||||
        s->highest_alloc = s->free_cluster_index;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return (s->free_cluster_index - nb_clusters) << s->cluster_bits;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -2418,12 +2380,6 @@ static int update_cluster_refcount(BlockDriverState *bs,
 | 
			
		||||
    block_index = cluster_index &
 | 
			
		||||
        ((1 << (s->cluster_bits - REFCOUNT_SHIFT)) - 1);
 | 
			
		||||
    refcount = be16_to_cpu(s->refcount_block_cache[block_index]);
 | 
			
		||||
 | 
			
		||||
    if (refcount == 1 && addend == -1)
 | 
			
		||||
        s->nc_free += 1;
 | 
			
		||||
    else if (refcount == 0 && addend == 1)
 | 
			
		||||
        s->nc_free -= 1;
 | 
			
		||||
 | 
			
		||||
    refcount += addend;
 | 
			
		||||
    if (refcount < 0 || refcount > 0xffff)
 | 
			
		||||
        return -EINVAL;
 | 
			
		||||
@@ -2645,6 +2601,31 @@ static void dump_refcounts(BlockDriverState *bs)
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static int qcow_put_buffer(BlockDriverState *bs, const uint8_t *buf,
 | 
			
		||||
                           int64_t pos, int size)
 | 
			
		||||
{
 | 
			
		||||
    int growable = bs->growable;
 | 
			
		||||
 | 
			
		||||
    bs->growable = 1;
 | 
			
		||||
    bdrv_pwrite(bs, pos, buf, size);
 | 
			
		||||
    bs->growable = growable;
 | 
			
		||||
 | 
			
		||||
    return size;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int qcow_get_buffer(BlockDriverState *bs, uint8_t *buf,
 | 
			
		||||
                           int64_t pos, int size)
 | 
			
		||||
{
 | 
			
		||||
    int growable = bs->growable;
 | 
			
		||||
    int ret;
 | 
			
		||||
 | 
			
		||||
    bs->growable = 1;
 | 
			
		||||
    ret = bdrv_pread(bs, pos, buf, size);
 | 
			
		||||
    bs->growable = growable;
 | 
			
		||||
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
BlockDriver bdrv_qcow2 = {
 | 
			
		||||
    "qcow2",
 | 
			
		||||
    sizeof(BDRVQcowState),
 | 
			
		||||
@@ -2670,4 +2651,7 @@ BlockDriver bdrv_qcow2 = {
 | 
			
		||||
    .bdrv_snapshot_delete = qcow_snapshot_delete,
 | 
			
		||||
    .bdrv_snapshot_list = qcow_snapshot_list,
 | 
			
		||||
    .bdrv_get_info = qcow_get_info,
 | 
			
		||||
 | 
			
		||||
    .bdrv_put_buffer    = qcow_put_buffer,
 | 
			
		||||
    .bdrv_get_buffer    = qcow_get_buffer,
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -399,10 +399,15 @@ static int find_device_type(BlockDriverState *bs, const char *filename)
 | 
			
		||||
            return FTYPE_HARDDISK;
 | 
			
		||||
        snprintf(s->drive_path, sizeof(s->drive_path), "%c:\\", p[0]);
 | 
			
		||||
        type = GetDriveType(s->drive_path);
 | 
			
		||||
        if (type == DRIVE_CDROM)
 | 
			
		||||
        switch (type) {
 | 
			
		||||
        case DRIVE_REMOVABLE:
 | 
			
		||||
        case DRIVE_FIXED:
 | 
			
		||||
            return FTYPE_HARDDISK;
 | 
			
		||||
        case DRIVE_CDROM:
 | 
			
		||||
            return FTYPE_CD;
 | 
			
		||||
        else
 | 
			
		||||
        default:
 | 
			
		||||
            return FTYPE_FILE;
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        return FTYPE_FILE;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										101
									
								
								block.c
									
									
									
									
									
								
							
							
						
						
									
										101
									
								
								block.c
									
									
									
									
									
								
							@@ -311,8 +311,6 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags)
 | 
			
		||||
    int ret;
 | 
			
		||||
 | 
			
		||||
    bs = bdrv_new("");
 | 
			
		||||
    if (!bs)
 | 
			
		||||
        return -ENOMEM;
 | 
			
		||||
    ret = bdrv_open2(bs, filename, flags | BDRV_O_FILE, NULL);
 | 
			
		||||
    if (ret < 0) {
 | 
			
		||||
        bdrv_delete(bs);
 | 
			
		||||
@@ -338,6 +336,7 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
 | 
			
		||||
    bs->read_only = 0;
 | 
			
		||||
    bs->is_temporary = 0;
 | 
			
		||||
    bs->encrypted = 0;
 | 
			
		||||
    bs->valid_key = 0;
 | 
			
		||||
 | 
			
		||||
    if (flags & BDRV_O_SNAPSHOT) {
 | 
			
		||||
        BlockDriverState *bs1;
 | 
			
		||||
@@ -349,12 +348,10 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
 | 
			
		||||
 | 
			
		||||
        /* if there is a backing file, use it */
 | 
			
		||||
        bs1 = bdrv_new("");
 | 
			
		||||
        if (!bs1) {
 | 
			
		||||
            return -ENOMEM;
 | 
			
		||||
        }
 | 
			
		||||
        if (bdrv_open(bs1, filename, 0) < 0) {
 | 
			
		||||
        ret = bdrv_open(bs1, filename, 0);
 | 
			
		||||
        if (ret < 0) {
 | 
			
		||||
            bdrv_delete(bs1);
 | 
			
		||||
            return -1;
 | 
			
		||||
            return ret;
 | 
			
		||||
        }
 | 
			
		||||
        total_size = bdrv_getlength(bs1) >> SECTOR_BITS;
 | 
			
		||||
 | 
			
		||||
@@ -372,9 +369,10 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
 | 
			
		||||
        else
 | 
			
		||||
            realpath(filename, backing_filename);
 | 
			
		||||
 | 
			
		||||
        if (bdrv_create(&bdrv_qcow2, tmp_filename,
 | 
			
		||||
                        total_size, backing_filename, 0) < 0) {
 | 
			
		||||
            return -1;
 | 
			
		||||
        ret = bdrv_create(&bdrv_qcow2, tmp_filename,
 | 
			
		||||
                          total_size, backing_filename, 0);
 | 
			
		||||
        if (ret < 0) {
 | 
			
		||||
            return ret;
 | 
			
		||||
        }
 | 
			
		||||
        filename = tmp_filename;
 | 
			
		||||
        bs->is_temporary = 1;
 | 
			
		||||
@@ -383,14 +381,12 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
 | 
			
		||||
    pstrcpy(bs->filename, sizeof(bs->filename), filename);
 | 
			
		||||
    if (flags & BDRV_O_FILE) {
 | 
			
		||||
        drv = find_protocol(filename);
 | 
			
		||||
        if (!drv)
 | 
			
		||||
            return -ENOENT;
 | 
			
		||||
    } else {
 | 
			
		||||
        if (!drv) {
 | 
			
		||||
    } else if (!drv) {
 | 
			
		||||
        drv = find_image_format(filename);
 | 
			
		||||
            if (!drv)
 | 
			
		||||
                return -1;
 | 
			
		||||
    }
 | 
			
		||||
    if (!drv) {
 | 
			
		||||
        ret = -ENOENT;
 | 
			
		||||
        goto unlink_and_fail;
 | 
			
		||||
    }
 | 
			
		||||
    bs->drv = drv;
 | 
			
		||||
    bs->opaque = qemu_mallocz(drv->instance_size);
 | 
			
		||||
@@ -409,6 +405,9 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
 | 
			
		||||
        qemu_free(bs->opaque);
 | 
			
		||||
        bs->opaque = NULL;
 | 
			
		||||
        bs->drv = NULL;
 | 
			
		||||
    unlink_and_fail:
 | 
			
		||||
        if (bs->is_temporary)
 | 
			
		||||
            unlink(filename);
 | 
			
		||||
        return ret;
 | 
			
		||||
    }
 | 
			
		||||
    if (drv->bdrv_getlength) {
 | 
			
		||||
@@ -422,15 +421,13 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
 | 
			
		||||
    if (bs->backing_file[0] != '\0') {
 | 
			
		||||
        /* if there is a backing file, use it */
 | 
			
		||||
        bs->backing_hd = bdrv_new("");
 | 
			
		||||
        if (!bs->backing_hd) {
 | 
			
		||||
        fail:
 | 
			
		||||
            bdrv_close(bs);
 | 
			
		||||
            return -ENOMEM;
 | 
			
		||||
        }
 | 
			
		||||
        path_combine(backing_filename, sizeof(backing_filename),
 | 
			
		||||
                     filename, bs->backing_file);
 | 
			
		||||
        if (bdrv_open(bs->backing_hd, backing_filename, open_flags) < 0)
 | 
			
		||||
            goto fail;
 | 
			
		||||
        ret = bdrv_open(bs->backing_hd, backing_filename, open_flags);
 | 
			
		||||
        if (ret < 0) {
 | 
			
		||||
            bdrv_close(bs);
 | 
			
		||||
            return ret;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* call the change callback */
 | 
			
		||||
@@ -970,6 +967,15 @@ int bdrv_is_encrypted(BlockDriverState *bs)
 | 
			
		||||
    return bs->encrypted;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int bdrv_key_required(BlockDriverState *bs)
 | 
			
		||||
{
 | 
			
		||||
    BlockDriverState *backing_hd = bs->backing_hd;
 | 
			
		||||
 | 
			
		||||
    if (backing_hd && backing_hd->encrypted && !backing_hd->valid_key)
 | 
			
		||||
        return 1;
 | 
			
		||||
    return (bs->encrypted && !bs->valid_key);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int bdrv_set_key(BlockDriverState *bs, const char *key)
 | 
			
		||||
{
 | 
			
		||||
    int ret;
 | 
			
		||||
@@ -982,7 +988,9 @@ int bdrv_set_key(BlockDriverState *bs, const char *key)
 | 
			
		||||
    }
 | 
			
		||||
    if (!bs->encrypted || !bs->drv || !bs->drv->bdrv_set_key)
 | 
			
		||||
        return -1;
 | 
			
		||||
    return bs->drv->bdrv_set_key(bs, key);
 | 
			
		||||
    ret = bs->drv->bdrv_set_key(bs, key);
 | 
			
		||||
    bs->valid_key = (ret == 0);
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size)
 | 
			
		||||
@@ -1015,12 +1023,12 @@ BlockDriverState *bdrv_find(const char *name)
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void bdrv_iterate(void (*it)(void *opaque, const char *name), void *opaque)
 | 
			
		||||
void bdrv_iterate(void (*it)(void *opaque, BlockDriverState *bs), void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    BlockDriverState *bs;
 | 
			
		||||
 | 
			
		||||
    for (bs = bdrv_first; bs != NULL; bs = bs->next) {
 | 
			
		||||
        it(opaque, bs->device_name);
 | 
			
		||||
        it(opaque, bs);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1105,8 +1113,7 @@ void bdrv_info(void)
 | 
			
		||||
	    }
 | 
			
		||||
            term_printf(" ro=%d", bs->read_only);
 | 
			
		||||
            term_printf(" drv=%s", bs->drv->format_name);
 | 
			
		||||
            if (bs->encrypted)
 | 
			
		||||
                term_printf(" encrypted");
 | 
			
		||||
            term_printf(" encrypted=%d", bdrv_is_encrypted(bs));
 | 
			
		||||
        } else {
 | 
			
		||||
            term_printf(" [not inserted]");
 | 
			
		||||
        }
 | 
			
		||||
@@ -1118,7 +1125,6 @@ void bdrv_info(void)
 | 
			
		||||
void bdrv_info_stats (void)
 | 
			
		||||
{
 | 
			
		||||
    BlockDriverState *bs;
 | 
			
		||||
    BlockDriverInfo bdi;
 | 
			
		||||
 | 
			
		||||
    for (bs = bdrv_first; bs != NULL; bs = bs->next) {
 | 
			
		||||
	term_printf ("%s:"
 | 
			
		||||
@@ -1126,18 +1132,23 @@ void bdrv_info_stats (void)
 | 
			
		||||
		     " wr_bytes=%" PRIu64
 | 
			
		||||
		     " rd_operations=%" PRIu64
 | 
			
		||||
		     " wr_operations=%" PRIu64
 | 
			
		||||
                     ,
 | 
			
		||||
                     "\n",
 | 
			
		||||
		     bs->device_name,
 | 
			
		||||
		     bs->rd_bytes, bs->wr_bytes,
 | 
			
		||||
		     bs->rd_ops, bs->wr_ops);
 | 
			
		||||
        if (bdrv_get_info(bs, &bdi) == 0)
 | 
			
		||||
            term_printf(" high=%" PRId64
 | 
			
		||||
                        " bytes_free=%" PRId64,
 | 
			
		||||
                        bdi.highest_alloc, bdi.num_free_bytes);
 | 
			
		||||
        term_printf("\n");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char *bdrv_get_encrypted_filename(BlockDriverState *bs)
 | 
			
		||||
{
 | 
			
		||||
    if (bs->backing_hd && bs->backing_hd->encrypted)
 | 
			
		||||
        return bs->backing_file;
 | 
			
		||||
    else if (bs->encrypted)
 | 
			
		||||
        return bs->filename;
 | 
			
		||||
    else
 | 
			
		||||
        return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void bdrv_get_backing_filename(BlockDriverState *bs,
 | 
			
		||||
                               char *filename, int filename_size)
 | 
			
		||||
{
 | 
			
		||||
@@ -1170,6 +1181,26 @@ int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
 | 
			
		||||
    return drv->bdrv_get_info(bs, bdi);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int bdrv_put_buffer(BlockDriverState *bs, const uint8_t *buf, int64_t pos, int size)
 | 
			
		||||
{
 | 
			
		||||
    BlockDriver *drv = bs->drv;
 | 
			
		||||
    if (!drv)
 | 
			
		||||
        return -ENOMEDIUM;
 | 
			
		||||
    if (!drv->bdrv_put_buffer)
 | 
			
		||||
        return -ENOTSUP;
 | 
			
		||||
    return drv->bdrv_put_buffer(bs, buf, pos, size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int bdrv_get_buffer(BlockDriverState *bs, uint8_t *buf, int64_t pos, int size)
 | 
			
		||||
{
 | 
			
		||||
    BlockDriver *drv = bs->drv;
 | 
			
		||||
    if (!drv)
 | 
			
		||||
        return -ENOMEDIUM;
 | 
			
		||||
    if (!drv->bdrv_get_buffer)
 | 
			
		||||
        return -ENOTSUP;
 | 
			
		||||
    return drv->bdrv_get_buffer(bs, buf, pos, size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**************************************************************/
 | 
			
		||||
/* handling of snapshots */
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										15
									
								
								block.h
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								block.h
									
									
									
									
									
								
							@@ -26,8 +26,6 @@ typedef struct BlockDriverInfo {
 | 
			
		||||
    int cluster_size;
 | 
			
		||||
    /* offset at which the VM state can be saved (0 if not possible) */
 | 
			
		||||
    int64_t vm_state_offset;
 | 
			
		||||
    int64_t highest_alloc; /* highest allocated block offset (in bytes) */
 | 
			
		||||
    int64_t num_free_bytes; /* below highest_alloc  */
 | 
			
		||||
} BlockDriverInfo;
 | 
			
		||||
 | 
			
		||||
typedef struct QEMUSnapshotInfo {
 | 
			
		||||
@@ -103,8 +101,6 @@ BlockDriverAIOCB *bdrv_aio_write(BlockDriverState *bs, int64_t sector_num,
 | 
			
		||||
                                 BlockDriverCompletionFunc *cb, void *opaque);
 | 
			
		||||
void bdrv_aio_cancel(BlockDriverAIOCB *acb);
 | 
			
		||||
 | 
			
		||||
int qemu_key_check(BlockDriverState *bs, const char *name);
 | 
			
		||||
 | 
			
		||||
/* Ensure contents are flushed to disk.  */
 | 
			
		||||
void bdrv_flush(BlockDriverState *bs);
 | 
			
		||||
void bdrv_flush_all(void);
 | 
			
		||||
@@ -141,9 +137,12 @@ void bdrv_set_change_cb(BlockDriverState *bs,
 | 
			
		||||
                        void (*change_cb)(void *opaque), void *opaque);
 | 
			
		||||
void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size);
 | 
			
		||||
BlockDriverState *bdrv_find(const char *name);
 | 
			
		||||
void bdrv_iterate(void (*it)(void *opaque, const char *name), void *opaque);
 | 
			
		||||
void bdrv_iterate(void (*it)(void *opaque, BlockDriverState *bs),
 | 
			
		||||
                  void *opaque);
 | 
			
		||||
int bdrv_is_encrypted(BlockDriverState *bs);
 | 
			
		||||
int bdrv_key_required(BlockDriverState *bs);
 | 
			
		||||
int bdrv_set_key(BlockDriverState *bs, const char *key);
 | 
			
		||||
int bdrv_query_missing_keys(void);
 | 
			
		||||
void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
 | 
			
		||||
                         void *opaque);
 | 
			
		||||
const char *bdrv_get_device_name(BlockDriverState *bs);
 | 
			
		||||
@@ -151,6 +150,7 @@ int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,
 | 
			
		||||
                          const uint8_t *buf, int nb_sectors);
 | 
			
		||||
int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi);
 | 
			
		||||
 | 
			
		||||
const char *bdrv_get_encrypted_filename(BlockDriverState *bs);
 | 
			
		||||
void bdrv_get_backing_filename(BlockDriverState *bs,
 | 
			
		||||
                               char *filename, int filename_size);
 | 
			
		||||
int bdrv_snapshot_create(BlockDriverState *bs,
 | 
			
		||||
@@ -169,4 +169,9 @@ void path_combine(char *dest, int dest_size,
 | 
			
		||||
                  const char *base_path,
 | 
			
		||||
                  const char *filename);
 | 
			
		||||
 | 
			
		||||
int bdrv_put_buffer(BlockDriverState *bs, const uint8_t *buf,
 | 
			
		||||
                    int64_t pos, int size);
 | 
			
		||||
 | 
			
		||||
int bdrv_get_buffer(BlockDriverState *bs, uint8_t *buf, int64_t pos, int size);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -76,6 +76,11 @@ struct BlockDriver {
 | 
			
		||||
                              QEMUSnapshotInfo **psn_info);
 | 
			
		||||
    int (*bdrv_get_info)(BlockDriverState *bs, BlockDriverInfo *bdi);
 | 
			
		||||
 | 
			
		||||
    int (*bdrv_put_buffer)(BlockDriverState *bs, const uint8_t *buf,
 | 
			
		||||
                           int64_t pos, int size);
 | 
			
		||||
    int (*bdrv_get_buffer)(BlockDriverState *bs, uint8_t *buf,
 | 
			
		||||
                           int64_t pos, int size);
 | 
			
		||||
 | 
			
		||||
    /* removable device specific */
 | 
			
		||||
    int (*bdrv_is_inserted)(BlockDriverState *bs);
 | 
			
		||||
    int (*bdrv_media_changed)(BlockDriverState *bs);
 | 
			
		||||
@@ -96,6 +101,7 @@ struct BlockDriverState {
 | 
			
		||||
    int removable; /* if true, the media can be removed */
 | 
			
		||||
    int locked;    /* if true, the media cannot temporarily be ejected */
 | 
			
		||||
    int encrypted; /* if true, the media is encrypted */
 | 
			
		||||
    int valid_key; /* if true, a valid encryption key has been set */
 | 
			
		||||
    int sg;        /* if true, the device is a /dev/sg* */
 | 
			
		||||
    /* event callback when inserting/removing */
 | 
			
		||||
    void (*change_cb)(void *opaque);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								configure
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								configure
									
									
									
									
										vendored
									
									
								
							@@ -1013,7 +1013,7 @@ EOF
 | 
			
		||||
    kvm="no";
 | 
			
		||||
    if [ -x "`which awk 2>/dev/null`" ] && \
 | 
			
		||||
       [ -x "`which grep 2>/dev/null`" ]; then
 | 
			
		||||
      kvmerr=`$cc $ARCH_CFLAGS -o $TMPE ${OS_CFLAGS} $kvm_cflags $TMPC 2>&1 \
 | 
			
		||||
      kvmerr=`LANG=C $cc $ARCH_CFLAGS -o $TMPE ${OS_CFLAGS} $kvm_cflags $TMPC 2>&1 \
 | 
			
		||||
	| grep "error: " \
 | 
			
		||||
	| awk -F "error: " '{if (NR>1) printf(", "); printf("%s",$2);}'`
 | 
			
		||||
      if test "$kvmerr" != "" ; then
 | 
			
		||||
 
 | 
			
		||||
@@ -302,10 +302,9 @@ void term_printf(const char *fmt, ...) __attribute__ ((__format__ (__printf__, 1
 | 
			
		||||
void term_print_filename(const char *filename);
 | 
			
		||||
void term_flush(void);
 | 
			
		||||
void term_print_help(void);
 | 
			
		||||
void monitor_readline(const char *prompt, int is_password,
 | 
			
		||||
                      char *buf, int buf_size);
 | 
			
		||||
void monitor_suspend(void);
 | 
			
		||||
void monitor_resume(void);
 | 
			
		||||
int monitor_read_bdrv_key(BlockDriverState *bs);
 | 
			
		||||
 | 
			
		||||
/* readline.c */
 | 
			
		||||
typedef void ReadLineFunc(void *opaque, const char *str);
 | 
			
		||||
 
 | 
			
		||||
@@ -27,6 +27,7 @@
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#include <setjmp.h>
 | 
			
		||||
#include <inttypes.h>
 | 
			
		||||
#include <signal.h>
 | 
			
		||||
#include "osdep.h"
 | 
			
		||||
#include "sys-queue.h"
 | 
			
		||||
 | 
			
		||||
@@ -170,6 +171,7 @@ typedef struct CPUWatchpoint {
 | 
			
		||||
                                     memory was accessed */             \
 | 
			
		||||
    uint32_t halted; /* Nonzero if the CPU is in suspend state */       \
 | 
			
		||||
    uint32_t interrupt_request;                                         \
 | 
			
		||||
    volatile sig_atomic_t exit_request;                                 \
 | 
			
		||||
    /* The meaning of the MMU modes is defined in the target code. */   \
 | 
			
		||||
    CPUTLBEntry tlb_table[NB_MMU_MODES][CPU_TLB_SIZE];                  \
 | 
			
		||||
    target_phys_addr_t iotlb[NB_MMU_MODES][CPU_TLB_SIZE];               \
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										12
									
								
								cpu-exec.c
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								cpu-exec.c
									
									
									
									
									
								
							@@ -311,7 +311,7 @@ int cpu_exec(CPUState *env1)
 | 
			
		||||
                env->exception_index = -1;
 | 
			
		||||
            }
 | 
			
		||||
#ifdef USE_KQEMU
 | 
			
		||||
            if (kqemu_is_ok(env) && env->interrupt_request == 0) {
 | 
			
		||||
            if (kqemu_is_ok(env) && env->interrupt_request == 0 && env->exit_request == 0) {
 | 
			
		||||
                int ret;
 | 
			
		||||
                env->eflags = env->eflags | helper_cc_compute_all(CC_OP) | (DF & DF_MASK);
 | 
			
		||||
                ret = kqemu_cpu_exec(env);
 | 
			
		||||
@@ -326,7 +326,7 @@ int cpu_exec(CPUState *env1)
 | 
			
		||||
                } else if (ret == 2) {
 | 
			
		||||
                    /* softmmu execution needed */
 | 
			
		||||
                } else {
 | 
			
		||||
                    if (env->interrupt_request != 0) {
 | 
			
		||||
                    if (env->interrupt_request != 0 || env->exit_request != 0) {
 | 
			
		||||
                        /* hardware interrupt will be executed just after */
 | 
			
		||||
                    } else {
 | 
			
		||||
                        /* otherwise, we restart */
 | 
			
		||||
@@ -525,12 +525,12 @@ int cpu_exec(CPUState *env1)
 | 
			
		||||
                           the program flow was changed */
 | 
			
		||||
                        next_tb = 0;
 | 
			
		||||
                    }
 | 
			
		||||
                    if (interrupt_request & CPU_INTERRUPT_EXIT) {
 | 
			
		||||
                        env->interrupt_request &= ~CPU_INTERRUPT_EXIT;
 | 
			
		||||
                }
 | 
			
		||||
                if (unlikely(env->exit_request)) {
 | 
			
		||||
                    env->exit_request = 0;
 | 
			
		||||
                    env->exception_index = EXCP_INTERRUPT;
 | 
			
		||||
                    cpu_loop_exit();
 | 
			
		||||
                }
 | 
			
		||||
                }
 | 
			
		||||
#ifdef DEBUG_EXEC
 | 
			
		||||
                if (qemu_loglevel_mask(CPU_LOG_TB_CPU)) {
 | 
			
		||||
                    /* restore flags in standard format */
 | 
			
		||||
@@ -599,7 +599,7 @@ int cpu_exec(CPUState *env1)
 | 
			
		||||
                   TB, but before it is linked into a potentially
 | 
			
		||||
                   infinite loop and becomes env->current_tb. Avoid
 | 
			
		||||
                   starting execution if there is a pending interrupt. */
 | 
			
		||||
                if (unlikely (env->interrupt_request & CPU_INTERRUPT_EXIT))
 | 
			
		||||
                if (unlikely (env->exit_request))
 | 
			
		||||
                    env->current_tb = NULL;
 | 
			
		||||
 | 
			
		||||
                while (env->current_tb) {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										12
									
								
								exec.c
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								exec.c
									
									
									
									
									
								
							@@ -523,6 +523,7 @@ static int cpu_common_load(QEMUFile *f, void *opaque, int version_id)
 | 
			
		||||
 | 
			
		||||
    qemu_get_be32s(f, &env->halted);
 | 
			
		||||
    qemu_get_be32s(f, &env->interrupt_request);
 | 
			
		||||
    env->interrupt_request &= ~CPU_INTERRUPT_EXIT;
 | 
			
		||||
    tlb_flush(env, 1);
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
@@ -1501,9 +1502,12 @@ void cpu_interrupt(CPUState *env, int mask)
 | 
			
		||||
#endif
 | 
			
		||||
    int old_mask;
 | 
			
		||||
 | 
			
		||||
    if (mask & CPU_INTERRUPT_EXIT) {
 | 
			
		||||
        env->exit_request = 1;
 | 
			
		||||
        mask &= ~CPU_INTERRUPT_EXIT;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    old_mask = env->interrupt_request;
 | 
			
		||||
    /* FIXME: This is probably not threadsafe.  A different thread could
 | 
			
		||||
       be in the middle of a read-modify-write operation.  */
 | 
			
		||||
    env->interrupt_request |= mask;
 | 
			
		||||
#if defined(USE_NPTL)
 | 
			
		||||
    /* FIXME: TB unchaining isn't SMP safe.  For now just ignore the
 | 
			
		||||
@@ -1514,10 +1518,8 @@ void cpu_interrupt(CPUState *env, int mask)
 | 
			
		||||
    if (use_icount) {
 | 
			
		||||
        env->icount_decr.u16.high = 0xffff;
 | 
			
		||||
#ifndef CONFIG_USER_ONLY
 | 
			
		||||
        /* CPU_INTERRUPT_EXIT isn't a real interrupt.  It just means
 | 
			
		||||
           an async event happened and we need to process it.  */
 | 
			
		||||
        if (!can_do_io(env)
 | 
			
		||||
            && (mask & ~(old_mask | CPU_INTERRUPT_EXIT)) != 0) {
 | 
			
		||||
            && (mask & ~old_mask) != 0) {
 | 
			
		||||
            cpu_abort(env, "Raised interrupt while not in I/O function");
 | 
			
		||||
        }
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -2637,11 +2637,16 @@ static void map_linear_vram(CirrusVGAState *s)
 | 
			
		||||
 | 
			
		||||
    s->lfb_vram_mapped = 0;
 | 
			
		||||
 | 
			
		||||
    cpu_register_physical_memory(isa_mem_base + 0xa0000, 0x8000,
 | 
			
		||||
                                (s->vram_offset + s->cirrus_bank_base[0]) | IO_MEM_UNASSIGNED);
 | 
			
		||||
    cpu_register_physical_memory(isa_mem_base + 0xa8000, 0x8000,
 | 
			
		||||
                                (s->vram_offset + s->cirrus_bank_base[1]) | IO_MEM_UNASSIGNED);
 | 
			
		||||
    if (!(s->cirrus_srcptr != s->cirrus_srcptr_end)
 | 
			
		||||
        && !((s->sr[0x07] & 0x01) == 0)
 | 
			
		||||
        && !((s->gr[0x0B] & 0x14) == 0x14)
 | 
			
		||||
        && !(s->gr[0x0B] & 0x02)) {
 | 
			
		||||
 | 
			
		||||
        vga_dirty_log_stop((VGAState *)s);
 | 
			
		||||
        cpu_register_physical_memory(isa_mem_base + 0xa0000, 0x8000,
 | 
			
		||||
                                    (s->vram_offset + s->cirrus_bank_base[0]) | IO_MEM_RAM);
 | 
			
		||||
        cpu_register_physical_memory(isa_mem_base + 0xa8000, 0x8000,
 | 
			
		||||
 
 | 
			
		||||
@@ -666,8 +666,8 @@ e1000_receive(void *opaque, const uint8_t *buf, int size)
 | 
			
		||||
    n = E1000_ICS_RXT0;
 | 
			
		||||
    if ((rdt = s->mac_reg[RDT]) < s->mac_reg[RDH])
 | 
			
		||||
        rdt += s->mac_reg[RDLEN] / sizeof(desc);
 | 
			
		||||
    if (((rdt - s->mac_reg[RDH]) * sizeof(desc)) << s->rxbuf_min_shift >=
 | 
			
		||||
        s->mac_reg[RDLEN])
 | 
			
		||||
    if (((rdt - s->mac_reg[RDH]) * sizeof(desc)) <= s->mac_reg[RDLEN] >>
 | 
			
		||||
        s->rxbuf_min_shift)
 | 
			
		||||
        n |= E1000_ICS_RXDMT0;
 | 
			
		||||
 | 
			
		||||
    set_ics(s, 0, n);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								hw/hw.h
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								hw/hw.h
									
									
									
									
									
								
							@@ -67,6 +67,7 @@ unsigned int qemu_get_be32(QEMUFile *f);
 | 
			
		||||
uint64_t qemu_get_be64(QEMUFile *f);
 | 
			
		||||
int qemu_file_rate_limit(QEMUFile *f);
 | 
			
		||||
int qemu_file_has_error(QEMUFile *f);
 | 
			
		||||
void qemu_file_set_error(QEMUFile *f);
 | 
			
		||||
 | 
			
		||||
/* Try to send any outstanding data.  This function is useful when output is
 | 
			
		||||
 * halted due to rate limiting or EAGAIN errors occur as it can be used to
 | 
			
		||||
 
 | 
			
		||||
@@ -1369,6 +1369,8 @@ static uint8_t lsi_reg_readb(LSIState *s, int offset)
 | 
			
		||||
    CASE_GET_REG32(dsa, 0x10)
 | 
			
		||||
    case 0x14: /* ISTAT0 */
 | 
			
		||||
        return s->istat0;
 | 
			
		||||
    case 0x15: /* ISTAT1 */
 | 
			
		||||
        return s->istat1;
 | 
			
		||||
    case 0x16: /* MBOX0 */
 | 
			
		||||
        return s->mbox0;
 | 
			
		||||
    case 0x17: /* MBOX1 */
 | 
			
		||||
 
 | 
			
		||||
@@ -95,19 +95,22 @@ static PCIDevice *qemu_pci_hot_add_storage(PCIBus *pci_bus, const char *opts)
 | 
			
		||||
            type = IF_SCSI;
 | 
			
		||||
        else if (!strcmp(buf, "virtio")) {
 | 
			
		||||
            type = IF_VIRTIO;
 | 
			
		||||
        } else {
 | 
			
		||||
            term_printf("type %s not a hotpluggable PCI device.\n", buf);
 | 
			
		||||
            goto out;
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        term_printf("no if= specified\n");
 | 
			
		||||
        return NULL;
 | 
			
		||||
        goto out;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (get_param_value(buf, sizeof(buf), "file", opts)) {
 | 
			
		||||
        drive_idx = add_init_drive(opts);
 | 
			
		||||
        if (drive_idx < 0)
 | 
			
		||||
            return NULL;
 | 
			
		||||
            goto out;
 | 
			
		||||
    } else if (type == IF_VIRTIO) {
 | 
			
		||||
        term_printf("virtio requires a backing file/device.\n");
 | 
			
		||||
        return NULL;
 | 
			
		||||
        goto out;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    switch (type) {
 | 
			
		||||
@@ -120,10 +123,9 @@ static PCIDevice *qemu_pci_hot_add_storage(PCIBus *pci_bus, const char *opts)
 | 
			
		||||
    case IF_VIRTIO:
 | 
			
		||||
        opaque = virtio_blk_init (pci_bus, drives_table[drive_idx].bdrv);
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        term_printf ("type %s not a hotpluggable PCI device.\n", buf);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
out:
 | 
			
		||||
    return opaque;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										18
									
								
								hw/r2d.c
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								hw/r2d.c
									
									
									
									
									
								
							@@ -37,6 +37,9 @@
 | 
			
		||||
 | 
			
		||||
#define SM501_VRAM_SIZE 0x800000
 | 
			
		||||
 | 
			
		||||
/* CONFIG_BOOT_LINK_OFFSET of Linux kernel */
 | 
			
		||||
#define LINUX_LOAD_OFFSET 0x800000
 | 
			
		||||
 | 
			
		||||
#define PA_IRLMSK	0x00
 | 
			
		||||
#define PA_POWOFF	0x30
 | 
			
		||||
#define PA_VERREG	0x32
 | 
			
		||||
@@ -233,20 +236,27 @@ static void r2d_init(ram_addr_t ram_size, int vga_ram_size,
 | 
			
		||||
        pci_nic_init(pci, &nd_table[i], (i==0)? 2<<3: -1, "rtl8139");
 | 
			
		||||
 | 
			
		||||
    /* Todo: register on board registers */
 | 
			
		||||
    {
 | 
			
		||||
    if (kernel_filename) {
 | 
			
		||||
      int kernel_size;
 | 
			
		||||
      /* initialization which should be done by firmware */
 | 
			
		||||
      stl_phys(SH7750_BCR1, 1<<3); /* cs3 SDRAM */
 | 
			
		||||
      stw_phys(SH7750_BCR2, 3<<(3*2)); /* cs3 32bit */
 | 
			
		||||
 | 
			
		||||
      kernel_size = load_image(kernel_filename, phys_ram_base);
 | 
			
		||||
      if (kernel_cmdline) {
 | 
			
		||||
          kernel_size = load_image_targphys(kernel_filename,
 | 
			
		||||
				   SDRAM_BASE + LINUX_LOAD_OFFSET,
 | 
			
		||||
				   SDRAM_SIZE - LINUX_LOAD_OFFSET);
 | 
			
		||||
          env->pc = (SDRAM_BASE + LINUX_LOAD_OFFSET) | 0xa0000000;
 | 
			
		||||
          pstrcpy_targphys(SDRAM_BASE + 0x10100, 256, kernel_cmdline);
 | 
			
		||||
      } else {
 | 
			
		||||
          kernel_size = load_image_targphys(kernel_filename, SDRAM_BASE, SDRAM_SIZE);
 | 
			
		||||
          env->pc = SDRAM_BASE | 0xa0000000; /* Start from P2 area */
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (kernel_size < 0) {
 | 
			
		||||
        fprintf(stderr, "qemu: could not load kernel '%s'\n", kernel_filename);
 | 
			
		||||
        exit(1);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      env->pc = SDRAM_BASE | 0xa0000000; /* Start from P2 area */
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -11,6 +11,7 @@
 | 
			
		||||
#include "usb.h"
 | 
			
		||||
#include "block.h"
 | 
			
		||||
#include "scsi-disk.h"
 | 
			
		||||
#include "console.h"
 | 
			
		||||
 | 
			
		||||
//#define DEBUG_MSD
 | 
			
		||||
 | 
			
		||||
@@ -513,7 +514,7 @@ static void usb_msd_handle_destroy(USBDevice *dev)
 | 
			
		||||
    qemu_free(s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
USBDevice *usb_msd_init(const char *filename)
 | 
			
		||||
USBDevice *usb_msd_init(const char *filename, BlockDriverState **pbs)
 | 
			
		||||
{
 | 
			
		||||
    MSDState *s;
 | 
			
		||||
    BlockDriverState *bdrv;
 | 
			
		||||
@@ -552,9 +553,8 @@ USBDevice *usb_msd_init(const char *filename)
 | 
			
		||||
    bdrv = bdrv_new("usb");
 | 
			
		||||
    if (bdrv_open2(bdrv, filename, 0, drv) < 0)
 | 
			
		||||
        goto fail;
 | 
			
		||||
    if (qemu_key_check(bdrv, filename))
 | 
			
		||||
        goto fail;
 | 
			
		||||
    s->bs = bdrv;
 | 
			
		||||
    *pbs = bdrv;
 | 
			
		||||
 | 
			
		||||
    s->dev.speed = USB_SPEED_FULL;
 | 
			
		||||
    s->dev.handle_packet = usb_generic_handle_packet;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										5
									
								
								hw/usb.h
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								hw/usb.h
									
									
									
									
									
								
							@@ -21,6 +21,9 @@
 | 
			
		||||
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
			
		||||
 * THE SOFTWARE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "block.h"
 | 
			
		||||
 | 
			
		||||
#define USB_TOKEN_SETUP 0x2d
 | 
			
		||||
#define USB_TOKEN_IN    0x69 /* device -> host */
 | 
			
		||||
#define USB_TOKEN_OUT   0xe1 /* host -> device */
 | 
			
		||||
@@ -250,7 +253,7 @@ USBDevice *usb_keyboard_init(void);
 | 
			
		||||
void usb_hid_datain_cb(USBDevice *dev, void *opaque, void (*datain)(void *));
 | 
			
		||||
 | 
			
		||||
/* usb-msd.c */
 | 
			
		||||
USBDevice *usb_msd_init(const char *filename);
 | 
			
		||||
USBDevice *usb_msd_init(const char *filename, BlockDriverState **pbs);
 | 
			
		||||
 | 
			
		||||
/* usb-net.c */
 | 
			
		||||
USBDevice *usb_net_init(NICInfo *nd);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										25
									
								
								hw/vga.c
									
									
									
									
									
								
							
							
						
						
									
										25
									
								
								hw/vga.c
									
									
									
									
									
								
							@@ -1616,6 +1616,16 @@ static void vga_draw_graphic(VGAState *s, int full_update)
 | 
			
		||||
        s->double_scan = double_scan;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (shift_control == 0) {
 | 
			
		||||
        if (s->sr[0x01] & 8) {
 | 
			
		||||
            disp_width <<= 1;
 | 
			
		||||
        }
 | 
			
		||||
    } else if (shift_control == 1) {
 | 
			
		||||
        if (s->sr[0x01] & 8) {
 | 
			
		||||
            disp_width <<= 1;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    depth = s->get_bpp(s);
 | 
			
		||||
    if (s->line_offset != s->last_line_offset ||
 | 
			
		||||
        disp_width != s->last_width ||
 | 
			
		||||
@@ -1661,7 +1671,6 @@ static void vga_draw_graphic(VGAState *s, int full_update)
 | 
			
		||||
        full_update |= update_palette16(s);
 | 
			
		||||
        if (s->sr[0x01] & 8) {
 | 
			
		||||
            v = VGA_DRAW_LINE4D2;
 | 
			
		||||
            disp_width <<= 1;
 | 
			
		||||
        } else {
 | 
			
		||||
            v = VGA_DRAW_LINE4;
 | 
			
		||||
        }
 | 
			
		||||
@@ -1670,7 +1679,6 @@ static void vga_draw_graphic(VGAState *s, int full_update)
 | 
			
		||||
        full_update |= update_palette16(s);
 | 
			
		||||
        if (s->sr[0x01] & 8) {
 | 
			
		||||
            v = VGA_DRAW_LINE2D2;
 | 
			
		||||
            disp_width <<= 1;
 | 
			
		||||
        } else {
 | 
			
		||||
            v = VGA_DRAW_LINE2;
 | 
			
		||||
        }
 | 
			
		||||
@@ -2482,6 +2490,17 @@ int isa_vga_mm_init(uint8_t *vga_ram_base,
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void pci_vga_write_config(PCIDevice *d,
 | 
			
		||||
                                 uint32_t address, uint32_t val, int len)
 | 
			
		||||
{
 | 
			
		||||
    PCIVGAState *pvs = container_of(d, PCIVGAState, dev);
 | 
			
		||||
    VGAState *s = &pvs->vga_state;
 | 
			
		||||
 | 
			
		||||
    vga_dirty_log_stop(s);
 | 
			
		||||
    pci_default_write_config(d, address, val, len);
 | 
			
		||||
    vga_dirty_log_start(s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int pci_vga_init(PCIBus *bus, uint8_t *vga_ram_base,
 | 
			
		||||
                 unsigned long vga_ram_offset, int vga_ram_size,
 | 
			
		||||
                 unsigned long vga_bios_offset, int vga_bios_size)
 | 
			
		||||
@@ -2492,7 +2511,7 @@ int pci_vga_init(PCIBus *bus, uint8_t *vga_ram_base,
 | 
			
		||||
 | 
			
		||||
    d = (PCIVGAState *)pci_register_device(bus, "VGA",
 | 
			
		||||
                                           sizeof(PCIVGAState),
 | 
			
		||||
                                           -1, NULL, NULL);
 | 
			
		||||
                                           -1, NULL, pci_vga_write_config);
 | 
			
		||||
    if (!d)
 | 
			
		||||
        return -1;
 | 
			
		||||
    s = &d->vga_state;
 | 
			
		||||
 
 | 
			
		||||
@@ -113,6 +113,21 @@ static uint32_t virtio_net_get_features(VirtIODevice *vdev)
 | 
			
		||||
    return features;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint32_t virtio_net_bad_features(VirtIODevice *vdev)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t features = 0;
 | 
			
		||||
 | 
			
		||||
    /* Linux kernel 2.6.25.  It understood MAC (as everyone must),
 | 
			
		||||
     * but also these: */
 | 
			
		||||
    features |= (1 << VIRTIO_NET_F_MAC);
 | 
			
		||||
    features |= (1 << VIRTIO_NET_F_GUEST_CSUM);
 | 
			
		||||
    features |= (1 << VIRTIO_NET_F_GUEST_TSO4);
 | 
			
		||||
    features |= (1 << VIRTIO_NET_F_GUEST_TSO6);
 | 
			
		||||
    features |= (1 << VIRTIO_NET_F_GUEST_ECN);
 | 
			
		||||
 | 
			
		||||
    return features & virtio_net_get_features(vdev);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void virtio_net_set_features(VirtIODevice *vdev, uint32_t features)
 | 
			
		||||
{
 | 
			
		||||
    VirtIONet *n = to_virtio_net(vdev);
 | 
			
		||||
@@ -228,7 +243,7 @@ static void virtio_net_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (elem.out_sg[0].iov_len < sizeof(ctrl) ||
 | 
			
		||||
            elem.out_sg[elem.in_num - 1].iov_len < sizeof(status)) {
 | 
			
		||||
            elem.in_sg[elem.in_num - 1].iov_len < sizeof(status)) {
 | 
			
		||||
            fprintf(stderr, "virtio-net ctrl header not in correct element\n");
 | 
			
		||||
            exit(1);
 | 
			
		||||
        }
 | 
			
		||||
@@ -580,6 +595,7 @@ PCIDevice *virtio_net_init(PCIBus *bus, NICInfo *nd, int devfn)
 | 
			
		||||
    n->vdev.set_config = virtio_net_set_config;
 | 
			
		||||
    n->vdev.get_features = virtio_net_get_features;
 | 
			
		||||
    n->vdev.set_features = virtio_net_set_features;
 | 
			
		||||
    n->vdev.bad_features = virtio_net_bad_features;
 | 
			
		||||
    n->vdev.reset = virtio_net_reset;
 | 
			
		||||
    n->rx_vq = virtio_add_queue(&n->vdev, 256, virtio_net_handle_rx);
 | 
			
		||||
    n->tx_vq = virtio_add_queue(&n->vdev, 256, virtio_net_handle_tx);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										16
									
								
								hw/virtio.c
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								hw/virtio.c
									
									
									
									
									
								
							@@ -516,6 +516,13 @@ static void virtio_ioport_write(void *opaque, uint32_t addr, uint32_t val)
 | 
			
		||||
 | 
			
		||||
    switch (addr) {
 | 
			
		||||
    case VIRTIO_PCI_GUEST_FEATURES:
 | 
			
		||||
	/* Guest does not negotiate properly?  We have to assume nothing. */
 | 
			
		||||
	if (val & (1 << VIRTIO_F_BAD_FEATURE)) {
 | 
			
		||||
	    if (vdev->bad_features)
 | 
			
		||||
		val = vdev->bad_features(vdev);
 | 
			
		||||
	    else
 | 
			
		||||
		val = 0;
 | 
			
		||||
	}
 | 
			
		||||
        if (vdev->set_features)
 | 
			
		||||
            vdev->set_features(vdev, val);
 | 
			
		||||
        vdev->features = val;
 | 
			
		||||
@@ -555,7 +562,7 @@ static uint32_t virtio_ioport_read(void *opaque, uint32_t addr)
 | 
			
		||||
    switch (addr) {
 | 
			
		||||
    case VIRTIO_PCI_HOST_FEATURES:
 | 
			
		||||
        ret = vdev->get_features(vdev);
 | 
			
		||||
        ret |= (1 << VIRTIO_F_NOTIFY_ON_EMPTY);
 | 
			
		||||
        ret |= (1 << VIRTIO_F_NOTIFY_ON_EMPTY) | (1 << VIRTIO_F_BAD_FEATURE);
 | 
			
		||||
        break;
 | 
			
		||||
    case VIRTIO_PCI_GUEST_FEATURES:
 | 
			
		||||
        ret = vdev->features;
 | 
			
		||||
@@ -726,9 +733,10 @@ VirtQueue *virtio_add_queue(VirtIODevice *vdev, int queue_size,
 | 
			
		||||
 | 
			
		||||
void virtio_notify(VirtIODevice *vdev, VirtQueue *vq)
 | 
			
		||||
{
 | 
			
		||||
    /* Always notify when queue is empty */
 | 
			
		||||
    if ((vq->inuse || vring_avail_idx(vq) != vq->last_avail_idx) &&
 | 
			
		||||
        (vring_avail_flags(vq) & VRING_AVAIL_F_NO_INTERRUPT))
 | 
			
		||||
    /* Always notify when queue is empty (when feature acknowledge) */
 | 
			
		||||
    if ((vring_avail_flags(vq) & VRING_AVAIL_F_NO_INTERRUPT) &&
 | 
			
		||||
        (!(vdev->features & (1 << VIRTIO_F_NOTIFY_ON_EMPTY)) ||
 | 
			
		||||
         (vq->inuse || vring_avail_idx(vq) != vq->last_avail_idx)))
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    vdev->isr |= 0x01;
 | 
			
		||||
 
 | 
			
		||||
@@ -32,6 +32,8 @@
 | 
			
		||||
/* We notify when the ring is completely used, even if the guest is supressing
 | 
			
		||||
 * callbacks */
 | 
			
		||||
#define VIRTIO_F_NOTIFY_ON_EMPTY        24
 | 
			
		||||
/* A guest should never accept this.  It implies negotiation is broken. */
 | 
			
		||||
#define VIRTIO_F_BAD_FEATURE		30
 | 
			
		||||
 | 
			
		||||
/* from Linux's linux/virtio_ring.h */
 | 
			
		||||
 | 
			
		||||
@@ -82,6 +84,7 @@ struct VirtIODevice
 | 
			
		||||
    size_t config_len;
 | 
			
		||||
    void *config;
 | 
			
		||||
    uint32_t (*get_features)(VirtIODevice *vdev);
 | 
			
		||||
    uint32_t (*bad_features)(VirtIODevice *vdev);
 | 
			
		||||
    void (*set_features)(VirtIODevice *vdev, uint32_t val);
 | 
			
		||||
    void (*get_config)(VirtIODevice *vdev, uint8_t *config);
 | 
			
		||||
    void (*set_config)(VirtIODevice *vdev, const uint8_t *config);
 | 
			
		||||
 
 | 
			
		||||
@@ -445,7 +445,7 @@ int kvm_cpu_exec(CPUState *env)
 | 
			
		||||
    do {
 | 
			
		||||
        kvm_arch_pre_run(env, run);
 | 
			
		||||
 | 
			
		||||
        if ((env->interrupt_request & CPU_INTERRUPT_EXIT)) {
 | 
			
		||||
        if (env->exit_request) {
 | 
			
		||||
            dprintf("interrupt exit requested\n");
 | 
			
		||||
            ret = 0;
 | 
			
		||||
            break;
 | 
			
		||||
@@ -512,8 +512,8 @@ int kvm_cpu_exec(CPUState *env)
 | 
			
		||||
        }
 | 
			
		||||
    } while (ret > 0);
 | 
			
		||||
 | 
			
		||||
    if ((env->interrupt_request & CPU_INTERRUPT_EXIT)) {
 | 
			
		||||
        env->interrupt_request &= ~CPU_INTERRUPT_EXIT;
 | 
			
		||||
    if (env->exit_request) {
 | 
			
		||||
        env->exit_request = 0;
 | 
			
		||||
        env->exception_index = EXCP_INTERRUPT;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										3
									
								
								loader.c
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								loader.c
									
									
									
									
									
								
							@@ -90,11 +90,12 @@ int fread_targphys(target_phys_addr_t dst_addr, size_t nbytes, FILE *f)
 | 
			
		||||
    while (nbytes) {
 | 
			
		||||
	want = nbytes > sizeof(buf) ? sizeof(buf) : nbytes;
 | 
			
		||||
	did = fread(buf, 1, want, f);
 | 
			
		||||
	if (did != want) break;
 | 
			
		||||
 | 
			
		||||
	cpu_physical_memory_write_rom(dst_addr, buf, did);
 | 
			
		||||
	dst_addr += did;
 | 
			
		||||
	nbytes -= did;
 | 
			
		||||
	if (did != want)
 | 
			
		||||
	    break;
 | 
			
		||||
    }
 | 
			
		||||
    return dst_addr - dst_begin;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										10
									
								
								migration.c
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								migration.c
									
									
									
									
									
								
							@@ -212,13 +212,19 @@ void migrate_fd_put_ready(void *opaque)
 | 
			
		||||
 | 
			
		||||
    dprintf("iterate\n");
 | 
			
		||||
    if (qemu_savevm_state_iterate(s->file) == 1) {
 | 
			
		||||
        int state;
 | 
			
		||||
        dprintf("done iterating\n");
 | 
			
		||||
        vm_stop(0);
 | 
			
		||||
 | 
			
		||||
        bdrv_flush_all();
 | 
			
		||||
        qemu_savevm_state_complete(s->file);
 | 
			
		||||
        s->state = MIG_STATE_COMPLETED;
 | 
			
		||||
        if ((qemu_savevm_state_complete(s->file)) < 0) {
 | 
			
		||||
            vm_start();
 | 
			
		||||
            state = MIG_STATE_ERROR;
 | 
			
		||||
        } else {
 | 
			
		||||
            state = MIG_STATE_COMPLETED;
 | 
			
		||||
        }
 | 
			
		||||
        migrate_fd_cleanup(s);
 | 
			
		||||
        s->state = state;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										43
									
								
								monitor.c
									
									
									
									
									
								
							
							
						
						
									
										43
									
								
								monitor.c
									
									
									
									
									
								
							@@ -76,6 +76,8 @@ static uint8_t term_outbuf[1024];
 | 
			
		||||
static int term_outbuf_index;
 | 
			
		||||
 | 
			
		||||
static void monitor_start_input(void);
 | 
			
		||||
static void monitor_readline(const char *prompt, int is_password,
 | 
			
		||||
                             char *buf, int buf_size);
 | 
			
		||||
 | 
			
		||||
static CPUState *mon_cpu = NULL;
 | 
			
		||||
 | 
			
		||||
@@ -433,7 +435,7 @@ static void do_change_block(const char *device, const char *filename, const char
 | 
			
		||||
    if (eject_device(bs, 0) < 0)
 | 
			
		||||
        return;
 | 
			
		||||
    bdrv_open2(bs, filename, 0, drv);
 | 
			
		||||
    qemu_key_check(bs, filename);
 | 
			
		||||
    monitor_read_bdrv_key(bs);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void do_change_vnc(const char *target, const char *arg)
 | 
			
		||||
@@ -494,8 +496,23 @@ static void do_stop(void)
 | 
			
		||||
    vm_stop(EXCP_INTERRUPT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void encrypted_bdrv_it(void *opaque, BlockDriverState *bs)
 | 
			
		||||
{
 | 
			
		||||
    int *err = opaque;
 | 
			
		||||
 | 
			
		||||
    if (bdrv_key_required(bs))
 | 
			
		||||
        *err = monitor_read_bdrv_key(bs);
 | 
			
		||||
    else
 | 
			
		||||
        *err = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void do_cont(void)
 | 
			
		||||
{
 | 
			
		||||
    int err = 0;
 | 
			
		||||
 | 
			
		||||
    bdrv_iterate(encrypted_bdrv_it, &err);
 | 
			
		||||
    /* only resume the vm if all keys are set and valid */
 | 
			
		||||
    if (!err)
 | 
			
		||||
        vm_start();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -2679,8 +2696,9 @@ static void file_completion(const char *input)
 | 
			
		||||
    closedir(ffs);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void block_completion_it(void *opaque, const char *name)
 | 
			
		||||
static void block_completion_it(void *opaque, BlockDriverState *bs)
 | 
			
		||||
{
 | 
			
		||||
    const char *name = bdrv_get_device_name(bs);
 | 
			
		||||
    const char *input = opaque;
 | 
			
		||||
 | 
			
		||||
    if (input[0] == '\0' ||
 | 
			
		||||
@@ -2891,7 +2909,7 @@ static void monitor_readline_cb(void *opaque, const char *input)
 | 
			
		||||
    monitor_readline_started = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void monitor_readline(const char *prompt, int is_password,
 | 
			
		||||
static void monitor_readline(const char *prompt, int is_password,
 | 
			
		||||
                             char *buf, int buf_size)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
@@ -2922,3 +2940,22 @@ void monitor_readline(const char *prompt, int is_password,
 | 
			
		||||
                monitor_hd[i]->focus = old_focus[i];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int monitor_read_bdrv_key(BlockDriverState *bs)
 | 
			
		||||
{
 | 
			
		||||
    char password[256];
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
    if (!bdrv_is_encrypted(bs))
 | 
			
		||||
        return 0;
 | 
			
		||||
 | 
			
		||||
    term_printf("%s (%s) is encrypted.\n", bdrv_get_device_name(bs),
 | 
			
		||||
                bdrv_get_encrypted_filename(bs));
 | 
			
		||||
    for(i = 0; i < 3; i++) {
 | 
			
		||||
        monitor_readline("Password: ", 1, password, sizeof(password));
 | 
			
		||||
        if (bdrv_set_key(bs, password) == 0)
 | 
			
		||||
            return 0;
 | 
			
		||||
        term_printf("invalid password\n");
 | 
			
		||||
    }
 | 
			
		||||
    return -EPERM;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										5
									
								
								net.c
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								net.c
									
									
									
									
									
								
							@@ -1818,11 +1818,6 @@ void net_host_device_remove(int vlan_id, const char *device)
 | 
			
		||||
    VLANState *vlan;
 | 
			
		||||
    VLANClientState *vc;
 | 
			
		||||
 | 
			
		||||
    if (!net_host_check_device(device)) {
 | 
			
		||||
        term_printf("invalid host network device %s\n", device);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    vlan = qemu_find_vlan(vlan_id);
 | 
			
		||||
    if (!vlan) {
 | 
			
		||||
        term_printf("can't find vlan %d\n", vlan_id);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										65
									
								
								qemu-char.c
									
									
									
									
									
								
							
							
						
						
									
										65
									
								
								qemu-char.c
									
									
									
									
									
								
							@@ -101,6 +101,10 @@
 | 
			
		||||
/***********************************************************/
 | 
			
		||||
/* character device */
 | 
			
		||||
 | 
			
		||||
static TAILQ_HEAD(CharDriverStateHead, CharDriverState) chardevs =
 | 
			
		||||
    TAILQ_HEAD_INITIALIZER(chardevs);
 | 
			
		||||
static int initial_reset_issued;
 | 
			
		||||
 | 
			
		||||
static void qemu_chr_event(CharDriverState *s, int event)
 | 
			
		||||
{
 | 
			
		||||
    if (!s->chr_event)
 | 
			
		||||
@@ -118,12 +122,23 @@ static void qemu_chr_reset_bh(void *opaque)
 | 
			
		||||
 | 
			
		||||
void qemu_chr_reset(CharDriverState *s)
 | 
			
		||||
{
 | 
			
		||||
    if (s->bh == NULL) {
 | 
			
		||||
    if (s->bh == NULL && initial_reset_issued) {
 | 
			
		||||
	s->bh = qemu_bh_new(qemu_chr_reset_bh, s);
 | 
			
		||||
	qemu_bh_schedule(s->bh);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void qemu_chr_initial_reset(void)
 | 
			
		||||
{
 | 
			
		||||
    CharDriverState *chr;
 | 
			
		||||
 | 
			
		||||
    initial_reset_issued = 1;
 | 
			
		||||
 | 
			
		||||
    TAILQ_FOREACH(chr, &chardevs, next) {
 | 
			
		||||
        qemu_chr_reset(chr);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int qemu_chr_write(CharDriverState *s, const uint8_t *buf, int len)
 | 
			
		||||
{
 | 
			
		||||
    return s->chr_write(s, buf, len);
 | 
			
		||||
@@ -210,12 +225,15 @@ typedef struct {
 | 
			
		||||
    IOEventHandler *chr_event[MAX_MUX];
 | 
			
		||||
    void *ext_opaque[MAX_MUX];
 | 
			
		||||
    CharDriverState *drv;
 | 
			
		||||
    unsigned char buffer[MUX_BUFFER_SIZE];
 | 
			
		||||
    int prod;
 | 
			
		||||
    int cons;
 | 
			
		||||
    int mux_cnt;
 | 
			
		||||
    int term_got_escape;
 | 
			
		||||
    int max_size;
 | 
			
		||||
    /* Intermediate input buffer allows to catch escape sequences even if the
 | 
			
		||||
       currently active device is not accepting any input - but only until it
 | 
			
		||||
       is full as well. */
 | 
			
		||||
    unsigned char buffer[MAX_MUX][MUX_BUFFER_SIZE];
 | 
			
		||||
    int prod[MAX_MUX];
 | 
			
		||||
    int cons[MAX_MUX];
 | 
			
		||||
} MuxDriver;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -345,11 +363,11 @@ static void mux_chr_accept_input(CharDriverState *chr)
 | 
			
		||||
    int m = chr->focus;
 | 
			
		||||
    MuxDriver *d = chr->opaque;
 | 
			
		||||
 | 
			
		||||
    while (d->prod != d->cons &&
 | 
			
		||||
    while (d->prod[m] != d->cons[m] &&
 | 
			
		||||
           d->chr_can_read[m] &&
 | 
			
		||||
           d->chr_can_read[m](d->ext_opaque[m])) {
 | 
			
		||||
        d->chr_read[m](d->ext_opaque[m],
 | 
			
		||||
                       &d->buffer[d->cons++ & MUX_BUFFER_MASK], 1);
 | 
			
		||||
                       &d->buffer[m][d->cons[m]++ & MUX_BUFFER_MASK], 1);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -357,11 +375,12 @@ static int mux_chr_can_read(void *opaque)
 | 
			
		||||
{
 | 
			
		||||
    CharDriverState *chr = opaque;
 | 
			
		||||
    MuxDriver *d = chr->opaque;
 | 
			
		||||
    int m = chr->focus;
 | 
			
		||||
 | 
			
		||||
    if ((d->prod - d->cons) < MUX_BUFFER_SIZE)
 | 
			
		||||
    if ((d->prod[m] - d->cons[m]) < MUX_BUFFER_SIZE)
 | 
			
		||||
        return 1;
 | 
			
		||||
    if (d->chr_can_read[chr->focus])
 | 
			
		||||
        return d->chr_can_read[chr->focus](d->ext_opaque[chr->focus]);
 | 
			
		||||
    if (d->chr_can_read[m])
 | 
			
		||||
        return d->chr_can_read[m](d->ext_opaque[m]);
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -376,12 +395,12 @@ static void mux_chr_read(void *opaque, const uint8_t *buf, int size)
 | 
			
		||||
 | 
			
		||||
    for(i = 0; i < size; i++)
 | 
			
		||||
        if (mux_proc_byte(chr, d, buf[i])) {
 | 
			
		||||
            if (d->prod == d->cons &&
 | 
			
		||||
            if (d->prod[m] == d->cons[m] &&
 | 
			
		||||
                d->chr_can_read[m] &&
 | 
			
		||||
                d->chr_can_read[m](d->ext_opaque[m]))
 | 
			
		||||
                d->chr_read[m](d->ext_opaque[m], &buf[i], 1);
 | 
			
		||||
            else
 | 
			
		||||
                d->buffer[d->prod++ & MUX_BUFFER_MASK] = buf[i];
 | 
			
		||||
                d->buffer[m][d->prod[m]++ & MUX_BUFFER_MASK] = buf[i];
 | 
			
		||||
        }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -898,6 +917,8 @@ static void pty_chr_close(struct CharDriverState *chr)
 | 
			
		||||
 | 
			
		||||
    qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
 | 
			
		||||
    close(s->fd);
 | 
			
		||||
    qemu_del_timer(s->timer);
 | 
			
		||||
    qemu_free_timer(s->timer);
 | 
			
		||||
    qemu_free(s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1727,6 +1748,16 @@ static void udp_chr_update_read_handler(CharDriverState *chr)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void udp_chr_close(CharDriverState *chr)
 | 
			
		||||
{
 | 
			
		||||
    NetCharDriver *s = chr->opaque;
 | 
			
		||||
    if (s->fd >= 0) {
 | 
			
		||||
        qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
 | 
			
		||||
        closesocket(s->fd);
 | 
			
		||||
    }
 | 
			
		||||
    qemu_free(s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static CharDriverState *qemu_chr_open_udp(const char *def)
 | 
			
		||||
{
 | 
			
		||||
    CharDriverState *chr = NULL;
 | 
			
		||||
@@ -1760,6 +1791,7 @@ static CharDriverState *qemu_chr_open_udp(const char *def)
 | 
			
		||||
    chr->opaque = s;
 | 
			
		||||
    chr->chr_write = udp_chr_write;
 | 
			
		||||
    chr->chr_update_read_handler = udp_chr_update_read_handler;
 | 
			
		||||
    chr->chr_close = udp_chr_close;
 | 
			
		||||
    return chr;
 | 
			
		||||
 | 
			
		||||
return_err:
 | 
			
		||||
@@ -1962,10 +1994,14 @@ static void tcp_chr_accept(void *opaque)
 | 
			
		||||
static void tcp_chr_close(CharDriverState *chr)
 | 
			
		||||
{
 | 
			
		||||
    TCPCharDriver *s = chr->opaque;
 | 
			
		||||
    if (s->fd >= 0)
 | 
			
		||||
    if (s->fd >= 0) {
 | 
			
		||||
        qemu_set_fd_handler(s->fd, NULL, NULL, NULL);
 | 
			
		||||
        closesocket(s->fd);
 | 
			
		||||
    if (s->listen_fd >= 0)
 | 
			
		||||
    }
 | 
			
		||||
    if (s->listen_fd >= 0) {
 | 
			
		||||
        qemu_set_fd_handler(s->listen_fd, NULL, NULL, NULL);
 | 
			
		||||
        closesocket(s->listen_fd);
 | 
			
		||||
    }
 | 
			
		||||
    qemu_free(s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -2076,9 +2112,6 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str,
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static TAILQ_HEAD(CharDriverStateHead, CharDriverState) chardevs
 | 
			
		||||
= TAILQ_HEAD_INITIALIZER(chardevs);
 | 
			
		||||
 | 
			
		||||
CharDriverState *qemu_chr_open(const char *label, const char *filename, void (*init)(struct CharDriverState *s))
 | 
			
		||||
{
 | 
			
		||||
    const char *p;
 | 
			
		||||
 
 | 
			
		||||
@@ -74,6 +74,7 @@ void qemu_chr_add_handlers(CharDriverState *s,
 | 
			
		||||
                           void *opaque);
 | 
			
		||||
int qemu_chr_ioctl(CharDriverState *s, int cmd, void *arg);
 | 
			
		||||
void qemu_chr_reset(CharDriverState *s);
 | 
			
		||||
void qemu_chr_initial_reset(void);
 | 
			
		||||
int qemu_chr_can_read(CharDriverState *s);
 | 
			
		||||
void qemu_chr_read(CharDriverState *s, uint8_t *buf, int len);
 | 
			
		||||
void qemu_chr_accept_input(CharDriverState *s);
 | 
			
		||||
 
 | 
			
		||||
@@ -74,8 +74,8 @@ static void help(void)
 | 
			
		||||
           "    differ\n"
 | 
			
		||||
           "  'fmt' is the disk image format. It is guessed automatically in most cases\n"
 | 
			
		||||
           "  'size' is the disk image size in kilobytes. Optional suffixes\n"
 | 
			
		||||
           "    'M' (megabyte, 1024 * 1024) and 'G' (gigabyte, 1024 * 1024 * 1024) are"
 | 
			
		||||
           "    supported any @code{k} or @code{K} is ignored\n"
 | 
			
		||||
           "    'M' (megabyte, 1024 * 1024) and 'G' (gigabyte, 1024 * 1024 * 1024) are\n"
 | 
			
		||||
           "    supported any 'k' or 'K' is ignored\n"
 | 
			
		||||
           "  'output_filename' is the destination disk image filename\n"
 | 
			
		||||
           "  'output_fmt' is the destination format\n"
 | 
			
		||||
           "  '-c' indicates that target image must be compressed (qcow format only)\n"
 | 
			
		||||
@@ -730,10 +730,6 @@ static int img_info(int argc, char **argv)
 | 
			
		||||
    if (bdrv_get_info(bs, &bdi) >= 0) {
 | 
			
		||||
        if (bdi.cluster_size != 0)
 | 
			
		||||
            printf("cluster_size: %d\n", bdi.cluster_size);
 | 
			
		||||
        if (bdi.highest_alloc)
 | 
			
		||||
            printf("highest_alloc: %" PRId64 "\n", bdi.highest_alloc);
 | 
			
		||||
        if (bdi.num_free_bytes)
 | 
			
		||||
            printf("num_free_bytes: %" PRId64 "\n", bdi.num_free_bytes);
 | 
			
		||||
    }
 | 
			
		||||
    bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename));
 | 
			
		||||
    if (backing_filename[0] != '\0') {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										21
									
								
								savevm.c
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								savevm.c
									
									
									
									
									
								
							@@ -118,7 +118,9 @@ void qemu_announce_self(void)
 | 
			
		||||
    VLANClientState *vc;
 | 
			
		||||
    uint8_t buf[256];
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < nb_nics; i++) {
 | 
			
		||||
    for (i = 0; i < MAX_NICS; i++) {
 | 
			
		||||
        if (!nd_table[i].used)
 | 
			
		||||
            continue;
 | 
			
		||||
        len = announce_self_create(buf, nd_table[i].macaddr);
 | 
			
		||||
        vlan = nd_table[i].vlan;
 | 
			
		||||
        for(vc = vlan->first_client; vc != NULL; vc = vc->next) {
 | 
			
		||||
@@ -304,18 +306,18 @@ typedef struct QEMUFileBdrv
 | 
			
		||||
    int64_t base_offset;
 | 
			
		||||
} QEMUFileBdrv;
 | 
			
		||||
 | 
			
		||||
static int bdrv_put_buffer(void *opaque, const uint8_t *buf,
 | 
			
		||||
static int block_put_buffer(void *opaque, const uint8_t *buf,
 | 
			
		||||
                           int64_t pos, int size)
 | 
			
		||||
{
 | 
			
		||||
    QEMUFileBdrv *s = opaque;
 | 
			
		||||
    bdrv_pwrite(s->bs, s->base_offset + pos, buf, size);
 | 
			
		||||
    bdrv_put_buffer(s->bs, buf, s->base_offset + pos, size);
 | 
			
		||||
    return size;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int bdrv_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
 | 
			
		||||
static int block_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
 | 
			
		||||
{
 | 
			
		||||
    QEMUFileBdrv *s = opaque;
 | 
			
		||||
    return bdrv_pread(s->bs, s->base_offset + pos, buf, size);
 | 
			
		||||
    return bdrv_get_buffer(s->bs, buf, s->base_offset + pos, size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int bdrv_fclose(void *opaque)
 | 
			
		||||
@@ -335,9 +337,9 @@ static QEMUFile *qemu_fopen_bdrv(BlockDriverState *bs, int64_t offset, int is_wr
 | 
			
		||||
    s->base_offset = offset;
 | 
			
		||||
 | 
			
		||||
    if (is_writable)
 | 
			
		||||
        return qemu_fopen_ops(s, bdrv_put_buffer, NULL, bdrv_fclose, NULL);
 | 
			
		||||
        return qemu_fopen_ops(s, block_put_buffer, NULL, bdrv_fclose, NULL);
 | 
			
		||||
 | 
			
		||||
    return qemu_fopen_ops(s, NULL, bdrv_get_buffer, bdrv_fclose, NULL);
 | 
			
		||||
    return qemu_fopen_ops(s, NULL, block_get_buffer, bdrv_fclose, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QEMUFile *qemu_fopen_ops(void *opaque, QEMUFilePutBufferFunc *put_buffer,
 | 
			
		||||
@@ -364,6 +366,11 @@ int qemu_file_has_error(QEMUFile *f)
 | 
			
		||||
    return f->has_error;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void qemu_file_set_error(QEMUFile *f)
 | 
			
		||||
{
 | 
			
		||||
    f->has_error = 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void qemu_fflush(QEMUFile *f)
 | 
			
		||||
{
 | 
			
		||||
    if (!f->put_buffer)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								sdl.c
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								sdl.c
									
									
									
									
									
								
							@@ -27,7 +27,7 @@
 | 
			
		||||
#include "x_keymap.h"
 | 
			
		||||
 | 
			
		||||
#include <SDL.h>
 | 
			
		||||
#include <SDL/SDL_syswm.h>
 | 
			
		||||
#include <SDL_syswm.h>
 | 
			
		||||
 | 
			
		||||
#ifndef _WIN32
 | 
			
		||||
#include <signal.h>
 | 
			
		||||
 
 | 
			
		||||
@@ -1421,10 +1421,10 @@ static void host_cpuid(uint32_t function, uint32_t count,
 | 
			
		||||
#else
 | 
			
		||||
    asm volatile("pusha \n\t"
 | 
			
		||||
                 "cpuid \n\t"
 | 
			
		||||
                 "mov %%eax, 0(%1) \n\t"
 | 
			
		||||
                 "mov %%ebx, 4(%1) \n\t"
 | 
			
		||||
                 "mov %%ecx, 8(%1) \n\t"
 | 
			
		||||
                 "mov %%edx, 12(%1) \n\t"
 | 
			
		||||
                 "mov %%eax, 0(%2) \n\t"
 | 
			
		||||
                 "mov %%ebx, 4(%2) \n\t"
 | 
			
		||||
                 "mov %%ecx, 8(%2) \n\t"
 | 
			
		||||
                 "mov %%edx, 12(%2) \n\t"
 | 
			
		||||
                 "popa"
 | 
			
		||||
                 : : "a"(function), "c"(count), "S"(vec)
 | 
			
		||||
                 : "memory", "cc");
 | 
			
		||||
 
 | 
			
		||||
@@ -3241,6 +3241,8 @@ target_ulong helper_lsl(target_ulong selector1)
 | 
			
		||||
 | 
			
		||||
    selector = selector1 & 0xffff;
 | 
			
		||||
    eflags = helper_cc_compute_all(CC_OP);
 | 
			
		||||
    if ((selector & 0xfffc) == 0)
 | 
			
		||||
        goto fail;
 | 
			
		||||
    if (load_segment(&e1, &e2, selector) != 0)
 | 
			
		||||
        goto fail;
 | 
			
		||||
    rpl = selector & 3;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										78
									
								
								vl.c
									
									
									
									
									
								
							
							
						
						
									
										78
									
								
								vl.c
									
									
									
									
									
								
							@@ -201,6 +201,7 @@ ram_addr_t ram_size;
 | 
			
		||||
int nb_nics;
 | 
			
		||||
NICInfo nd_table[MAX_NICS];
 | 
			
		||||
int vm_running;
 | 
			
		||||
static int autostart;
 | 
			
		||||
static int rtc_utc = 1;
 | 
			
		||||
static int rtc_date_offset = -1; /* -1 means no change */
 | 
			
		||||
int cirrus_vga_enabled = 1;
 | 
			
		||||
@@ -2607,11 +2608,13 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque)
 | 
			
		||||
        bdrv_flags |= BDRV_O_CACHE_WB;
 | 
			
		||||
    else if (cache == 3) /* not specified */
 | 
			
		||||
        bdrv_flags |= BDRV_O_CACHE_DEF;
 | 
			
		||||
    if (bdrv_open2(bdrv, file, bdrv_flags, drv) < 0 || qemu_key_check(bdrv, file)) {
 | 
			
		||||
    if (bdrv_open2(bdrv, file, bdrv_flags, drv) < 0) {
 | 
			
		||||
        fprintf(stderr, "qemu: could not open disk image %s\n",
 | 
			
		||||
                        file);
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
    if (bdrv_key_required(bdrv))
 | 
			
		||||
        autostart = 0;
 | 
			
		||||
    return drives_table_idx;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -2658,7 +2661,7 @@ int usb_device_add_dev(USBDevice *dev)
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int usb_device_add(const char *devname)
 | 
			
		||||
static int usb_device_add(const char *devname, int is_hotplug)
 | 
			
		||||
{
 | 
			
		||||
    const char *p;
 | 
			
		||||
    USBDevice *dev;
 | 
			
		||||
@@ -2675,7 +2678,18 @@ static int usb_device_add(const char *devname)
 | 
			
		||||
    } else if (!strcmp(devname, "keyboard")) {
 | 
			
		||||
        dev = usb_keyboard_init();
 | 
			
		||||
    } else if (strstart(devname, "disk:", &p)) {
 | 
			
		||||
        dev = usb_msd_init(p);
 | 
			
		||||
        BlockDriverState *bs;
 | 
			
		||||
 | 
			
		||||
        dev = usb_msd_init(p, &bs);
 | 
			
		||||
        if (!dev)
 | 
			
		||||
            return -1;
 | 
			
		||||
        if (bdrv_key_required(bs)) {
 | 
			
		||||
            autostart = 0;
 | 
			
		||||
            if (is_hotplug && monitor_read_bdrv_key(bs) < 0) {
 | 
			
		||||
                dev->handle_destroy(dev);
 | 
			
		||||
                return -1;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    } else if (!strcmp(devname, "wacom-tablet")) {
 | 
			
		||||
        dev = usb_wacom_init();
 | 
			
		||||
    } else if (strstart(devname, "serial:", &p)) {
 | 
			
		||||
@@ -2756,7 +2770,7 @@ static int usb_device_del(const char *devname)
 | 
			
		||||
 | 
			
		||||
void do_usb_add(const char *devname)
 | 
			
		||||
{
 | 
			
		||||
    usb_device_add(devname);
 | 
			
		||||
    usb_device_add(devname, 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void do_usb_del(const char *devname)
 | 
			
		||||
@@ -3206,10 +3220,10 @@ static int ram_save_live(QEMUFile *f, int stage, void *opaque)
 | 
			
		||||
    /* try transferring iterative blocks of memory */
 | 
			
		||||
 | 
			
		||||
    if (stage == 3) {
 | 
			
		||||
        cpu_physical_memory_set_dirty_tracking(0);
 | 
			
		||||
 | 
			
		||||
        /* flush all remaining blocks regardless of rate limiting */
 | 
			
		||||
        while (ram_save_block(f) != 0);
 | 
			
		||||
        cpu_physical_memory_set_dirty_tracking(0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
 | 
			
		||||
@@ -4230,9 +4244,7 @@ static const QEMUOption qemu_options[] = {
 | 
			
		||||
    { "boot", HAS_ARG, QEMU_OPTION_boot },
 | 
			
		||||
    { "snapshot", 0, QEMU_OPTION_snapshot },
 | 
			
		||||
    { "m", HAS_ARG, QEMU_OPTION_m },
 | 
			
		||||
#ifndef _WIN32
 | 
			
		||||
    { "k", HAS_ARG, QEMU_OPTION_k },
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef HAS_AUDIO
 | 
			
		||||
    { "audio-help", 0, QEMU_OPTION_audio_help },
 | 
			
		||||
    { "soundhw", HAS_ARG, QEMU_OPTION_soundhw },
 | 
			
		||||
@@ -4334,45 +4346,6 @@ static const QEMUOption qemu_options[] = {
 | 
			
		||||
    { NULL },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* password input */
 | 
			
		||||
 | 
			
		||||
int qemu_key_check(BlockDriverState *bs, const char *name)
 | 
			
		||||
{
 | 
			
		||||
    char password[256];
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
    if (!bdrv_is_encrypted(bs))
 | 
			
		||||
        return 0;
 | 
			
		||||
 | 
			
		||||
    term_printf("%s is encrypted.\n", name);
 | 
			
		||||
    for(i = 0; i < 3; i++) {
 | 
			
		||||
        monitor_readline("Password: ", 1, password, sizeof(password));
 | 
			
		||||
        if (bdrv_set_key(bs, password) == 0)
 | 
			
		||||
            return 0;
 | 
			
		||||
        term_printf("invalid password\n");
 | 
			
		||||
    }
 | 
			
		||||
    return -EPERM;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static BlockDriverState *get_bdrv(int index)
 | 
			
		||||
{
 | 
			
		||||
    if (index > nb_drives)
 | 
			
		||||
        return NULL;
 | 
			
		||||
    return drives_table[index].bdrv;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void read_passwords(void)
 | 
			
		||||
{
 | 
			
		||||
    BlockDriverState *bs;
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
    for(i = 0; i < 6; i++) {
 | 
			
		||||
        bs = get_bdrv(i);
 | 
			
		||||
        if (bs)
 | 
			
		||||
            qemu_key_check(bs, bdrv_get_device_name(bs));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef HAS_AUDIO
 | 
			
		||||
struct soundhw soundhw[] = {
 | 
			
		||||
#ifdef HAS_AUDIO_CHOICE
 | 
			
		||||
@@ -4639,7 +4612,6 @@ int main(int argc, char **argv, char **envp)
 | 
			
		||||
    int fds[2];
 | 
			
		||||
    int tb_size;
 | 
			
		||||
    const char *pid_file = NULL;
 | 
			
		||||
    int autostart;
 | 
			
		||||
    const char *incoming = NULL;
 | 
			
		||||
    int fd = 0;
 | 
			
		||||
    struct passwd *pwd = NULL;
 | 
			
		||||
@@ -4696,7 +4668,7 @@ int main(int argc, char **argv, char **envp)
 | 
			
		||||
    kernel_cmdline = "";
 | 
			
		||||
    cyls = heads = secs = 0;
 | 
			
		||||
    translation = BIOS_ATA_TRANSLATION_AUTO;
 | 
			
		||||
    monitor_device = "vc";
 | 
			
		||||
    monitor_device = "vc:80Cx24C";
 | 
			
		||||
 | 
			
		||||
    serial_devices[0] = "vc:80Cx24C";
 | 
			
		||||
    for(i = 1; i < MAX_SERIAL_PORTS; i++)
 | 
			
		||||
@@ -5637,7 +5609,7 @@ int main(int argc, char **argv, char **envp)
 | 
			
		||||
    /* init USB devices */
 | 
			
		||||
    if (usb_enabled) {
 | 
			
		||||
        for(i = 0; i < usb_devices_index; i++) {
 | 
			
		||||
            if (usb_device_add(usb_devices[i]) < 0) {
 | 
			
		||||
            if (usb_device_add(usb_devices[i], 0) < 0) {
 | 
			
		||||
                fprintf(stderr, "Warning: could not add USB device %s\n",
 | 
			
		||||
                        usb_devices[i]);
 | 
			
		||||
            }
 | 
			
		||||
@@ -5693,6 +5665,7 @@ int main(int argc, char **argv, char **envp)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    text_consoles_set_display(display_state);
 | 
			
		||||
    qemu_chr_initial_reset();
 | 
			
		||||
 | 
			
		||||
    if (monitor_device && monitor_hd)
 | 
			
		||||
        monitor_init(monitor_hd, !nographic);
 | 
			
		||||
@@ -5747,13 +5720,8 @@ int main(int argc, char **argv, char **envp)
 | 
			
		||||
        qemu_start_incoming_migration(incoming);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        /* XXX: simplify init */
 | 
			
		||||
        read_passwords();
 | 
			
		||||
        if (autostart) {
 | 
			
		||||
    if (autostart)
 | 
			
		||||
        vm_start();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (daemonize) {
 | 
			
		||||
	uint8_t status = 0;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user