Re: [Qemu-devel] [PATCH] e1000: Handle IO Port.
On 06/27/2011 08:07 PM, Peter Maydell wrote: > +int ioport_base; > +uint32_t ioport_reg[2]; I think ioport_reg[] needs to go in the VMStateDescription as well. I don't know enough about the PCI subsystem to know whether that's also true of ioport_base or whether the the map function is called again on a vmload. ioport_reg[1] is never written nor read, so this can be changed to a single uint32_t ioport_addr. Since it will be almost always 0 (either because it was never written, or because E1000_CTRL == 0), a subsection is useful to have. Paolo
[Qemu-devel] buildbot failure in qemu on ppc-next_i386_debian_5_0
The Buildbot has detected a new failure on builder ppc-next_i386_debian_5_0 while building qemu. Full details are available at: http://buildbot.b1-systems.de/qemu/builders/ppc-next_i386_debian_5_0/builds/17 Buildbot URL: http://buildbot.b1-systems.de/qemu/ Buildslave for this Build: yuzuki Build Reason: The Nightly scheduler named 'nightly_ppc-next' triggered this build Build Source Stamp: [branch ppc-next] HEAD Blamelist: BUILD FAILED: failed git sincerely, -The Buildbot
[Qemu-devel] [PATCH v5 12/12] BlockDriver: add bdrv_get_allocated_file_size() operation
qemu-img.c wants to count allocated file size of image. Previously it counts a single bs->file by 'stat' or Window API. As VMDK introduces multiple file support, the operation becomes format specific with platform specific meanwhile. The functions are moved to block/raw-{posix,win32}.c and qemu-img.c calls bdrv_get_allocated_file_size to count the bs. And also added VMDK code to count his own extents. Signed-off-by: Fam Zheng --- block.c | 19 +++ block.h |1 + block/raw-posix.c | 21 + block/raw-win32.c | 29 + block/vmdk.c | 21 + block_int.h |1 + qemu-img.c| 31 +-- 7 files changed, 93 insertions(+), 30 deletions(-) diff --git a/block.c b/block.c index 24a25d5..9549b9e 100644 --- a/block.c +++ b/block.c @@ -1147,6 +1147,25 @@ int bdrv_truncate(BlockDriverState *bs, int64_t offset) } /** + * Length of a allocated file in bytes. Sparse files are counted by actual + * allocated space. Return < 0 if error or unknown. + */ +int64_t bdrv_get_allocated_file_size(BlockDriverState *bs) +{ +BlockDriver *drv = bs->drv; +if (!drv) { +return -ENOMEDIUM; +} +if (drv->bdrv_get_allocated_file_size) { +return drv->bdrv_get_allocated_file_size(bs); +} +if (bs->file) { +return bdrv_get_allocated_file_size(bs->file); +} +return -ENOTSUP; +} + +/** * Length of a file in bytes. Return < 0 if error or unknown. */ int64_t bdrv_getlength(BlockDriverState *bs) diff --git a/block.h b/block.h index 859d1d9..59cc410 100644 --- a/block.h +++ b/block.h @@ -89,6 +89,7 @@ int bdrv_write_sync(BlockDriverState *bs, int64_t sector_num, const uint8_t *buf, int nb_sectors); int bdrv_truncate(BlockDriverState *bs, int64_t offset); int64_t bdrv_getlength(BlockDriverState *bs); +int64_t bdrv_get_allocated_file_size(BlockDriverState *bs); void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr); void bdrv_guess_geometry(BlockDriverState *bs, int *pcyls, int *pheads, int *psecs); int bdrv_commit(BlockDriverState *bs); diff --git a/block/raw-posix.c b/block/raw-posix.c index 4cd7d7a..911cc0d 100644 --- a/block/raw-posix.c +++ b/block/raw-posix.c @@ -791,6 +791,17 @@ static int64_t raw_getlength(BlockDriverState *bs) } #endif +static int64_t raw_get_allocated_file_size(BlockDriverState *bs) +{ +struct stat st; +BDRVRawState *s = bs->opaque; + +if (fstat(s->fd, &st) < 0) { +return -errno; +} +return (int64_t)st.st_blocks * 512; +} + static int raw_create(const char *filename, QEMUOptionParameter *options) { int fd; @@ -886,6 +897,8 @@ static BlockDriver bdrv_file = { .bdrv_truncate = raw_truncate, .bdrv_getlength = raw_getlength, +.bdrv_get_allocated_file_size += raw_get_allocated_file_size, .create_options = raw_create_options, }; @@ -1154,6 +1167,8 @@ static BlockDriver bdrv_host_device = { .bdrv_read = raw_read, .bdrv_write = raw_write, .bdrv_getlength= raw_getlength, +.bdrv_get_allocated_file_size += raw_get_allocated_file_size, /* generic scsi device */ #ifdef __linux__ @@ -1269,6 +1284,8 @@ static BlockDriver bdrv_host_floppy = { .bdrv_read = raw_read, .bdrv_write = raw_write, .bdrv_getlength= raw_getlength, +.bdrv_get_allocated_file_size += raw_get_allocated_file_size, /* removable device support */ .bdrv_is_inserted = floppy_is_inserted, @@ -1366,6 +1383,8 @@ static BlockDriver bdrv_host_cdrom = { .bdrv_read = raw_read, .bdrv_write = raw_write, .bdrv_getlength = raw_getlength, +.bdrv_get_allocated_file_size += raw_get_allocated_file_size, /* removable device support */ .bdrv_is_inserted = cdrom_is_inserted, @@ -1489,6 +1508,8 @@ static BlockDriver bdrv_host_cdrom = { .bdrv_read = raw_read, .bdrv_write = raw_write, .bdrv_getlength = raw_getlength, +.bdrv_get_allocated_file_size += raw_get_allocated_file_size, /* removable device support */ .bdrv_is_inserted = cdrom_is_inserted, diff --git a/block/raw-win32.c b/block/raw-win32.c index 56bd719..91067e7 100644 --- a/block/raw-win32.c +++ b/block/raw-win32.c @@ -213,6 +213,31 @@ static int64_t raw_getlength(BlockDriverState *bs) return l.QuadPart; } +static int64_t raw_get_allocated_file_size(BlockDriverState *bs) +{ +typedef DWORD (WINAPI * get_compressed_t)(const char *filename, + DWORD * high); +get_compressed_t get_compressed; +struct _stati64 st; +const char *filename = bs->filename; +/* WinNT support GetCompressedFileSize to determine allocate size */ +get_compressed =
[Qemu-devel] Query on the License of qemu
Dear All, This is Jaemin Park, who delves into qemu. I have 2 questions about the license of qemu. 1. Does it has any GPL issues to deploy a virtual machine, which runs a proprietary operating system, on qemu? Qemu has GPL. A guest which runs on Qemu, has non-GPL. Is it OK to release them together? We are going, of course, to open all of source codes related to qemu, except the guest operating system. 2. Does it has any GPL issues to add virtual devices to qemu and add device drivers to the guest proprietary operating system? We are going to add some peripheral devices to the qemu board. To work with those devices, we are going to add device drivers to the proprietary operating system. There are no linkage on source level between qemu and the guest operating system. They communicates by handling interrupts and memory map. We, however, are concerned about the interpretation of the GPL. If we are obliged to open some of guest source codes, how can we interprete the open range of the GPL? Sincerely yours, Jaemin Park. -- Jaemin Park "God is Love"
[Qemu-devel] [PATCH v5 10/12] VMDK: create different subformats
Add create option 'format', with enums: monolithicSparse monolithicFlat twoGbMaxExtentSparse twoGbMaxExtentFlat Each creates a subformat image file. The default is monolithiSparse. Signed-off-by: Fam Zheng --- block/vmdk.c | 563 ++ block_int.h |1 + 2 files changed, 333 insertions(+), 231 deletions(-) diff --git a/block/vmdk.c b/block/vmdk.c index 8083c31..c8f3536 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -154,8 +154,8 @@ static int vmdk_probe(const uint8_t *buf, int buf_size, const char *filename) #define CHECK_CID 1 #define SECTOR_SIZE 512 -#define DESC_SIZE 20*SECTOR_SIZE // 20 sectors of 512 bytes each -#define HEADER_SIZE 512// first sector of 512 bytes +#define DESC_SIZE (20 * SECTOR_SIZE)/* 20 sectors of 512 bytes each */ +#define HEADER_SIZE 512 /* first sector of 512 bytes */ static uint32_t vmdk_read_cid(BlockDriverState *bs, int parent) { @@ -227,167 +227,6 @@ static int vmdk_is_cid_valid(BlockDriverState *bs) return 1; } -static int vmdk_snapshot_create(const char *filename, const char *backing_file) -{ -int snp_fd, p_fd; -int ret; -uint32_t p_cid; -char *p_name, *gd_buf, *rgd_buf; -const char *real_filename, *temp_str; -VMDK4Header header; -uint32_t gde_entries, gd_size; -int64_t gd_offset, rgd_offset, capacity, gt_size; -char p_desc[DESC_SIZE], s_desc[DESC_SIZE], hdr[HEADER_SIZE]; -static const char desc_template[] = -"# Disk DescriptorFile\n" -"version=1\n" -"CID=%x\n" -"parentCID=%x\n" -"createType=\"monolithicSparse\"\n" -"parentFileNameHint=\"%s\"\n" -"\n" -"# Extent description\n" -"RW %u SPARSE \"%s\"\n" -"\n" -"# The Disk Data Base \n" -"#DDB\n" -"\n"; - -snp_fd = open(filename, O_RDWR | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE, 0644); -if (snp_fd < 0) -return -errno; -p_fd = open(backing_file, O_RDONLY | O_BINARY | O_LARGEFILE); -if (p_fd < 0) { -close(snp_fd); -return -errno; -} - -/* read the header */ -if (lseek(p_fd, 0x0, SEEK_SET) == -1) { -ret = -errno; -goto fail; -} -if (read(p_fd, hdr, HEADER_SIZE) != HEADER_SIZE) { -ret = -errno; -goto fail; -} - -/* write the header */ -if (lseek(snp_fd, 0x0, SEEK_SET) == -1) { -ret = -errno; -goto fail; -} -if (write(snp_fd, hdr, HEADER_SIZE) == -1) { -ret = -errno; -goto fail; -} - -memset(&header, 0, sizeof(header)); -memcpy(&header,&hdr[4], sizeof(header)); // skip the VMDK4_MAGIC - -if (ftruncate(snp_fd, header.grain_offset << 9)) { -ret = -errno; -goto fail; -} -if (lseek(p_fd, 0x200, SEEK_SET) == -1) { -ret = -errno; -goto fail; -} -if (read(p_fd, p_desc, DESC_SIZE) != DESC_SIZE) { -ret = -errno; -goto fail; -} - -if ((p_name = strstr(p_desc,"CID")) != NULL) { -p_name += sizeof("CID"); -sscanf(p_name,"%x",&p_cid); -} - -real_filename = filename; -if ((temp_str = strrchr(real_filename, '\\')) != NULL) -real_filename = temp_str + 1; -if ((temp_str = strrchr(real_filename, '/')) != NULL) -real_filename = temp_str + 1; -if ((temp_str = strrchr(real_filename, ':')) != NULL) -real_filename = temp_str + 1; - -snprintf(s_desc, sizeof(s_desc), desc_template, p_cid, p_cid, backing_file, - (uint32_t)header.capacity, real_filename); - -/* write the descriptor */ -if (lseek(snp_fd, 0x200, SEEK_SET) == -1) { -ret = -errno; -goto fail; -} -if (write(snp_fd, s_desc, strlen(s_desc)) == -1) { -ret = -errno; -goto fail; -} - -gd_offset = header.gd_offset * SECTOR_SIZE; // offset of GD table -rgd_offset = header.rgd_offset * SECTOR_SIZE; // offset of RGD table -capacity = header.capacity * SECTOR_SIZE; // Extent size -/* - * Each GDE span 32M disk, means: - * 512 GTE per GT, each GTE points to grain - */ -gt_size = (int64_t)header.num_gtes_per_gte * header.granularity * SECTOR_SIZE; -if (!gt_size) { -ret = -EINVAL; -goto fail; -} -gde_entries = (uint32_t)(capacity / gt_size); // number of gde/rgde -gd_size = gde_entries * sizeof(uint32_t); - -/* write RGD */ -rgd_buf = qemu_malloc(gd_size); -if (lseek(p_fd, rgd_offset, SEEK_SET) == -1) { -ret = -errno; -goto fail_rgd; -} -if (read(p_fd, rgd_buf, gd_size) != gd_size) { -ret = -errno; -goto fail_rgd; -} -if (lseek(snp_fd, rgd_offset, SEEK_SET) == -1) { -ret = -errno; -goto fail_rgd; -} -if (write(snp_fd, rgd_buf, gd_size) == -1) { -ret = -errno; -goto fail_rgd; -} - -/* write GD */ -gd_buf = qemu_malloc(gd_size); -i
[Qemu-devel] [PATCH v5 07/12] VMDK: move 'static' cid_update flag to bs field
Cid_update is the flag for updating CID on first write after opening the image. This should be per image open rather than per program life cycle, so change it from static var of vmdk_write to a field in BDRVVmdkState. Signed-off-by: Fam Zheng --- block/vmdk.c |6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/block/vmdk.c b/block/vmdk.c index cf7370f..10a8a9a 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -82,6 +82,7 @@ typedef struct VmdkExtent { typedef struct BDRVVmdkState { int desc_offset; +bool cid_updated; int num_extents; uint32_t parent_cid; VmdkExtent *extents; @@ -857,7 +858,6 @@ static int vmdk_write(BlockDriverState *bs, int64_t sector_num, int n; int64_t index_in_cluster; uint64_t cluster_offset; -static int cid_update = 0; VmdkMetaData m_data; if (sector_num > bs->total_sectors) { @@ -904,9 +904,9 @@ static int vmdk_write(BlockDriverState *bs, int64_t sector_num, buf += n * 512; // update CID on the first write every time the virtual disk is opened -if (!cid_update) { +if (!s->cid_updated) { vmdk_write_cid(bs, time(NULL)); -cid_update++; +s->cid_updated = true; } } return 0;
[Qemu-devel] [PATCH v5 11/12] VMDK: fix coding style
Conform coding style in vmdk.c to pass scripts/checkpatch.pl checks. Signed-off-by: Fam Zheng --- block/vmdk.c | 79 +++-- 1 files changed, 48 insertions(+), 31 deletions(-) diff --git a/block/vmdk.c b/block/vmdk.c index c8f3536..f472e39 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -101,8 +101,9 @@ static int vmdk_probe(const uint8_t *buf, int buf_size, const char *filename) { uint32_t magic; -if (buf_size < 4) +if (buf_size < 4) { return 0; +} magic = be32_to_cpu(*(uint32_t *)buf); if (magic == VMDK3_MAGIC || magic == VMDK4_MAGIC) { @@ -177,9 +178,10 @@ static uint32_t vmdk_read_cid(BlockDriverState *bs, int parent) cid_str_size = sizeof("CID"); } -if ((p_name = strstr(desc,cid_str)) != NULL) { +p_name = strstr(desc, cid_str); +if (p_name != NULL) { p_name += cid_str_size; -sscanf(p_name,"%x",&cid); +sscanf(p_name, "%x", &cid); } return cid; @@ -195,9 +197,10 @@ static int vmdk_write_cid(BlockDriverState *bs, uint32_t cid) return -EIO; } -tmp_str = strstr(desc,"parentCID"); +tmp_str = strstr(desc, "parentCID"); pstrcpy(tmp_desc, sizeof(tmp_desc), tmp_str); -if ((p_name = strstr(desc,"CID")) != NULL) { +p_name = strstr(desc, "CID"); +if (p_name != NULL) { p_name += sizeof("CID"); snprintf(p_name, sizeof(desc) - (p_name - desc), "%x\n", cid); pstrcat(desc, sizeof(desc), tmp_desc); @@ -217,13 +220,14 @@ static int vmdk_is_cid_valid(BlockDriverState *bs) uint32_t cur_pcid; if (p_bs) { -cur_pcid = vmdk_read_cid(p_bs,0); -if (s->parent_cid != cur_pcid) -// CID not valid +cur_pcid = vmdk_read_cid(p_bs, 0); +if (s->parent_cid != cur_pcid) { +/* CID not valid */ return 0; +} } #endif -// CID valid +/* CID valid */ return 1; } @@ -238,14 +242,18 @@ static int vmdk_parent_open(BlockDriverState *bs) return -1; } -if ((p_name = strstr(desc,"parentFileNameHint")) != NULL) { +p_name = strstr(desc, "parentFileNameHint"); +if (p_name != NULL) { char *end_name; p_name += sizeof("parentFileNameHint") + 1; -if ((end_name = strchr(p_name,'\"')) == NULL) +end_name = strchr(p_name, '\"'); +if (end_name == NULL) { return -1; -if ((end_name - p_name) > sizeof (bs->backing_file) - 1) +} +if ((end_name - p_name) > sizeof(bs->backing_file) - 1) { return -1; +} pstrcpy(bs->backing_file, end_name - p_name + 1, p_name); } @@ -612,8 +620,9 @@ static int get_whole_cluster(BlockDriverState *bs, if (bs->backing_hd) { int ret; -if (!vmdk_is_cid_valid(bs)) +if (!vmdk_is_cid_valid(bs)) { return -1; +} /* floor offset to cluster */ offset -= offset % (extent->cluster_sectors * 512); @@ -672,8 +681,9 @@ static int get_cluster_offset(BlockDriverState *bs, int min_index, i, j; uint32_t min_count, *l2_table, tmp = 0; -if (m_data) +if (m_data) { m_data->valid = 0; +} if (extent->flat) { *cluster_offset = extent->flat_start_offset; return 0; @@ -729,7 +739,7 @@ static int get_cluster_offset(BlockDriverState *bs, return -1; } -// Avoid the L2 tables update for the images that have snapshots. +/* Avoid the L2 tables update for the images that have snapshots. */ *cluster_offset = bdrv_getlength(extent->file); bdrv_truncate( extent->file, @@ -746,8 +756,9 @@ static int get_cluster_offset(BlockDriverState *bs, * or inappropriate VM shutdown. */ if (get_whole_cluster( -bs, extent, *cluster_offset, offset, allocate) == -1) +bs, extent, *cluster_offset, offset, allocate) == -1) { return -1; +} if (m_data) { m_data->offset = tmp; @@ -797,8 +808,9 @@ static int vmdk_is_allocated(BlockDriverState *bs, int64_t sector_num, index_in_cluster = sector_num % extent->cluster_sectors; n = extent->cluster_sectors - index_in_cluster; -if (n > nb_sectors) +if (n > nb_sectors) { n = nb_sectors; +} *pnum = n; return ret; } @@ -822,16 +834,19 @@ static int vmdk_read(BlockDriverState *bs, int64_t sector_num, sector_num << 9, 0, &cluster_offset); index_in_cluster = sector_num % extent->cluster_sectors; n = extent->cluster_sectors - index_in_cluster; -if (n > nb_sectors) +if (n > nb_sectors) { n = nb_sectors; +} if (ret) { /* if not allocated, try to read from parent image, if exist */ if (bs->backing_hd) { -
[Qemu-devel] [PATCH v5 08/12] VMDK: change get_cluster_offset return type
The return type of get_cluster_offset was an offset that use 0 to denote 'not allocated', this will be no longer true for flat extents, as we see flat extent file as a single huge cluster whose offset is 0 and length is the whole file length. So now we use int return value, 0 means success and otherwise offset invalid. Signed-off-by: Fam Zheng --- block/vmdk.c | 73 +++--- 1 files changed, 39 insertions(+), 34 deletions(-) diff --git a/block/vmdk.c b/block/vmdk.c index 10a8a9a..c84ea90 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -669,18 +669,23 @@ static int vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data) return 0; } -static uint64_t get_cluster_offset(BlockDriverState *bs, +static int get_cluster_offset(BlockDriverState *bs, VmdkExtent *extent, VmdkMetaData *m_data, -uint64_t offset, int allocate) +uint64_t offset, +int allocate, +uint64_t *cluster_offset) { unsigned int l1_index, l2_offset, l2_index; int min_index, i, j; uint32_t min_count, *l2_table, tmp = 0; -uint64_t cluster_offset; if (m_data) m_data->valid = 0; +if (extent->flat) { +*cluster_offset = 0; +return 0; +} l1_index = (offset >> 9) / extent->l1_entry_sectors; if (l1_index >= extent->l1_size) { @@ -725,21 +730,22 @@ static uint64_t get_cluster_offset(BlockDriverState *bs, extent->l2_cache_counts[min_index] = 1; found: l2_index = ((offset >> 9) / extent->cluster_sectors) % extent->l2_size; -cluster_offset = le32_to_cpu(l2_table[l2_index]); +*cluster_offset = le32_to_cpu(l2_table[l2_index]); -if (!cluster_offset) { -if (!allocate) -return 0; +if (!*cluster_offset) { +if (!allocate) { +return -1; +} // Avoid the L2 tables update for the images that have snapshots. -cluster_offset = bdrv_getlength(extent->file); +*cluster_offset = bdrv_getlength(extent->file); bdrv_truncate( extent->file, -cluster_offset + (extent->cluster_sectors << 9) +*cluster_offset + (extent->cluster_sectors << 9) ); -cluster_offset >>= 9; -tmp = cpu_to_le32(cluster_offset); +*cluster_offset >>= 9; +tmp = cpu_to_le32(*cluster_offset); l2_table[l2_index] = tmp; /* First of all we write grain itself, to avoid race condition @@ -748,8 +754,8 @@ static uint64_t get_cluster_offset(BlockDriverState *bs, * or inappropriate VM shutdown. */ if (get_whole_cluster( -bs, extent, cluster_offset, offset, allocate) == -1) -return 0; +bs, extent, *cluster_offset, offset, allocate) == -1) +return -1; if (m_data) { m_data->offset = tmp; @@ -759,8 +765,8 @@ static uint64_t get_cluster_offset(BlockDriverState *bs, m_data->valid = 1; } } -cluster_offset <<= 9; -return cluster_offset; +*cluster_offset <<= 9; +return 0; } static VmdkExtent *find_extent(BDRVVmdkState *s, @@ -784,7 +790,6 @@ static int vmdk_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors, int *pnum) { BDRVVmdkState *s = bs->opaque; - int64_t index_in_cluster, n, ret; uint64_t offset; VmdkExtent *extent; @@ -793,15 +798,13 @@ static int vmdk_is_allocated(BlockDriverState *bs, int64_t sector_num, if (!extent) { return 0; } -if (extent->flat) { -n = extent->end_sector - sector_num; -ret = 1; -} else { -offset = get_cluster_offset(bs, extent, NULL, sector_num * 512, 0); -index_in_cluster = sector_num % extent->cluster_sectors; -n = extent->cluster_sectors - index_in_cluster; -ret = offset ? 1 : 0; -} +ret = get_cluster_offset(bs, extent, NULL, +sector_num * 512, 0, &offset); +/* get_cluster_offset returning 0 means success */ +ret = !ret; + +index_in_cluster = sector_num % extent->cluster_sectors; +n = extent->cluster_sectors - index_in_cluster; if (n > nb_sectors) n = nb_sectors; *pnum = n; @@ -822,14 +825,15 @@ static int vmdk_read(BlockDriverState *bs, int64_t sector_num, if (!extent) { return -EIO; } -cluster_offset = get_cluster_offset( -bs, extent, NULL, sector_num << 9, 0); +ret = get_cluster_offset( +bs, extent, NULL, +sector_num << 9, 0, &cluster_offset); index_in_cluster = sector_num % extent->cluster_sectors; n = extent->cluster_sector
[Qemu-devel] [PATCH v5 06/12] VMDK: flush multiple extents
Flush all the file that referenced by the image. Signed-off-by: Fam Zheng --- block/vmdk.c | 12 +++- 1 files changed, 11 insertions(+), 1 deletions(-) diff --git a/block/vmdk.c b/block/vmdk.c index c3f0ab6..cf7370f 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -1084,7 +1084,17 @@ static void vmdk_close(BlockDriverState *bs) static int vmdk_flush(BlockDriverState *bs) { -return bdrv_flush(bs->file); +int i, ret, err; +BDRVVmdkState *s = bs->opaque; + +ret = bdrv_flush(bs->file); +for (i = 0; i < s->num_extents; i++) { +err = bdrv_flush(s->extents[i].file); +if (err < 0) { +ret = err; +} +} +return ret; }
[Qemu-devel] [PATCH v5 09/12] VMDK: open/read/write for monolithicFlat image
Parse vmdk decriptor file and open mono flat image. Read/write the flat extent. Signed-off-by: Fam Zheng --- block/vmdk.c | 185 + 1 files changed, 172 insertions(+), 13 deletions(-) diff --git a/block/vmdk.c b/block/vmdk.c index c84ea90..8083c31 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -65,6 +65,7 @@ typedef struct VmdkExtent { bool flat; int64_t sectors; int64_t end_sector; +int64_t flat_start_offset; int64_t l1_table_offset; int64_t l1_backup_table_offset; uint32_t *l1_table; @@ -390,9 +391,10 @@ fail: static int vmdk_parent_open(BlockDriverState *bs) { char *p_name; -char desc[DESC_SIZE]; +char desc[DESC_SIZE + 1]; BDRVVmdkState *s = bs->opaque; +desc[DESC_SIZE] = '\0'; if (bdrv_pread(bs->file, s->desc_offset, desc, DESC_SIZE) != DESC_SIZE) { return -1; } @@ -588,6 +590,157 @@ static int vmdk_open_vmdk4(BlockDriverState *bs, int flags) return ret; } +/* find an option value out of descriptor file */ +static int vmdk_parse_description(const char *desc, const char *opt_name, +char *buf, int buf_size) +{ +char *opt_pos, *opt_end; +const char *end = desc + strlen(desc); + +opt_pos = strstr(desc, opt_name); +if (!opt_pos) { +return -1; +} +/* Skip "=\"" following opt_name */ +opt_pos += strlen(opt_name) + 2; +if (opt_pos >= end) { +return -1; +} +opt_end = opt_pos; +while (opt_end < end && *opt_end != '"') { +opt_end++; +} +if (opt_end == end || buf_size < opt_end - opt_pos + 1) { +return -1; +} +pstrcpy(buf, opt_end - opt_pos + 1, opt_pos); +return 0; +} + +static int vmdk_parse_extents(const char *desc, BlockDriverState *bs, +const char *desc_file_path) +{ +int ret = 0; +int r; +char access[11]; +char type[11]; +char fname[512]; +const char *p = desc; +int64_t sectors = 0; +int64_t flat_offset; + +while (*p) { +if (strncmp(p, "RW", strlen("RW"))) { +goto next_line; +} +/* parse extent line: + * RW [size in sectors] FLAT "file-name.vmdk" OFFSET + * or + * RW [size in sectors] SPARSE "file-name.vmdk" + */ +flat_offset = -1; +sscanf(p, "%10s %lld %10s %512s", +access, §ors, type, fname); +if (!strcmp(type, "FLAT")) { +sscanf(p, "%10s %lld %10s %512s %lld", +access, §ors, type, fname, &flat_offset); +if (flat_offset == -1) { +return -EINVAL; +} +} + +/* trim the quotation marks around */ +if (fname[0] == '"') { +memmove(fname, fname + 1, strlen(fname) + 1); +if (fname[strlen(fname) - 1] == '"') { +fname[strlen(fname) - 1] = '\0'; +} +} +if (!(strlen(access) && sectors && strlen(type) && strlen(fname))) { +goto next_line; +} +if (strcmp(type, "FLAT") && strcmp(type, "SPARSE")) { +goto next_line; +} +if (strcmp(access, "RW")) { +goto next_line; +} +ret++; + +/* save to extents array */ +if (!strcmp(type, "FLAT")) { +/* FLAT extent */ +char extent_path[PATH_MAX]; +BlockDriverState *extent_file; +BlockDriver *drv; +VmdkExtent *extent; + +extent_file = bdrv_new(""); +drv = bdrv_find_format("file"); +if (!drv) { +return -EINVAL; +} +path_combine(extent_path, sizeof(extent_path), +desc_file_path, fname); +r = bdrv_open(extent_file, extent_path, +BDRV_O_RDWR | BDRV_O_NO_BACKING, drv); +if (r) { +return -EINVAL; +} +extent = vmdk_add_extent(bs, extent_file, true, sectors, +0, 0, 0, 0, sectors); +extent->flat_start_offset = flat_offset; +} else { +/* SPARSE extent, not supported for now */ +fprintf(stderr, +"VMDK: Not supported extent type \"%s\""".\n", type); +return -ENOTSUP; +} +next_line: +/* move to next line */ +while (*p && *p != '\n') { +p++; +} +p++; +} +return 0; +} + +static int vmdk_open_desc_file(BlockDriverState *bs, int flags) +{ +int ret; +char buf[2048]; +char ct[128]; +BDRVVmdkState *s = bs->opaque; + +ret = bdrv_pread(bs->file, 0, buf, sizeof(buf)); +if (ret < 0) { +return ret; +} +buf[2047] = '\0'; +if (vmdk_parse_description(buf, "createType", ct, sizeof(ct))) { +return -EINVAL; +} +if (strcmp(ct, "monolithicFlat")) { +fprintf(stderr, +"VMDK: Not supported image ty
[Qemu-devel] [PATCH v5 02/12] VMDK: bugfix, align offset to cluster in get_whole_cluster
In get_whole_cluster, the offset is not aligned to cluster when reading from backing_hd. When the first write to child is not at the cluster boundary, wrong address data from parent is copied to child. Signed-off-by: Fam Zheng --- block/vmdk.c |8 +--- 1 files changed, 5 insertions(+), 3 deletions(-) diff --git a/block/vmdk.c b/block/vmdk.c index 49df1a5..a2538be 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -511,21 +511,23 @@ static int get_whole_cluster(BlockDriverState *bs, /* 128 sectors * 512 bytes each = grain size 64KB */ uint8_t whole_grain[extent->cluster_sectors * 512]; -// we will be here if it's first write on non-exist grain(cluster). -// try to read from parent image, if exist +/* we will be here if it's first write on non-exist grain(cluster). + * try to read from parent image, if exist */ if (bs->backing_hd) { int ret; if (!vmdk_is_cid_valid(bs)) return -1; +/* floor offset to cluster */ +offset -= offset % (extent->cluster_sectors * 512); ret = bdrv_read(bs->backing_hd, offset >> 9, whole_grain, extent->cluster_sectors); if (ret < 0) { return -1; } -//Write grain only into the active image +/* Write grain only into the active image */ ret = bdrv_write(extent->file, cluster_offset, whole_grain, extent->cluster_sectors); if (ret < 0) {
[Qemu-devel] [PATCH v5 05/12] VMDK: add field BDRVVmdkState.desc_offset
There are several occurrence of magic number 0x200 as the descriptor offset within mono sparse image file. This is not the case for images with separate descriptor file. So a field is added to BDRVVmdkState to hold the correct value. Signed-off-by: Fam Zheng --- block/vmdk.c | 26 -- 1 files changed, 16 insertions(+), 10 deletions(-) diff --git a/block/vmdk.c b/block/vmdk.c index 81c1054..c3f0ab6 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -81,6 +81,7 @@ typedef struct VmdkExtent { } VmdkExtent; typedef struct BDRVVmdkState { +int desc_offset; int num_extents; uint32_t parent_cid; VmdkExtent *extents; @@ -160,10 +161,11 @@ static uint32_t vmdk_read_cid(BlockDriverState *bs, int parent) uint32_t cid; const char *p_name, *cid_str; size_t cid_str_size; +BDRVVmdkState *s = bs->opaque; -/* the descriptor offset = 0x200 */ -if (bdrv_pread(bs->file, 0x200, desc, DESC_SIZE) != DESC_SIZE) +if (bdrv_pread(bs->file, s->desc_offset, desc, DESC_SIZE) != DESC_SIZE) { return 0; +} if (parent) { cid_str = "parentCID"; @@ -185,10 +187,11 @@ static int vmdk_write_cid(BlockDriverState *bs, uint32_t cid) { char desc[DESC_SIZE], tmp_desc[DESC_SIZE]; char *p_name, *tmp_str; +BDRVVmdkState *s = bs->opaque; -/* the descriptor offset = 0x200 */ -if (bdrv_pread(bs->file, 0x200, desc, DESC_SIZE) != DESC_SIZE) -return -1; +if (bdrv_pread(bs->file, s->desc_offset, desc, DESC_SIZE) != DESC_SIZE) { +return -EIO; +} tmp_str = strstr(desc,"parentCID"); pstrcpy(tmp_desc, sizeof(tmp_desc), tmp_str); @@ -198,8 +201,9 @@ static int vmdk_write_cid(BlockDriverState *bs, uint32_t cid) pstrcat(desc, sizeof(desc), tmp_desc); } -if (bdrv_pwrite_sync(bs->file, 0x200, desc, DESC_SIZE) < 0) -return -1; +if (bdrv_pwrite_sync(bs->file, s->desc_offset, desc, DESC_SIZE) < 0) { +return -EIO; +} return 0; } @@ -283,7 +287,6 @@ static int vmdk_snapshot_create(const char *filename, const char *backing_file) ret = -errno; goto fail; } -/* the descriptor offset = 0x200 */ if (lseek(p_fd, 0x200, SEEK_SET) == -1) { ret = -errno; goto fail; @@ -387,10 +390,11 @@ static int vmdk_parent_open(BlockDriverState *bs) { char *p_name; char desc[DESC_SIZE]; +BDRVVmdkState *s = bs->opaque; -/* the descriptor offset = 0x200 */ -if (bdrv_pread(bs->file, 0x200, desc, DESC_SIZE) != DESC_SIZE) +if (bdrv_pread(bs->file, s->desc_offset, desc, DESC_SIZE) != DESC_SIZE) { return -1; +} if ((p_name = strstr(desc,"parentFileNameHint")) != NULL) { char *end_name; @@ -518,6 +522,7 @@ static int vmdk_open_vmdk3(BlockDriverState *bs, int flags) VmdkExtent *extent; BDRVVmdkState *s = bs->opaque; +s->desc_offset = 0x200; ret = bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header)); if (ret != sizeof(header)) { ret = ret < 0 ? ret : -EIO; @@ -545,6 +550,7 @@ static int vmdk_open_vmdk4(BlockDriverState *bs, int flags) BDRVVmdkState *s = bs->opaque; VmdkExtent *extent; +s->desc_offset = 0x200; ret = bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header)); if (ret != sizeof(header)) { ret = ret < 0 ? ret : -EIO;
[Qemu-devel] [PATCH v5 01/12] VMDK: introduce VmdkExtent
Introduced VmdkExtent array into BDRVVmdkState, enable holding multiple image extents for multiple file image support. Signed-off-by: Fam Zheng --- block/vmdk.c | 351 +- 1 files changed, 250 insertions(+), 101 deletions(-) diff --git a/block/vmdk.c b/block/vmdk.c index 922b23d..49df1a5 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -60,7 +60,11 @@ typedef struct { #define L2_CACHE_SIZE 16 -typedef struct BDRVVmdkState { +typedef struct VmdkExtent { +BlockDriverState *file; +bool flat; +int64_t sectors; +int64_t end_sector; int64_t l1_table_offset; int64_t l1_backup_table_offset; uint32_t *l1_table; @@ -74,7 +78,12 @@ typedef struct BDRVVmdkState { uint32_t l2_cache_counts[L2_CACHE_SIZE]; unsigned int cluster_sectors; +} VmdkExtent; + +typedef struct BDRVVmdkState { +int num_extents; uint32_t parent_cid; +VmdkExtent *extents; } BDRVVmdkState; typedef struct VmdkMetaData { @@ -156,8 +165,8 @@ static int vmdk_write_cid(BlockDriverState *bs, uint32_t cid) static int vmdk_is_cid_valid(BlockDriverState *bs) { -#ifdef CHECK_CID BDRVVmdkState *s = bs->opaque; +#ifdef CHECK_CID BlockDriverState *p_bs = bs->backing_hd; uint32_t cur_pcid; @@ -358,11 +367,50 @@ static int vmdk_parent_open(BlockDriverState *bs) return 0; } +/* Create and append extent to the extent array. Return the added VmdkExtent + * address. return NULL if allocation failed. */ +static VmdkExtent *vmdk_add_extent(BlockDriverState *bs, + BlockDriverState *file, bool flat, int64_t sectors, + int64_t l1_offset, int64_t l1_backup_offset, + uint32_t l1_size, + int l2_size, unsigned int cluster_sectors) +{ +VmdkExtent *extent; +BDRVVmdkState *s = bs->opaque; + +s->extents = qemu_realloc(s->extents, + (s->num_extents + 1) * sizeof(VmdkExtent)); +extent = &s->extents[s->num_extents]; +s->num_extents++; + +memset(extent, 0, sizeof(VmdkExtent)); +extent->file = file; +extent->flat = flat; +extent->sectors = sectors; +extent->l1_table_offset = l1_offset; +extent->l1_backup_table_offset = l1_backup_offset; +extent->l1_size = l1_size; +extent->l1_entry_sectors = l2_size * cluster_sectors; +extent->l2_size = l2_size; +extent->cluster_sectors = cluster_sectors; + +if (s->num_extents > 1) { +extent->end_sector = (*(extent - 1)).end_sector + extent->sectors; +} else { +extent->end_sector = extent->sectors; +} +bs->total_sectors = extent->end_sector; +return extent; +} + + static int vmdk_open(BlockDriverState *bs, int flags) { BDRVVmdkState *s = bs->opaque; uint32_t magic; -int l1_size, i; +int i; +uint32_t l1_size, l1_entry_sectors; +VmdkExtent *extent = NULL; if (bdrv_pread(bs->file, 0, &magic, sizeof(magic)) != sizeof(magic)) goto fail; @@ -370,32 +418,34 @@ static int vmdk_open(BlockDriverState *bs, int flags) magic = be32_to_cpu(magic); if (magic == VMDK3_MAGIC) { VMDK3Header header; - -if (bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header)) != sizeof(header)) +if (bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header)) +!= sizeof(header)) { goto fail; -s->cluster_sectors = le32_to_cpu(header.granularity); -s->l2_size = 1 << 9; -s->l1_size = 1 << 6; -bs->total_sectors = le32_to_cpu(header.disk_sectors); -s->l1_table_offset = le32_to_cpu(header.l1dir_offset) << 9; -s->l1_backup_table_offset = 0; -s->l1_entry_sectors = s->l2_size * s->cluster_sectors; +} +extent = vmdk_add_extent(bs, bs->file, false, + le32_to_cpu(header.disk_sectors), + le32_to_cpu(header.l1dir_offset) << 9, 0, + 1 << 6, 1 << 9, le32_to_cpu(header.granularity)); } else if (magic == VMDK4_MAGIC) { VMDK4Header header; - -if (bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header)) != sizeof(header)) +if (bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header)) +!= sizeof(header)) { goto fail; -bs->total_sectors = le64_to_cpu(header.capacity); -s->cluster_sectors = le64_to_cpu(header.granularity); -s->l2_size = le32_to_cpu(header.num_gtes_per_gte); -s->l1_entry_sectors = s->l2_size * s->cluster_sectors; -if (s->l1_entry_sectors <= 0) +} +l1_entry_sectors = le32_to_cpu(header.num_gtes_per_gte) +* le64_to_cpu(header.granularity); +l1_size = (le64_to_cpu(header.capacity) + l1_entry_sectors - 1) +/ l1_entry_sectors; +extent = vmdk_add_extent(bs, bs->file, false
[Qemu-devel] [PATCH v5 03/12] VMDK: probe for monolithicFlat images
Probe as the same behavior as VMware does. Recognize image as monolithicFlat descriptor file when the file is text and the first effective line (not '#' leaded comment or space line) is either 'version=1' or 'version=2'. No space or upper case charactors accepted. Signed-off-by: Fam Zheng --- block/vmdk.c | 44 ++-- 1 files changed, 42 insertions(+), 2 deletions(-) diff --git a/block/vmdk.c b/block/vmdk.c index a2538be..3bf8980 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -102,10 +102,50 @@ static int vmdk_probe(const uint8_t *buf, int buf_size, const char *filename) return 0; magic = be32_to_cpu(*(uint32_t *)buf); if (magic == VMDK3_MAGIC || -magic == VMDK4_MAGIC) +magic == VMDK4_MAGIC) { return 100; -else +} else { +const char *p = (const char *)buf; +const char *end = p + buf_size; +while (p < end) { +if (*p == '#') { +/* skip comment line */ +while (p < end && *p != '\n') { +p++; +} +p++; +continue; +} +if (*p == ' ') { +while (p < end && *p == ' ') { +p++; +} +/* skip '\r' if windows line endings used. */ +if (p < end && *p == '\r') { +p++; +} +/* only accept blank lines before 'version=' line */ +if (p == end || *p != '\n') { +return 0; +} +p++; +continue; +} +if (end - p >= strlen("version=X\n")) { +if (strncmp("version=1\n", p, strlen("version=1\n")) == 0 || +strncmp("version=2\n", p, strlen("version=2\n")) == 0) { +return 100; +} +} +if (end - p >= strlen("version=X\r\n")) { +if (strncmp("version=1\r\n", p, strlen("version=1\r\n")) == 0 || +strncmp("version=2\r\n", p, strlen("version=2\r\n")) == 0) { +return 100; +} +} +} return 0; +} } #define CHECK_CID 1
[Qemu-devel] [PATCH v5 04/12] VMDK: separate vmdk_open by format version
Separate vmdk_open by subformats to: * vmdk_open_vmdk3 * vmdk_open_vmdk4 Signed-off-by: Fam Zheng --- block/vmdk.c | 195 + 1 files changed, 126 insertions(+), 69 deletions(-) diff --git a/block/vmdk.c b/block/vmdk.c index 3bf8980..81c1054 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -443,74 +443,26 @@ static VmdkExtent *vmdk_add_extent(BlockDriverState *bs, return extent; } - -static int vmdk_open(BlockDriverState *bs, int flags) +static int vmdk_init_tables(BlockDriverState *bs, VmdkExtent *extent) { -BDRVVmdkState *s = bs->opaque; -uint32_t magic; -int i; -uint32_t l1_size, l1_entry_sectors; -VmdkExtent *extent = NULL; - -if (bdrv_pread(bs->file, 0, &magic, sizeof(magic)) != sizeof(magic)) -goto fail; - -magic = be32_to_cpu(magic); -if (magic == VMDK3_MAGIC) { -VMDK3Header header; -if (bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header)) -!= sizeof(header)) { -goto fail; -} -extent = vmdk_add_extent(bs, bs->file, false, - le32_to_cpu(header.disk_sectors), - le32_to_cpu(header.l1dir_offset) << 9, 0, - 1 << 6, 1 << 9, le32_to_cpu(header.granularity)); -} else if (magic == VMDK4_MAGIC) { -VMDK4Header header; -if (bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header)) -!= sizeof(header)) { -goto fail; -} -l1_entry_sectors = le32_to_cpu(header.num_gtes_per_gte) -* le64_to_cpu(header.granularity); -l1_size = (le64_to_cpu(header.capacity) + l1_entry_sectors - 1) -/ l1_entry_sectors; -extent = vmdk_add_extent(bs, bs->file, false, - le64_to_cpu(header.capacity), - le64_to_cpu(header.rgd_offset) << 9, - le64_to_cpu(header.gd_offset) << 9, - l1_size, - le32_to_cpu(header.num_gtes_per_gte), - le64_to_cpu(header.granularity)); -if (extent->l1_entry_sectors <= 0) { -goto fail; -} -// try to open parent images, if exist -if (vmdk_parent_open(bs) != 0) -goto fail; -// write the CID once after the image creation -s->parent_cid = vmdk_read_cid(bs,1); -} else { -goto fail; -} - -/* sum up the total sectors */ -bs->total_sectors = 0; -for (i = 0; i < s->num_extents; i++) { -bs->total_sectors += s->extents[i].sectors; -} +int ret; +int l1_size, i; /* read the L1 table */ l1_size = extent->l1_size * sizeof(uint32_t); extent->l1_table = qemu_malloc(l1_size); -if (bdrv_pread(bs->file, -extent->l1_table_offset, -extent->l1_table, -l1_size) -!= l1_size) { +if (!extent->l1_table) { +ret = -ENOMEM; goto fail; } +ret = bdrv_pread(bs->file, +extent->l1_table_offset, +extent->l1_table, +l1_size); +if (ret != l1_size) { +ret = ret < 0 ? ret : -EIO; +goto fail_l1; +} for (i = 0; i < extent->l1_size; i++) { le32_to_cpus(&extent->l1_table[i]); } @@ -525,21 +477,126 @@ static int vmdk_open(BlockDriverState *bs, int flags) goto fail; } for (i = 0; i < extent->l1_size; i++) { +if (!extent->l1_backup_table) { +ret = -ENOMEM; +goto fail_l1; +} +} +ret = bdrv_pread(bs->file, +extent->l1_backup_table_offset, +extent->l1_backup_table, +l1_size); +if (ret != l1_size) { +ret = ret < 0 ? ret : -EIO; +goto fail; +} +for (i = 0; i < extent->l1_size; i++) { le32_to_cpus(&extent->l1_backup_table[i]); } } extent->l2_cache = qemu_malloc(extent->l2_size * L2_CACHE_SIZE * sizeof(uint32_t)); +if (!extent->l2_cache) { +ret = -ENOMEM; +goto fail_l1b; +} return 0; + fail_l1b: +qemu_free(extent->l1_backup_table); + fail_l1: +qemu_free(extent->l1_table); fail: -for (i = 0; i < s->num_extents; i++) { -qemu_free(s->extents[i].l1_backup_table); -qemu_free(s->extents[i].l1_table); -qemu_free(s->extents[i].l2_cache); +return ret; +} + +static int vmdk_open_vmdk3(BlockDriverState *bs, int flags) +{ +int ret; +uint32_t magic; +VMDK3Header header; +VmdkExtent *extent; +BDRVVmdkState *s = bs->opaque; + +ret = bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header)); +if (ret != sizeof(header)) { +ret = ret < 0 ? ret : -E
[Qemu-devel] [PATCH v5 00/12] Adding VMDK monolithic flat support
Changes from v4: 09/12: pstrcpy call off-by-one in vmdk_parse_description Fam Zheng (12): VMDK: introduce VmdkExtent VMDK: bugfix, align offset to cluster in get_whole_cluster VMDK: probe for monolithicFlat images VMDK: separate vmdk_open by format version VMDK: add field BDRVVmdkState.desc_offset VMDK: flush multiple extents VMDK: move 'static' cid_update flag to bs field VMDK: change get_cluster_offset return type VMDK: open/read/write for monolithicFlat image VMDK: create different subformats VMDK: fix coding style BlockDriver: add bdrv_get_allocated_file_size() operation block.c | 19 + block.h |1 + block/raw-posix.c | 21 + block/raw-win32.c | 29 ++ block/vmdk.c | 1379 + block_int.h |2 + qemu-img.c| 31 +-- 7 files changed, 1046 insertions(+), 436 deletions(-)
Re: [Qemu-devel] [PATCH 08/12] TCG/PPC: use TCG_REG_CALL_STACK instead of TCG_REG_R1
On Sun, 26 Jun 2011, Blue Swirl wrote: > Use TCG_REG_CALL_STACK instead of TCG_REG_R1 etc. for consistency. > This i'd rather avoid. [..snip..] -- mailto:av1...@comtv.ru
Re: [Qemu-devel] [PATCH 09/12] TCG/PPC: use stack for TCG temps
On Sun, 26 Jun 2011, Blue Swirl wrote: > Use stack instead of temp_buf array in CPUState for TCG temps. > This works. > Signed-off-by: Blue Swirl > --- > tcg/ppc/tcg-target.c |7 +-- > tcg/ppc64/tcg-target.c |7 +-- > 2 files changed, 10 insertions(+), 4 deletions(-) > > diff --git a/tcg/ppc/tcg-target.c b/tcg/ppc/tcg-target.c > index 5ab5d6d..100ef12 100644 > --- a/tcg/ppc/tcg-target.c > +++ b/tcg/ppc/tcg-target.c > @@ -907,9 +907,14 @@ static void tcg_target_qemu_prologue (TCGContext *s) > + LINKAGE_AREA_SIZE > + TCG_STATIC_CALL_ARGS_SIZE > + ARRAY_SIZE (tcg_target_callee_save_regs) * 4 > ++ CPU_TEMP_BUF_NLONGS * sizeof(long) > ; > frame_size = (frame_size + 15) & ~15; > > +tcg_set_frame(s, TCG_REG_CALL_STACK, frame_size > + - CPU_TEMP_BUF_NLONGS * sizeof(long), > + CPU_TEMP_BUF_NLONGS * sizeof(long)); > + > #ifdef _CALL_AIX > { > uint32_t addr; > @@ -1923,6 +1928,4 @@ static void tcg_target_init(TCGContext *s) > #endif > > tcg_add_target_add_op_defs(ppc_op_defs); > -tcg_set_frame(s, TCG_AREG0, offsetof(CPUState, temp_buf), > - CPU_TEMP_BUF_NLONGS * sizeof(long)); > } > diff --git a/tcg/ppc64/tcg-target.c b/tcg/ppc64/tcg-target.c > index 5f79342..6c92d84 100644 > --- a/tcg/ppc64/tcg-target.c > +++ b/tcg/ppc64/tcg-target.c > @@ -875,9 +875,14 @@ static void tcg_target_qemu_prologue (TCGContext *s) > + 8 /* TOC save area */ > + TCG_STATIC_CALL_ARGS_SIZE > + ARRAY_SIZE (tcg_target_callee_save_regs) * 8 > ++ CPU_TEMP_BUF_NLONGS * sizeof(long) > ; > frame_size = (frame_size + 15) & ~15; > > +tcg_set_frame(s, TCG_REG_CALL_STACK, frame_size > + - CPU_TEMP_BUF_NLONGS * sizeof(long), > + CPU_TEMP_BUF_NLONGS * sizeof(long)); > + > #ifndef __APPLE__ > /* First emit adhoc function descriptor */ > addr = (uint64_t) s->code_ptr + 24; > @@ -1698,6 +1703,4 @@ static void tcg_target_init (TCGContext *s) > tcg_regset_set_reg (s->reserved_regs, TCG_REG_R13); > > tcg_add_target_add_op_defs (ppc_op_defs); > -tcg_set_frame(s, TCG_AREG0, offsetof(CPUState, temp_buf), > - CPU_TEMP_BUF_NLONGS * sizeof(long)); > } > -- mailto:av1...@comtv.ru
Re: [Qemu-devel] [PULL] virtio-serial: Fix segfault on start
On 06/27/2011 04:37 AM, Amit Shah wrote: Hello, This fixes a segfault at startup regression debugged and fixed by Luiz. Please pull. The following changes since commit f26e428da505709ec03b2ed2c9eb3db82b30bd7b: Fix MinGW compilation when --enable-vnc-jpeg is specified (2011-06-26 20:19:38 +) Pulled. Thanks. Regards, Anthony Liguori are available in the git repository at: git://git.kernel.org/pub/scm/virt/qemu/amit/virtio-serial.git for-anthony Luiz Capitulino (1): virtio-serial: Fix segfault on guest boot hw/virtio-serial-bus.c | 24 ++-- 1 files changed, 14 insertions(+), 10 deletions(-) Amit
Re: [Qemu-devel] [PATCH] [PowerPC][RFC] booke timers
On Mon, 27 Jun 2011 18:14:06 +0200 Fabien Chouteau wrote: > While working on the emulation of the freescale p2010 (e500v2) I realized that > there's no implementation of booke's timers features. Currently mpc8544 uses > ppc_emb (ppc_emb_timers_init) which is close but not exactly like booke (for > example booke uses different SPR). ppc_emb_timers_init should be renamed something less generic, then. > +/* Timer Control Register */ > + > +#define TCR_WP_MASK 0x3 /* Watchdog Timer Period */ > +#define TCR_WP_SHIFT 30 > +#define TCR_WRC_MASK 0x3 /* Watchdog Timer Reset Control */ > +#define TCR_WRC_SHIFT 28 Usually such MASK defines are before shifting right: #define TCR_WP_MASK 0xc000 #define TCR_WP_SHIFT 30 #define TCR_WRC_MASK 0x3000 #define TCR_WRC_SHIFT 28 That way you can do things like if (tcr & TCR_WRC_MASK) { ... } > +/* Return the time base value at which the FIT will raise an interrupt */ > +static uint64_t booke_get_fit_target(CPUState *env) > +{ > +uint32_t fp = (env->spr[SPR_BOOKE_TCR] >> TCR_FP_SHIFT) & TCR_FP_MASK; > + > +/* Only for e500 */ > +if (env->insns_flags2 & PPC2_BOOKE206) { > +uint32_t fpext = (env->spr[SPR_BOOKE_TCR] >> TCR_E500_FPEXT_SHIFT) > +& TCR_E500_FPEXT_MASK; > +fp |= fpext << 2; > +} BOOKE206 does not mean e500. FPEXT does not exist in Power ISA V2.06 Book III-E. > + > +return 1 << fp; > +} The particular bits selected by the possible values of FP are implementation-dependent. e500 uses fpext to make all values possible, but on 440 the four values of fp select from 2^13, 2^17, 2^21, and 2^25. > +/* Return the time base value at which the WDT will raise an interrupt */ > +static uint64_t booke_get_wdt_target(CPUState *env) > +{ > +uint32_t fp = (env->spr[SPR_BOOKE_TCR] >> TCR_WP_SHIFT) & TCR_WP_MASK; > + > +/* Only for e500 */ > +if (env->insns_flags2 & PPC2_BOOKE206) { > +uint32_t fpext = (env->spr[SPR_BOOKE_TCR] >> TCR_E500_WPEXT_SHIFT) > +& TCR_E500_WPEXT_MASK; > +fp |= fpext << 2; > +} > + > +return 1 << fp; > +} s/fp/wp/ Avoiding the confusion is especially important on 440, since a different interval is selected by a given value in FP versus WP. > +static void booke_update_fixed_timer(CPUState *env, > + uint64_t tb_target, > + uint64_t *next, > + struct QEMUTimer *timer) > +{ > +ppc_tb_t *tb_env = env->tb_env; > +uint64_t lapse; > +uint64_t tb; > +uint64_t now; > + > +now = qemu_get_clock_ns(vm_clock); > +tb = cpu_ppc_get_tb(tb_env, now, tb_env->tb_offset); > + > +if (tb_target < tb) { > +qemu_del_timer(timer); You're treating the target as the timebase value that has only the selected bit and nothing else -- you want to expire the next time that bit transitions from zero to one, regardless of the other bits. The timer should never be outright disabled. > +static void booke_decr_cb (void *opaque) > +{ > +CPUState *env; > +ppc_tb_t *tb_env; > +booke_timer_t *booke_timer; > + > +env = opaque; > +tb_env = env->tb_env; > +booke_timer = tb_env->opaque; > +env->spr[SPR_BOOKE_TSR] |= TSR_DIS; > +if (env->spr[SPR_BOOKE_TCR] & TCR_DIE) { > +ppc_set_irq(env, booke_timer->decr_excp, 1); > +} > + > +if (env->spr[SPR_BOOKE_TCR] & TCR_ARE) { > +/* Auto Reload */ > +cpu_ppc_store_decr(env, env->spr[SPR_BOOKE_DECAR]); > +} > +} I think some changes in the decrementer code are needed to provide booke semantics -- no raising the interrupt based on the high bit of decr, and stop counting when reach zero. > +static void booke_wdt_cb (void *opaque) > +{ > +CPUState *env; > +ppc_tb_t *tb_env; > +booke_timer_t *booke_timer; > + > +env = opaque; > +tb_env = env->tb_env; > +booke_timer = tb_env->opaque; > + > +/* TODO: There's lots of complicated stuff to do here */ > +abort(); > + > +booke_update_fixed_timer(env, > + booke_get_wdt_target(env), > + &booke_timer->wdt_next, > + booke_timer->wdt_timer); > +} Might want to avoid arming this one until that abort() is fixed... > + > +void store_booke_tsr (CPUState *env, target_ulong val) > +{ > +ppc_tb_t *tb_env = env->tb_env; > +booke_timer_t *booke_timer; > + > +booke_timer = tb_env->opaque; > + > +env->spr[SPR_BOOKE_TSR] &= ~(val & 0xFC00); Do we really need the "& 0xFC00"? Likewise in TCR. > + > +if (val & TSR_DIS) { > +ppc_set_irq(env, booke_timer->decr_excp, 0); > +} > + > +if (val & TSR_FIS) { > +ppc_set_irq(env, booke_timer->fit_excp, 0); > +} > + > +if (val & TSR_WIS) { > +ppc_set_irq(env, booke_timer->wdt_excp, 0); > +} > +} It looks like ppc_hw_interrupt() i
Re: [Qemu-devel] [PATCHv2 0/4] libcacard fixes
On Mon, Jun 27, 2011 at 05:27:35PM +0200, Christophe Fergeau wrote: > Hey, > > Alon asked me to split the parsing patches to make the review easier, to here > they are. Reviewed-by: Alon Levy > > Changes since v1: > - split first patch into 3 patches, v1 2/2 is unchanged > > Christophe Fergeau (4): > libcacard: s/strip(args++)/strip(args+1) > libcacard: fix soft=... parsing in vcard_emul_options > libcacard: introduce NEXT_TOKEN macro > libcacard: replace copy_string with strndup > > libcacard/vcard_emul_nss.c | 113 +-- > 1 files changed, 45 insertions(+), 68 deletions(-) > > -- > 1.7.5.4 > >
Re: [Qemu-devel] [RFC v2 00/20] Memory API
On 06/27/2011 10:59 AM, Michael S. Tsirkin wrote: On Mon, Jun 27, 2011 at 06:54:05PM +0300, Avi Kivity wrote: On 06/27/2011 06:52 PM, Michael S. Tsirkin wrote: - bridges might also enable subtractive decoding (required for isa behind the bridge) What does that mean? subtractive decoding is a method of address decoding in which a device accepts all accesses not positively decoded by another agent. Subtractive decoding is very slow in real hardware so generally any well known devices are positively decoded (like anything on the Super I/O chip). Unless we're dealing with very odd ISA devices, we probably don't need to worry about subtractive decoding. The real key point is, each level may dispatch in subtly different ways. You can get 95% of the way there with a generic memory API. I think it's the 95% that actually matters but just realize that we can't model hardware exactly without true hierarchical dispatch. Regards, Anthony Liguori
Re: [Qemu-devel] [PULL] pending linux-user patches
On 06/25/2011 11:18 AM, riku.voi...@iki.fi wrote: Hi, The following changes since commit 744d3644181ddb16ef5944a0f9217e46961c8c84: coreaudio: Fix OSStatus format specifier (2011-06-23 18:56:58 +0400) Pulled. Thanks. Regards, Anthony Liguori are available in the git repository at: git://git.linaro.org/people/rikuvoipio/qemu.git linux-user-for-upstream Cédric VINCENT (1): linux-user: Fix the load of ELF files that have no "useful" symbol linux-user: Fix the computation of the requested heap size Juan Quintela (5): linuxload: id_change was a write only variable syscall: really return ret code linux-user: syscall should use sanitized arg1 flatload: end_code was only used in a debug message flatload: memp was a write-only variable Laurent ALFONSI (1): linux-user: Define AT_RANDOM to support target stack protection mechanism. Mike Frysinger (1): linux-user: add pselect6 syscall support Mike McCormack (1): Don't translate pointer when in restore_sigcontext Peter Maydell (7): linux-user: Handle images where lowest vaddr is not page aligned linux-user: Don't use MAP_FIXED in do_brk() arm-semi.c: Use correct check for failure of do_brk() m68k-semi.c: Use correct check for failure of do_brk() linux-user: Bump do_syscall() up to 8 syscall arguments linux-user/signal.c: Remove only-ever-set variable fpu_save_addr linux-user/signal.c: Remove unused fenab Riku Voipio (1): linux-user: Fix sync_file_range on 32bit mips arm-semi.c |5 +- linux-user/elfload.c | 185 ++--- linux-user/flatload.c |8 +- linux-user/linuxload.c | 25 +- linux-user/main.c | 37 +--- linux-user/qemu.h |3 +- linux-user/signal.c| 21 +++-- linux-user/syscall.c | 240 +++- m68k-semi.c|5 +- 9 files changed, 354 insertions(+), 175 deletions(-) §
Re: [Qemu-devel] [PULL] pending linux-user patches
On 06/25/2011 11:18 AM, riku.voi...@iki.fi wrote: Hi, The following changes since commit 744d3644181ddb16ef5944a0f9217e46961c8c84: coreaudio: Fix OSStatus format specifier (2011-06-23 18:56:58 +0400) are available in the git repository at: git://git.linaro.org/people/rikuvoipio/qemu.git linux-user-for-upstream Pulled. Thanks. Regards, Anthony Liguori Cédric VINCENT (1): linux-user: Fix the load of ELF files that have no "useful" symbol linux-user: Fix the computation of the requested heap size Juan Quintela (5): linuxload: id_change was a write only variable syscall: really return ret code linux-user: syscall should use sanitized arg1 flatload: end_code was only used in a debug message flatload: memp was a write-only variable Laurent ALFONSI (1): linux-user: Define AT_RANDOM to support target stack protection mechanism. Mike Frysinger (1): linux-user: add pselect6 syscall support Mike McCormack (1): Don't translate pointer when in restore_sigcontext Peter Maydell (7): linux-user: Handle images where lowest vaddr is not page aligned linux-user: Don't use MAP_FIXED in do_brk() arm-semi.c: Use correct check for failure of do_brk() m68k-semi.c: Use correct check for failure of do_brk() linux-user: Bump do_syscall() up to 8 syscall arguments linux-user/signal.c: Remove only-ever-set variable fpu_save_addr linux-user/signal.c: Remove unused fenab Riku Voipio (1): linux-user: Fix sync_file_range on 32bit mips arm-semi.c |5 +- linux-user/elfload.c | 185 ++--- linux-user/flatload.c |8 +- linux-user/linuxload.c | 25 +- linux-user/main.c | 37 +--- linux-user/qemu.h |3 +- linux-user/signal.c| 21 +++-- linux-user/syscall.c | 240 +++- m68k-semi.c|5 +- 9 files changed, 354 insertions(+), 175 deletions(-) §
Re: [Qemu-devel] [PULL 00/13] Trivial patches for June 16 to June 24 2011
On 06/24/2011 11:56 AM, Stefan Hajnoczi wrote: (I currently do not have access to my email address.) The following changes since commit 744d3644181ddb16ef5944a0f9217e46961c8c84: coreaudio: Fix OSStatus format specifier (2011-06-23 18:56:58 +0400) are available in the git repository at: ssh://repo.or.cz/srv/git/qemu/stefanha.git trivial-patches Pulled. Thanks. Regards, Anthony Liguori Jan Kiszka (2): Align dummy display to fixed-size active console Do not include compatfd for WIN32 Juan Quintela (1): exec: last_first_tb was only used in !ONLY_USER case Marc-Antoine Perennou (1): qemu-kvm: fix pulseaudio detection in configure Markus Armbruster (5): sheepdog: qemu_bh_new() can't return null pointer, drop check Strip trailing '\n' from error_report()'s first argument qemu-img: Don't prepend qemu-img to error messages twice. Spell "unkown" correctly in error_report() arguments blockdev: Put space after comma in error message Matthew Fernandez (1): Fix comment typos in hw/armv7m.c Peter Maydell (2): configure: Don't create symlinks to nonexistent targets MAINTAINERS: Fix typo in email address Stefan Weil (1): w32: Remove redundant definitions of PRI*64 MAINTAINERS |2 +- block-migration.c |2 +- block/qcow2.c |2 +- block/sheepdog.c| 90 ++- blockdev.c |2 +- configure |6 ++- console.c |9 - cpus.c |3 ++ exec.c | 10 -- hw/armv7m.c |4 +- hw/lm32_sys.c |2 +- hw/lm32_timer.c |4 +- hw/lm32_uart.c |4 +- hw/milkymist-ac97.c |4 +- hw/milkymist-memcard.c |4 +- hw/milkymist-minimac2.c |6 ++-- hw/milkymist-pfpu.c |4 +- hw/milkymist-softusb.c |8 ++-- hw/milkymist-sysctl.c |4 +- hw/milkymist-tmu2.c |8 ++-- hw/qdev.c |2 +- hw/strongarm.c |4 +- hw/usb-ccid.c |2 +- hw/virtio-serial-bus.c | 10 +++--- hw/virtio.c |4 +- net.c |2 +- net/socket.c|6 ++-- qemu-common.h |5 --- qemu-error.c|2 + qemu-img.c | 12 +++--- 30 files changed, 117 insertions(+), 110 deletions(-)
Re: [Qemu-devel] [PULL] usb patch queue
On 06/24/2011 05:59 AM, Gerd Hoffmann wrote: Hi, Here comes the USB patch queue. Nothing major, just a bunch of little fixes and improvements. please pull, Pulled. Thanks. Regards, Anthony Liguori Gerd The following changes since commit 48e2faf222cbf4abab7c8e4b3f44229ec98eae7f: net: Warn about "-net nic" options which were ignored (2011-06-22 07:18:39 -0500) are available in the git repository at: git://git.kraxel.org/qemu usb.17 Gerd Hoffmann (6): usb-linux: add get_endp() usb-linux: make iso urb count contigurable usb-linux: track inflight iso urb count ehci: add freq + maxframes properties ehci: switch to nanoseconds usb: ignore USB_DT_DEBUG Hans de Goede (5): usb-bus: Don't allow attaching a device to a bus with no free ports usb: Proper error propagation for usb_device_attach errors usb: Add a speedmask to devices usb-linux: allow "compatible" high speed devices to connect at fullspeed usb-bus: Don't allow speed mismatch while attaching devices Markus Armbruster (1): usb-storage: Turn drive serial into a qdev property usb-storage.serial Peter Maydell (1): hw/usb-ohci.c: Fix handling of remote wakeup corner cases hw/usb-bus.c | 31 ++- hw/usb-ccid.c |1 + hw/usb-desc.c | 14 ++ hw/usb-ehci.c | 43 +++- hw/usb-msd.c | 19 ++-- hw/usb-ohci.c | 17 ++- hw/usb.h |4 ++ usb-bsd.c |2 + usb-linux.c | 124 + 9 files changed, 191 insertions(+), 64 deletions(-)
Re: [Qemu-devel] [PATCH 2/4] virtio-serial: Clean up virtser_bus_dev_print() output
Am 19.05.2011 um 16:18 schrieb Markus Armbruster: Amit Shah writes: On (Thu) 19 May 2011 [13:37:15], Markus Armbruster wrote: Old version looks like this in info qtree (last four lines): dev: virtconsole, id "" dev-prop: is_console = 1 dev-prop: nr = 0 dev-prop: chardev = dev-prop: name = dev-prop-int: id: 0 dev-prop-int: guest_connected: 1 dev-prop-int: host_connected: 0 dev-prop-int: throttled: 0 Indentation is off, and "dev-prop-int" suggests these are properties you can configure with -device, which isn't the case. The other buses' print_dev() callbacks don't do that. For instance, PCI's output looks like this: class Ethernet controller, addr 00:03.0, pci id 1af4:1000 (sub 1af4:0001) bar 0: i/o at 0x [0x1e] bar 1: mem at 0x [0xffe] bar 6: mem at 0x [0xfffe] Change virtser_bus_dev_print() to that style. Result: dev: virtconsole, id "" dev-prop: is_console = 1 dev-prop: nr = 0 dev-prop: chardev = dev-prop: name = port 0, guest on, host off, throttle off Here the original guest_connected and host_connected meant whether the endpoints were open. guest on/off, host on/off don't convey that meaning. Can't think of a short version, can you? I chose on/off to stay consistent with how qdev shows bool properties (print_bit() in qdev-properties.c). May be misguided. Like you, I'm having difficulties coming up with a better version that is still consise. Erm, I'm not aware that my qdev bool patch got committed yet, so the question of how to parse/print bool properties (on/off vs. yes/no) is still undecided, no comments so far. It would be entirely possible to let the author decide that on a case-by-case basis by using different property type enums for the same 'bool' type. Andreas
Re: [Qemu-devel] [PATCH] e1000: Handle IO Port.
On 27 June 2011 17:34, Anthony PERARD wrote: > @@ -83,6 +86,8 @@ typedef struct E1000State_st { > NICState *nic; > NICConf conf; > int mmio_index; > + int ioport_base; > + uint32_t ioport_reg[2]; I think ioport_reg[] needs to go in the VMStateDescription as well. I don't know enough about the PCI subsystem to know whether that's also true of ioport_base or whether the the map function is called again on a vmload. > @@ -202,6 +201,11 @@ rxbufsize(uint32_t v) > static void > set_ctrl(E1000State *s, int index, uint32_t val) > { > + DBGOUT(IO, "set ctrl = %08x\n", val); > + if (val & E1000_CTRL_RST) { > + s->mac_reg[CTRL] = val; > + e1000_reset(s); > + } There doesn't seem to be much point in setting mac_reg[CTRL] when e1000_reset() is going to put it to its reset value anyway; and you almost certainly don't want to fall through to this: > /* RST is self clearing */ > s->mac_reg[CTRL] = val & ~E1000_CTRL_RST; ...which means there's no need for that bit to special case RST. > static void > +e1000_ioport_writel(void *opaque, uint32_t addr, uint32_t val) > +{ > + E1000State *s = opaque; > + > + if (addr == s->ioport_base + REG_IOADDR) { > + DBGOUT(IO, "e1000_ioport_writel write base: 0x%04x\n", val); > + s->ioport_reg[REG_IOADDR] = val & 0xf; > + } else if (addr == (s->ioport_base + REG_IODATA)) { > + unsigned int index = (s->ioport_reg[REG_IOADDR] & 0x1) >> 2; > + > + DBGOUT(IO, "e1000_ioport_writel %x: 0x%04x\n", index, val); > + > + if (index < NWRITEOPS && macreg_writeops[index]) { > + macreg_writeops[index](s, index, val); > + } else if (index < NREADOPS && macreg_readops[index]) { > + DBGOUT(IO, "e1000_ioport_writel RO %x: 0x%04x\n", index << 2, > val); > + } else { > + DBGOUT(UNKNOWN, "IO unknown write index=0x%08x,val=0x%08x\n", > + index, val); > + } This part of this function seems to be duplicating the code in e1000_mmio_writel: wouldn't it be cleaner just to call that function? Ditto readl. -- PMM
Re: [Qemu-devel] [PATCH 04/12] TCG/IA64: use TCG_REG_CALL_STACK instead of TCG_REG_R12
On 06/26/2011 12:22 PM, Blue Swirl wrote: > Use TCG_REG_CALL_STACK instead of TCG_REG_R12 for consistency. > > Signed-off-by: Blue Swirl Reviewed-by: Richard Henderson r~
Re: [Qemu-devel] [PATCH 05/12] TCG/IA64: use stack for TCG temps
On 06/26/2011 12:22 PM, Blue Swirl wrote: > Use stack instead of temp_buf array in CPUState for TCG temps. > > Signed-off-by: Blue Swirl Reviewed-by: Richard Henderson r~
Re: [Qemu-devel] [PATCH 2/2] libcacard: add pc file, install it + includes
On Mon, Jun 27, 2011 at 02:11:00PM +0200, Christophe Fergeau wrote: > Hi, > > On Mon, Jun 27, 2011 at 12:34:44PM +0200, Alon Levy wrote: > > Also add --pkgconfigdir and --includedir configure parameters. > > --- > > configure | 10 ++ > > libcacard/Makefile| 25 ++--- > > libcacard/libcacard.pc.in | 13 + > > 3 files changed, 45 insertions(+), 3 deletions(-) > > create mode 100644 libcacard/libcacard.pc.in > > > > diff --git a/configure b/configure > > index e523976..d08818f 100755 > > --- a/configure > > +++ b/configure > > @@ -146,6 +146,8 @@ datadir="\${prefix}/share/qemu" > > docdir="\${prefix}/share/doc/qemu" > > bindir="\${prefix}/bin" > > libdir="\${prefix}/lib" > > +pkgconfigdir="\${prefix}/lib/pkgconfig" > > It would be more convenient if it was \${libdir}/pkgconfig and if it was > assigned a default value after --libdir has been parsed, though that would > look a bit out of place compared to how other values are set. ok, I'll drop --pkgconfigdir > > Christophe
[Qemu-devel] [PATCH v2] qemu_ram_ptr_length: take ram_addr_t as arguments
From: Stefano Stabellini qemu_ram_ptr_length should take ram_addr_t as argument rather than target_phys_addr_t because is doing comparisons with RAMBlock addresses. cpu_physical_memory_map should create a ram_addr_t address to pass to qemu_ram_ptr_length from PhysPageDesc phys_offset. Remove code after abort() in qemu_ram_ptr_length. Changes in v2: - handle 0 size in qemu_ram_ptr_length; - rename addr1 to raddr; - initialize raddr to ULONG_MAX. Signed-off-by: Stefano Stabellini --- cpu-common.h |2 +- exec.c | 21 ++--- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/cpu-common.h b/cpu-common.h index b027e43..e4fcded 100644 --- a/cpu-common.h +++ b/cpu-common.h @@ -65,7 +65,7 @@ void qemu_ram_free_from_ptr(ram_addr_t addr); void qemu_ram_remap(ram_addr_t addr, ram_addr_t length); /* This should only be used for ram local to a device. */ void *qemu_get_ram_ptr(ram_addr_t addr); -void *qemu_ram_ptr_length(target_phys_addr_t addr, target_phys_addr_t *size); +void *qemu_ram_ptr_length(ram_addr_t addr, ram_addr_t *size); /* Same but slower, to use for migration, where the order of * RAMBlocks must not change. */ void *qemu_safe_ram_ptr(ram_addr_t addr); diff --git a/exec.c b/exec.c index 7f14332..7d7c2b2 100644 --- a/exec.c +++ b/exec.c @@ -3135,8 +3135,11 @@ void *qemu_safe_ram_ptr(ram_addr_t addr) /* Return a host pointer to guest's ram. Similar to qemu_get_ram_ptr * but takes a size argument */ -void *qemu_ram_ptr_length(target_phys_addr_t addr, target_phys_addr_t *size) +void *qemu_ram_ptr_length(ram_addr_t addr, ram_addr_t *size) { +if (*size == 0) { +return NULL; +} if (xen_mapcache_enabled()) return qemu_map_cache(addr, *size, 1); else { @@ -3152,9 +3155,6 @@ void *qemu_ram_ptr_length(target_phys_addr_t addr, target_phys_addr_t *size) fprintf(stderr, "Bad ram offset %" PRIx64 "\n", (uint64_t)addr); abort(); - -*size = 0; -return NULL; } } @@ -4020,7 +4020,9 @@ void *cpu_physical_memory_map(target_phys_addr_t addr, target_phys_addr_t page; unsigned long pd; PhysPageDesc *p; -target_phys_addr_t addr1 = addr; +ram_addr_t raddr = ULONG_MAX; +ram_addr_t rlen; +void *ret; while (len > 0) { page = addr & TARGET_PAGE_MASK; @@ -4048,13 +4050,18 @@ void *cpu_physical_memory_map(target_phys_addr_t addr, *plen = l; return bounce.buffer; } +if (!todo) { +raddr = (pd & TARGET_PAGE_MASK) + (addr & ~TARGET_PAGE_MASK); +} len -= l; addr += l; todo += l; } -*plen = todo; -return qemu_ram_ptr_length(addr1, plen); +rlen = todo; +ret = qemu_ram_ptr_length(raddr, &rlen); +*plen = rlen; +return ret; } /* Unmaps a memory region previously mapped by cpu_physical_memory_map(). -- 1.7.2.3
Re: [Qemu-devel] [Qemu-trivial] [PATCH] fix MinGW compilation when --enable-vnc-jpeg is specified
Am 27.06.2011 07:56, schrieb Roy Tam: 2011/6/27 Stefan Weil: Am 27.06.2011 04:37, schrieb TeLeMan: This patch breaks the compilation with --enable-vnc-png: CC ui/vnc-enc-tight.o In file included from /usr/include/png.h:518, from ui/vnc-enc-tight.c:34: /usr/include/pngconf.h:371: error: expected '=', ',', ';', 'asm' or '__attribute__' before '.' token /usr/include/pngconf.h:372: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'include' make: *** [ui/vnc-enc-tight.o] Error 1 -- SUN OF A BEACH I get the same compiler error when I run with --enable-vnc-png, and the buildbots got it as well. In my last test, png support was disabled, so I did not notice this problem. The png header files check for prior inclusion of setjmp.h and have a really surprising way of telling that this happened (instead of #error, they use illegal C code - a comment without comment delimiters). I wonder which libpng version do you use. Mine is 1.5.2 and it works here. The critical code is only active for linux (#ifdef __linux__ ... #endif). I was using linbpng-1.2.42 (ubuntu) and libpng-1.2.44 (debian). You won't get the problem when compiling with MinGW.
Re: [Qemu-devel] [PATCH] qemu_ram_ptr_length: take ram_addr_t as arguments
On Mon, 27 Jun 2011, Peter Maydell wrote: > On 27 June 2011 14:34, Stefano Stabellini > wrote: > > On Fri, 24 Jun 2011, Peter Maydell wrote: > >> You probably want to only call qemu_ram_ptr_length() if (todo). > >> (I don't know if anybody ever calls this routine with a zero input > >> length, but that would handle that case too.) > > > > I would rather fix qemu_ram_ptr_length to handle 0 as size argument, and > > then call qemu_ram_ptr_length with 0 size from cpu_physical_memory_map > > (see appended patch). > > OK, that should work too. > > >> (Also 'addr1' is not a fantastic variable name :-)) > > > > Agreed, but it is the same as before :) > > Do you have any better suggestion? Maybe raddr? I admit I am not very > > imaginative with names. > > I think raddr is better than addr1, yes. OK, I'll use that instead. > > + if (*size == 0) > > + return NULL; > > Incidentally, QEMU coding style has braces here. scripts/checkpatch.pl > can catch this kind of minor style nit for you (although it is not > infallible...) Thanks for the tip, I'll have to start using that script for real: I work on three different projects and they all have very very similar code styles apart from this rule about the braces in one line statements, my brain cannot cope :/
[Qemu-devel] [Bug 799036] Re: NIC assignment order in command line make some NIC can't work
Without fixing address of the device, the first device will get 00:03.0 in my guest, and the second get 00:04.0. And when NIC 82576 is in the first order, it will get 00:03.0 in my guest, and it will not working. If I fix 82576 NIC using "addr=0x3" and other using "addr=0x4", 82576 NIC in guest will get 00:03.0 and the other will get 04:00.0. If fixing address, the assignment order doestn't matter the result. With "addr=0x3", NIC 82576 always works well in guest; but with "addr=0x4", 82580 or some other NIC will work well in my guest. -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/799036 Title: NIC assignment order in command line make some NIC can't work Status in QEMU: New Bug description: Environment: Host OS (ia32/ia32e/IA64):All Guest OS (ia32/ia32e/IA64):ia32e Guest OS Type (Linux/Windows):Linux kvm.git Commit:681fb677ace0754589792c92b8dbee9884d07158 qemu-kvm Commit:05f1737582ab6c075476bde931c5eafbc62a9349 Host Kernel Version:3.0.0-rc2+ Hardware: Westmere-EP platform Bug detailed description: -- When using qemu-system-x86_64 to create a linux guest with a 82586 NIC and a 82572EI NIC statically assigned, the two NIC's order in command line may make 82586 NIC can't work in guest. command1: qemu-system-x86_64 -m 1024 -smp 2 -device pci-assign,host=0e:00.1 -device pci-assign,host=0c:00.0 -net none -hda qcow-rhel6.img command2: qemu-system-x86_64 -m 1024 -smp 2 -device pci-assign,host=0c:00.0 -device pci-assign,host=0e:00.1 -net none -hda qcow-rhel6.img Using command1 to create a guest, both two NICs works well in guest. While using command2 to create a guest, 82576(kawela) NIC 0c:00.0 cannot get IP in guest. BDF 0c:00.0 is a 82576(kawela) NIC, while BDF 0e:00.1 is 82572EI NIC. The only difference of the two command lines is the order of NICs assignment. And only the 82576(kawela) NIC have this problem, the other one 82572EI always works well. And sriov VF doesn't have this issue. A VF and a 82576 PF assigned to a guest always work well. I don't know the order of NIC assignment in qemu-system-x86_64 will make this difference in guest. Maybe it's a qemu bug ? Reproduce steps: 1.pci-stub the two NIC 2.create a guest: qemu-system-x86_64 -m 1024 -smp 2 -device pci-assign,host=0c:00.0 -device pci-assign,host=0e:00.1 -net none -hda qcow-rhel6.img (0c:00.0 is a 82576 NIC, and 0e:00.1 is another NIC). Current result: 82576 PF and the other NIC in guest will work well regardless of what the order of assignment is. Expected result: To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/799036/+subscriptions
[Qemu-devel] [PATCH] [PowerPC][RFC] booke timers
While working on the emulation of the freescale p2010 (e500v2) I realized that there's no implementation of booke's timers features. Currently mpc8544 uses ppc_emb (ppc_emb_timers_init) which is close but not exactly like booke (for example booke uses different SPR). This is a first attempt for a distinct and clean implementation of booke's timers. Please feel free to comment. Signed-off-by: Fabien Chouteau --- Makefile.target|2 +- hw/ppc.c | 45 + hw/ppc.h | 23 + hw/ppc_booke.c | 254 hw/ppce500_mpc8544ds.c |4 +- 5 files changed, 281 insertions(+), 47 deletions(-) create mode 100644 hw/ppc_booke.c diff --git a/Makefile.target b/Makefile.target index 38afdb8..f0d4062 100644 --- a/Makefile.target +++ b/Makefile.target @@ -242,7 +242,7 @@ obj-i386-$(CONFIG_KVM) += kvmclock.o obj-i386-$(CONFIG_SPICE) += qxl.o qxl-logger.o qxl-render.o # shared objects -obj-ppc-y = ppc.o +obj-ppc-y = ppc.o ppc_booke.o obj-ppc-y += vga.o # PREP target obj-ppc-y += i8259.o mc146818rtc.o diff --git a/hw/ppc.c b/hw/ppc.c index 9157719..9932136 100644 --- a/hw/ppc.c +++ b/hw/ppc.c @@ -50,7 +50,7 @@ static void cpu_ppc_tb_stop (CPUState *env); static void cpu_ppc_tb_start (CPUState *env); -static void ppc_set_irq (CPUState *env, int n_IRQ, int level) +void ppc_set_irq (CPUState *env, int n_IRQ, int level) { unsigned int old_pending = env->pending_interrupts; @@ -423,25 +423,8 @@ void ppce500_irq_init (CPUState *env) } /*/ /* PowerPC time base and decrementer emulation */ -struct ppc_tb_t { -/* Time base management */ -int64_t tb_offset;/* Compensation*/ -int64_t atb_offset; /* Compensation*/ -uint32_t tb_freq; /* TB frequency*/ -/* Decrementer management */ -uint64_t decr_next;/* Tick for next decr interrupt*/ -uint32_t decr_freq;/* decrementer frequency */ -struct QEMUTimer *decr_timer; -/* Hypervisor decrementer management */ -uint64_t hdecr_next;/* Tick for next hdecr interrupt */ -struct QEMUTimer *hdecr_timer; -uint64_t purr_load; -uint64_t purr_start; -void *opaque; -}; -static inline uint64_t cpu_ppc_get_tb(ppc_tb_t *tb_env, uint64_t vmclk, - int64_t tb_offset) +uint64_t cpu_ppc_get_tb(ppc_tb_t *tb_env, uint64_t vmclk, int64_t tb_offset) { /* TB time in tb periods */ return muldiv64(vmclk, tb_env->tb_freq, get_ticks_per_sec()) + tb_offset; @@ -996,30 +979,6 @@ target_ulong load_40x_pit (CPUState *env) return cpu_ppc_load_decr(env); } -void store_booke_tsr (CPUState *env, target_ulong val) -{ -ppc_tb_t *tb_env = env->tb_env; -ppcemb_timer_t *ppcemb_timer; - -ppcemb_timer = tb_env->opaque; - -LOG_TB("%s: val " TARGET_FMT_lx "\n", __func__, val); -env->spr[SPR_40x_TSR] &= ~(val & 0xFC00); -if (val & 0x8000) -ppc_set_irq(env, ppcemb_timer->decr_excp, 0); -} - -void store_booke_tcr (CPUState *env, target_ulong val) -{ -ppc_tb_t *tb_env; - -tb_env = env->tb_env; -LOG_TB("%s: val " TARGET_FMT_lx "\n", __func__, val); -env->spr[SPR_40x_TCR] = val & 0xFFC0; -start_stop_pit(env, tb_env, 1); -cpu_4xx_wdt_cb(env); -} - static void ppc_emb_set_tb_clk (void *opaque, uint32_t freq) { CPUState *env = opaque; diff --git a/hw/ppc.h b/hw/ppc.h index 3ccf134..633c53e 100644 --- a/hw/ppc.h +++ b/hw/ppc.h @@ -1,3 +1,5 @@ +void ppc_set_irq (CPUState *env, int n_IRQ, int level); + /* PowerPC hardware exceptions management helpers */ typedef void (*clk_setup_cb)(void *opaque, uint32_t freq); typedef struct clk_setup_t clk_setup_t; @@ -11,6 +13,24 @@ static inline void clk_setup (clk_setup_t *clk, uint32_t freq) (*clk->cb)(clk->opaque, freq); } +struct ppc_tb_t { +/* Time base management */ +int64_t tb_offset;/* Compensation*/ +int64_t atb_offset; /* Compensation*/ +uint32_t tb_freq; /* TB frequency*/ +/* Decrementer management */ +uint64_t decr_next;/* Tick for next decr interrupt*/ +uint32_t decr_freq;/* decrementer frequency */ +struct QEMUTimer *decr_timer; +/* Hypervisor decrementer management */ +uint64_t hdecr_next;/* Tick for next hdecr interrupt */ +struct QEMUTimer *hdecr_timer; +uint64_t purr_load; +uint64_t purr_start; +void *opaque; +}; + +uint64_t cpu_ppc_get_tb(ppc_tb_t *tb_env, uint64_t vmclk, int64_t tb_offset); clk_setup_cb cpu_ppc_tb_init (CPUState *env, uint32_t freq); /* Embedded PowerPC DCR management */ typedef uint32_t (*dcr_read_cb)(void *opaque, int dcrn); @@ -55,3 +75,6 @@ enum { #define FW_CFG_PPC_KVM_PID (FW_CFG_ARCH_LOCAL + 0x07) #defin
Re: [Qemu-devel] [PATCH] qemu_ram_ptr_length: take ram_addr_t as arguments
On 27 June 2011 14:34, Stefano Stabellini wrote: > On Fri, 24 Jun 2011, Peter Maydell wrote: >> You probably want to only call qemu_ram_ptr_length() if (todo). >> (I don't know if anybody ever calls this routine with a zero input >> length, but that would handle that case too.) > > I would rather fix qemu_ram_ptr_length to handle 0 as size argument, and > then call qemu_ram_ptr_length with 0 size from cpu_physical_memory_map > (see appended patch). OK, that should work too. >> (Also 'addr1' is not a fantastic variable name :-)) > > Agreed, but it is the same as before :) > Do you have any better suggestion? Maybe raddr? I admit I am not very > imaginative with names. I think raddr is better than addr1, yes. > + if (*size == 0) > + return NULL; Incidentally, QEMU coding style has braces here. scripts/checkpatch.pl can catch this kind of minor style nit for you (although it is not infallible...) -- PMM
[Qemu-devel] [PATCH 1/2] linux-user: Add syscall numbers from kernel 2.6.39.2
Add syscall numbers for new syscall numbers; this brings us into line with Linux 2.6.39.2. Signed-off-by: Peter Maydell --- linux-user/alpha/syscall_nr.h | 23 ++- linux-user/arm/syscall_nr.h| 13 + linux-user/cris/syscall_nr.h |2 ++ linux-user/i386/syscall_nr.h | 12 linux-user/m68k/syscall_nr.h | 16 linux-user/main.c | 27 +++ linux-user/microblaze/syscall_nr.h | 14 -- linux-user/mips/syscall_nr.h | 13 + linux-user/mips64/syscall_nr.h | 13 + linux-user/mipsn32/syscall_nr.h| 14 ++ linux-user/ppc/syscall_nr.h| 30 ++ linux-user/s390x/syscall_nr.h | 13 +++-- linux-user/sh4/syscall_nr.h| 32 linux-user/sparc/syscall_nr.h | 12 linux-user/sparc64/syscall_nr.h| 12 linux-user/x86_64/syscall_nr.h | 12 16 files changed, 253 insertions(+), 5 deletions(-) diff --git a/linux-user/alpha/syscall_nr.h b/linux-user/alpha/syscall_nr.h index e3127df..f6284db 100644 --- a/linux-user/alpha/syscall_nr.h +++ b/linux-user/alpha/syscall_nr.h @@ -411,4 +411,25 @@ #define TARGET_NR_signalfd 476 #define TARGET_NR_timerfd 477 #define TARGET_NR_eventfd 478 - +#define TARGET_NR_recvmmsg 479 +#define TARGET_NR_fallocate 480 +#define TARGET_NR_timerfd_create481 +#define TARGET_NR_timerfd_settime 482 +#define TARGET_NR_timerfd_gettime 483 +#define TARGET_NR_signalfd4 484 +#define TARGET_NR_eventfd2 485 +#define TARGET_NR_epoll_create1 486 +#define TARGET_NR_dup3 487 +#define TARGET_NR_pipe2 488 +#define TARGET_NR_inotify_init1 489 +#define TARGET_NR_preadv490 +#define TARGET_NR_pwritev 491 +#define TARGET_NR_rt_tgsigqueueinfo 492 +#define TARGET_NR_perf_event_open 493 +#define TARGET_NR_fanotify_init 494 +#define TARGET_NR_fanotify_mark 495 +#define TARGET_NR_prlimit64 496 +#define TARGET_NR_name_to_handle_at 497 +#define TARGET_NR_open_by_handle_at 498 +#define TARGET_NR_clock_adjtime 499 +#define TARGET_NR_syncfs500 diff --git a/linux-user/arm/syscall_nr.h b/linux-user/arm/syscall_nr.h index 79a216a..7f05879 100644 --- a/linux-user/arm/syscall_nr.h +++ b/linux-user/arm/syscall_nr.h @@ -365,3 +365,16 @@ #define TARGET_NR_dup3 (358) #define TARGET_NR_pipe2(359) #define TARGET_NR_inotify_init1(360) +#define TARGET_NR_preadv (361) +#define TARGET_NR_pwritev (362) +#define TARGET_NR_rt_tgsigqueueinfo(363) +#define TARGET_NR_perf_event_open (364) +#define TARGET_NR_recvmmsg (365) +#define TARGET_NR_accept4 (366) +#define TARGET_NR_fanotify_init(367) +#define TARGET_NR_fanotify_mark(368) +#define TARGET_NR_prlimit64(369) +#define TARGET_NR_name_to_handle_at(370) +#define TARGET_NR_open_by_handle_at(371) +#define TARGET_NR_clock_adjtime(372) +#define TARGET_NR_syncfs (373) diff --git a/linux-user/cris/syscall_nr.h b/linux-user/cris/syscall_nr.h index 6132817..98f1a0b 100644 --- a/linux-user/cris/syscall_nr.h +++ b/linux-user/cris/syscall_nr.h @@ -333,3 +333,5 @@ #define TARGET_NR_dup3 330 #define TARGET_NR_pipe2 331 #define TARGET_NR_inotify_init1 332 +#define TARGET_NR_preadv 333 +#define TARGET_NR_pwritev334 diff --git a/linux-user/i386/syscall_nr.h b/linux-user/i386/syscall_nr.h index 3ef71ce..74abfca 100644 --- a/linux-user/i386/syscall_nr.h +++ b/linux-user/i386/syscall_nr.h @@ -335,3 +335,15 @@ #define TARGET_NR_dup3 330 #define TARGET_NR_pipe2331 #define TARGET_NR_inotify_init1332 +#define TARGET_NR_preadv333 +#define TARGET_NR_pwritev 334 +#define TARGET_NR_rt_tgsigqueueinfo 335 +#define TARGET_NR_perf_event_open 336 +#define TARGET_NR_recvmmsg 337 +#define TARGET_NR_fanotify_init 338 +#define TARGET_NR_fanotify_mark 339 +#define TARGET_NR_prlimit64 340 +#define TARGET_NR_name_to_handle_at 341 +#define TARGET_NR_open_by_handle_at 342 +#define TARGET_NR_clock_adjtime 343 +#define TARGET_NR_syncfs344 diff --git a
[Qemu-devel] [PATCH 0/2] linux-user: Implement prlimit64
The main purpose of this patch series is to implement the prlimit64 syscall, which is what patch 2 does. Since prlimit64 is a new syscall number, I had to add it to the syscall number definitions. Patch 1 is therefore a comprehensive update of the syscall number tables for all archs to match the mainline 2.6.39.2 defined syscalls. The exception is that I haven't touched the unicore32 syscall_nr.h, because as far as I can tell it doesn't match the kernel's syscall numbers for that architecture at all... Peter Maydell (2): linux-user: Add syscall numbers from kernel 2.6.39.2 linux-user: Implement prlimit64 syscall linux-user/alpha/syscall_nr.h | 23 ++- linux-user/arm/syscall_nr.h| 13 +++ linux-user/cris/syscall_nr.h |2 + linux-user/i386/syscall_nr.h | 12 ++ linux-user/m68k/syscall_nr.h | 16 + linux-user/main.c | 27 ++ linux-user/microblaze/syscall_nr.h | 14 ++- linux-user/mips/syscall_nr.h | 13 +++ linux-user/mips64/syscall_nr.h | 13 +++ linux-user/mipsn32/syscall_nr.h| 14 +++ linux-user/ppc/syscall_nr.h| 30 + linux-user/s390x/syscall_nr.h | 13 +- linux-user/sh4/syscall_nr.h| 32 ++ linux-user/sparc/syscall_nr.h | 12 ++ linux-user/sparc64/syscall_nr.h| 12 ++ linux-user/syscall.c | 43 linux-user/syscall_defs.h |5 linux-user/x86_64/syscall_nr.h | 12 ++ 18 files changed, 301 insertions(+), 5 deletions(-) -- 1.7.4.1
[Qemu-devel] [PATCH 2/2] linux-user: Implement prlimit64 syscall
Implement the prlimit64 syscall. Signed-off-by: Peter Maydell --- linux-user/syscall.c | 43 +++ linux-user/syscall_defs.h |5 + 2 files changed, 48 insertions(+), 0 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 5cb27c7..2ec1c2b 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -550,6 +550,21 @@ _syscall5(int, sys_ppoll, struct pollfd *, fds, nfds_t, nfds, size_t, sigsetsize) #endif +#if defined(TARGET_NR_prlimit64) +#ifndef __NR_prlimit64 +# define __NR_prlimit64 -1 +#endif +#define __NR_sys_prlimit64 __NR_prlimit64 +/* The glibc rlimit structure may not be that used by the underlying syscall */ +struct host_rlimit64 { +uint64_t rlim_cur; +uint64_t rlim_max; +}; +_syscall4(int, sys_prlimit64, pid_t, pid, int, resource, + const struct host_rlimit64 *, new_limit, + struct host_rlimit64 *, old_limit) +#endif + extern int personality(int); extern int flock(int, int); extern int setfsuid(int); @@ -7840,6 +7855,34 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, } #endif #endif +#ifdef TARGET_NR_prlimit64 +case TARGET_NR_prlimit64: +{ +/* args: pid, resource number, ptr to new rlimit, ptr to old rlimit */ +struct target_rlimit64 *target_rnew, *target_rold; +struct host_rlimit64 rnew, rold, *rnewp = 0; +if (arg3) { +if (!lock_user_struct(VERIFY_READ, target_rnew, arg3, 1)) { +goto efault; +} +rnew.rlim_cur = tswap64(target_rnew->rlim_cur); +rnew.rlim_max = tswap64(target_rnew->rlim_max); +unlock_user_struct(target_rnew, arg3, 0); +rnewp = &rnew; +} + +ret = get_errno(sys_prlimit64(arg1, arg2, rnewp, arg4 ? &rold : 0)); +if (!is_error(ret) && arg4) { +if (!lock_user_struct(VERIFY_WRITE, target_rold, arg4, 1)) { +goto efault; +} +target_rold->rlim_cur = tswap64(rold.rlim_cur); +target_rold->rlim_max = tswap64(rold.rlim_max); +unlock_user_struct(target_rold, arg4, 1); +} +break; +} +#endif default: unimplemented: gemu_log("qemu: Unsupported syscall: %d\n", num); diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index 04c268d..e2700eb 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -2280,3 +2280,8 @@ struct target_epoll_event { target_epoll_data_t data; }; #endif + +struct target_rlimit64 { +uint64_t rlim_cur; +uint64_t rlim_max; +}; -- 1.7.4.1
Re: [Qemu-devel] [PATCH] vnc: Fix compilation with --enable-vnc-png
On 06/27/2011 12:44 AM, Stefan Weil wrote: Am 27.06.2011 07:29, schrieb Stefan Weil: Commit f26e428da505709ec03b2ed2c9eb3db82b30bd7b fixed compilation with --enable-vnc-png, but broke it with --enable-vnc-png. should be with --enable-vnc-jpeg, but broke it with --enable-vnc-png. Please fix this detail before applying the patch. Applied. Thanks. Regards, Anthony Liguori Thanks, Stefan
[Qemu-devel] [Bug 799036] Re: NIC assignment order in command line make some NIC can't work
dmesg and lspci logs are attached as a tar package. There are many logs in it, please read README.txt first, which will tell you which log is in which case. ** Attachment added: "vtd-NIC-assignment-order-issue.tar" https://bugs.launchpad.net/qemu/+bug/799036/+attachment/2182799/+files/vtd-NIC-assignment-order-issue.tar -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/799036 Title: NIC assignment order in command line make some NIC can't work Status in QEMU: New Bug description: Environment: Host OS (ia32/ia32e/IA64):All Guest OS (ia32/ia32e/IA64):ia32e Guest OS Type (Linux/Windows):Linux kvm.git Commit:681fb677ace0754589792c92b8dbee9884d07158 qemu-kvm Commit:05f1737582ab6c075476bde931c5eafbc62a9349 Host Kernel Version:3.0.0-rc2+ Hardware: Westmere-EP platform Bug detailed description: -- When using qemu-system-x86_64 to create a linux guest with a 82586 NIC and a 82572EI NIC statically assigned, the two NIC's order in command line may make 82586 NIC can't work in guest. command1: qemu-system-x86_64 -m 1024 -smp 2 -device pci-assign,host=0e:00.1 -device pci-assign,host=0c:00.0 -net none -hda qcow-rhel6.img command2: qemu-system-x86_64 -m 1024 -smp 2 -device pci-assign,host=0c:00.0 -device pci-assign,host=0e:00.1 -net none -hda qcow-rhel6.img Using command1 to create a guest, both two NICs works well in guest. While using command2 to create a guest, 82576(kawela) NIC 0c:00.0 cannot get IP in guest. BDF 0c:00.0 is a 82576(kawela) NIC, while BDF 0e:00.1 is 82572EI NIC. The only difference of the two command lines is the order of NICs assignment. And only the 82576(kawela) NIC have this problem, the other one 82572EI always works well. And sriov VF doesn't have this issue. A VF and a 82576 PF assigned to a guest always work well. I don't know the order of NIC assignment in qemu-system-x86_64 will make this difference in guest. Maybe it's a qemu bug ? Reproduce steps: 1.pci-stub the two NIC 2.create a guest: qemu-system-x86_64 -m 1024 -smp 2 -device pci-assign,host=0c:00.0 -device pci-assign,host=0e:00.1 -net none -hda qcow-rhel6.img (0c:00.0 is a 82576 NIC, and 0e:00.1 is another NIC). Current result: 82576 PF and the other NIC in guest will work well regardless of what the order of assignment is. Expected result: To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/799036/+subscriptions
Re: [Qemu-devel] [RFC v2 00/20] Memory API
On 06/27/2011 06:59 PM, Michael S. Tsirkin wrote: > > >- bridges might also enable subtractive decoding > >(required for isa behind the bridge) > > What does that mean? subtractive decoding is a method of address decoding in which a device accepts all accesses not positively decoded by another agent. Okay, we implement that already via memory region priorities. -- error compiling committee.c: too many arguments to function
Re: [Qemu-devel] [PATCH 3/3] xen: implement unplug protocol in xen_platform
Am 27.06.2011 17:34, schrieb Stefano Stabellini: > On Mon, 27 Jun 2011, Kevin Wolf wrote: >> hw/ide/pci.h is just as internal as internal.h is. And even if you >> managed to access the same things without any IDE header file, I still >> think it's not the right level of abstraction because it relies on the >> implementation details of IDE. >> >> Just this line: pci_ide->bus[di->bus].ifs[di->unit].bs = NULL; Does this >> really look right to you to do anywhere outside IDE? >> >> I'm basically looking for the same as Michael who wanted to have network >> unplug handled through qdev, just that the IDE code doesn't support >> unplug yet. > > I understand. > > I created pci_piix3_xen_ide_init and moved the unplug code to > hw/ide/piix.c so that we don't have any internal knowledge of IDE code > in xen_platform.c any more, see below. > > One remaining problem is that the generic pci unplug function is not > what I need in this case so I have to setup my own; but I hope that in > general the changes are going in the right direction. Looks much better to me now. :-) Just a few comments inline: > diff --git a/hw/ide.h b/hw/ide.h > index 34d9394..a490cbb 100644 > --- a/hw/ide.h > +++ b/hw/ide.h > @@ -13,6 +13,7 @@ ISADevice *isa_ide_init(int iobase, int iobase2, int isairq, > /* ide-pci.c */ > void pci_cmd646_ide_init(PCIBus *bus, DriveInfo **hd_table, > int secondary_ide_enabled); > +PCIDevice *pci_piix3_xen_ide_init(PCIBus *bus, DriveInfo **hd_table, int > devfn); > PCIDevice *pci_piix3_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn); > PCIDevice *pci_piix4_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn); > void vt82c686b_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn); > diff --git a/hw/ide/piix.c b/hw/ide/piix.c > index c349644..8ae9ff0 100644 > --- a/hw/ide/piix.c > +++ b/hw/ide/piix.c > @@ -167,6 +167,41 @@ static int pci_piix4_ide_initfn(PCIDevice *dev) > return pci_piix_ide_initfn(d); > } > > +static int pci_piix3_xen_ide_unplug(DeviceState *dev) > +{ > +PCIDevice *pci_dev; > +PCIIDEState *pci_ide; > +DriveInfo *di; > +int i = 0; > + > +pci_dev = DO_UPCAST(PCIDevice, qdev, dev); > +pci_ide = DO_UPCAST(PCIIDEState, dev, pci_dev); > + > +for (; i < 3; i++) { > +di = drive_get_by_index(IF_IDE, i); > +if (di != NULL && di->bdrv != NULL && !di->bdrv->removable) { > +DeviceState *ds = bdrv_get_attached(di->bdrv); > +if (ds) > +bdrv_detach(di->bdrv, ds); Missing braces > +bdrv_close(di->bdrv); > +pci_ide->bus[di->bus].ifs[di->unit].bs = NULL; > +drive_put_ref(di); > +} > +} > +qdev_reset_all(&(pci_ide->dev.qdev)); > +return 0; > +} > + > +PCIDevice *pci_piix3_xen_ide_init(PCIBus *bus, DriveInfo **hd_table, int > devfn) > +{ > +PCIDevice *dev; > + > +dev = pci_create_simple(bus, devfn, "piix3-ide"); > +dev->qdev.info->unplug = pci_piix3_xen_ide_unplug; Doesn't this modify the piix3-ide definition? Shouldn't matter in practice because you can't have additional IDE controllers anyway, but maybe worth a comment stating this. The other, probably cleaner way of doing it would be adding another PCIDeviceInfo for xen-ide. Kevin
[Qemu-devel] [PATCH] e1000: Handle IO Port.
This patch introduces the two IOPorts on e1000, IOADDR and IODATA. The IOADDR is used to specify which register we want to access when we read or write on IODATA. This patch fixes some weird behavior that I see when I use e1000 with QEMU/Xen, the guest memory can be corrupted by this NIC because it will write on memory that it doesn't own anymore after a reset. It's because the kernel Linux use the IOPort to reset the network card instead of the MMIO. Signed-off-by: Anthony PERARD --- hw/e1000.c | 92 ++- 1 files changed, 84 insertions(+), 8 deletions(-) diff --git a/hw/e1000.c b/hw/e1000.c index f160bfc..9961f1a 100644 --- a/hw/e1000.c +++ b/hw/e1000.c @@ -58,6 +58,9 @@ static int debugflags = DBGBIT(TXERR) | DBGBIT(GENERAL); #define PNPMMIO_SIZE 0x2 #define MIN_BUF_SIZE 60 /* Min. octets in an ethernet frame sans FCS */ +#define REG_IOADDR 0x0 +#define REG_IODATA 0x4 + /* * HW models: * E1000_DEV_ID_82540EM works with Windows and Linux @@ -83,6 +86,8 @@ typedef struct E1000State_st { NICState *nic; NICConf conf; int mmio_index; +int ioport_base; +uint32_t ioport_reg[2]; uint32_t mac_reg[0x8000]; uint16_t phy_reg[0x20]; @@ -150,13 +155,7 @@ static const char phy_regcap[0x20] = { [PHY_ID2] = PHY_R, [M88E1000_PHY_SPEC_STATUS] = PHY_R }; -static void -ioport_map(PCIDevice *pci_dev, int region_num, pcibus_t addr, - pcibus_t size, int type) -{ -DBGOUT(IO, "e1000_ioport_map addr=0x%04"FMT_PCIBUS - " size=0x%08"FMT_PCIBUS"\n", addr, size); -} +static void e1000_reset(void *opaque); static void set_interrupt_cause(E1000State *s, int index, uint32_t val) @@ -202,6 +201,11 @@ rxbufsize(uint32_t v) static void set_ctrl(E1000State *s, int index, uint32_t val) { +DBGOUT(IO, "set ctrl = %08x\n", val); +if (val & E1000_CTRL_RST) { +s->mac_reg[CTRL] = val; +e1000_reset(s); +} /* RST is self clearing */ s->mac_reg[CTRL] = val & ~E1000_CTRL_RST; } @@ -905,6 +909,53 @@ static void (*macreg_writeops[])(E1000State *, int, uint32_t) = { enum { NWRITEOPS = ARRAY_SIZE(macreg_writeops) }; static void +e1000_ioport_writel(void *opaque, uint32_t addr, uint32_t val) +{ +E1000State *s = opaque; + +if (addr == s->ioport_base + REG_IOADDR) { +DBGOUT(IO, "e1000_ioport_writel write base: 0x%04x\n", val); +s->ioport_reg[REG_IOADDR] = val & 0xf; +} else if (addr == (s->ioport_base + REG_IODATA)) { +unsigned int index = (s->ioport_reg[REG_IOADDR] & 0x1) >> 2; + +DBGOUT(IO, "e1000_ioport_writel %x: 0x%04x\n", index, val); + +if (index < NWRITEOPS && macreg_writeops[index]) { +macreg_writeops[index](s, index, val); +} else if (index < NREADOPS && macreg_readops[index]) { +DBGOUT(IO, "e1000_ioport_writel RO %x: 0x%04x\n", index << 2, val); +} else { +DBGOUT(UNKNOWN, "IO unknown write index=0x%08x,val=0x%08x\n", + index, val); +} +} else { +DBGOUT(UNKNOWN, "IO unknown write addr=0x%08x,val=0x%08x\n", + addr, val); +} +} + +static uint32_t +e1000_ioport_readl(void *opaque, uint32_t addr) +{ +E1000State *s = opaque; + +if (addr == s->ioport_base + REG_IOADDR) { +return s->ioport_reg[REG_IOADDR] & 0xf; +} else if (addr == (s->ioport_base + REG_IODATA)) { +unsigned int index = (s->ioport_reg[REG_IOADDR] & 0x1) >> 2; + +if (index < NREADOPS && macreg_readops[index]) { +return macreg_readops[index](s, index); +} +DBGOUT(UNKNOWN, "IO unknown read addr=0x%08x\n", index<<2); +} else { +DBGOUT(UNKNOWN, "IO unknown read addr=0x%08x\n", addr); +} +return 0; +} + +static void e1000_mmio_writel(void *opaque, target_phys_addr_t addr, uint32_t val) { E1000State *s = opaque; @@ -1083,6 +1134,30 @@ static const uint32_t mac_reg_init[] = { /* PCI interface */ +static void +e1000_ioport_map(PCIDevice *pci_dev, int region_num, pcibus_t addr, + pcibus_t size, int type) +{ +E1000State *d = DO_UPCAST(E1000State, dev, pci_dev); + +DBGOUT(IO, "e1000_ioport_map addr=0x%04" FMT_PCIBUS + " size=0x%08" FMT_PCIBUS "\n", addr, size); + +d->ioport_base = addr; + +/* Writes that are less than 32 bits are ignored on IOADDR. + * For the Flash access, a write can be less than 32 bits for + * IODATA register, but is not handled. + */ + +register_ioport_read(addr, size, 1, e1000_ioport_readl, d); + +register_ioport_read(addr, size, 2, e1000_ioport_readl, d); + +register_ioport_write(addr, size, 4, e1000_ioport_writel, d); +register_ioport_read(addr, size, 4, e1000_ioport_readl, d); +} + static CPUWriteMemoryFunc * const e1000_mmio_write[] = { e1000_mmio_writeb, e1000_mmio_writew, e1000_mmio_writel }; @@ -1137,6 +1212,7 @@ stat
Re: [Qemu-devel] [RFC v2 00/20] Memory API
On 06/27/2011 08:21 AM, Avi Kivity wrote: As expected, this is taking longer than expected, so I'm releasing something less complete than I'd have liked. Not even all of the PC machine is converted, but the difficult parts are (cirrus). It appears to work well. The major change compared to v1 is the introduction of memory_region_init_alias(), which defines a memory region in terms of another. With the current API, the ability to alias is provided by address arithmetic on ram_addr_t: ram_addr = qemu_ram_alloc(...); cpu_register_physical_memory(..., ram_addr, size, ...); /* alias: */ cpu_register_physical_memory(..., ram_addr + offset, another_size, ...); With the new API, you have to create an alias: memory_region_init_ram(&mem, ...); memory_region_register_subregion(...,&mem); /* alias: */ memory_region_init_alias(&alias, ...,&mem, offset, another_size); memory_region_register_subregion(...,&alias); What's the rationale for explicit aliasing verses registering the same region to two different address spaces? Regards, Anthony Liguori
Re: [Qemu-devel] [PATCH] Add e500 instructions dcblc, dcbtls and dcbtstl as no-op
On Mon, 27 Jun 2011 15:15:55 +0200 Fabien Chouteau wrote: > +/* dcbtls */ > +static void gen_dcbtls(DisasContext *ctx) > +{ > +/* interpreted as no-op */ > +} > + > +/* dcbtstls */ > +static void gen_dcbtstls(DisasContext *ctx) > +{ > +/* interpreted as no-op */ > +} Set L1CSR0[CUL] (unable to lock)? -Scott
[Qemu-devel] [Bug 802588] [NEW] Latest GIT version fails to compile on Linux - setjmp.h problem
Public bug reported: Git version: f26e428da505709ec03b2ed2c9eb3db82b30bd7b Gcc: 4.6.1 Host: Debinan/x86_64 Fails to compile at In file included from /usr/include/png.h:518:0, from ui/vnc-enc-tight.c:37: /usr/include/pngconf.h: At top level: /usr/include/pngconf.h:371:21: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘.’ token /usr/include/pngconf.h:372:12: error: unknown type name ‘__dont__’ /usr/include/pngconf.h:372:29: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘it’ /usr/include/pngconf.h:372:29: error: unknown type name ‘it’ Looking at pngconf.h around line 370 gives the reason for the compilation failure: # ifdef _SETJMP_H /* If you encounter a compiler error here, see the explanation * near the end of INSTALL. */ __pngconf.h__ in libpng already includes setjmp.h; __dont__ include it again.; # endif ** Affects: qemu Importance: Undecided Status: New -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/802588 Title: Latest GIT version fails to compile on Linux - setjmp.h problem Status in QEMU: New Bug description: Git version: f26e428da505709ec03b2ed2c9eb3db82b30bd7b Gcc: 4.6.1 Host: Debinan/x86_64 Fails to compile at In file included from /usr/include/png.h:518:0, from ui/vnc-enc-tight.c:37: /usr/include/pngconf.h: At top level: /usr/include/pngconf.h:371:21: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘.’ token /usr/include/pngconf.h:372:12: error: unknown type name ‘__dont__’ /usr/include/pngconf.h:372:29: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘it’ /usr/include/pngconf.h:372:29: error: unknown type name ‘it’ Looking at pngconf.h around line 370 gives the reason for the compilation failure: # ifdef _SETJMP_H /* If you encounter a compiler error here, see the explanation * near the end of INSTALL. */ __pngconf.h__ in libpng already includes setjmp.h; __dont__ include it again.; # endif To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/802588/+subscriptions
Re: [Qemu-devel] IO errors in guest caused by LTP dio test
On Mon, Jun 27, 2011 at 05:59:41PM +0200, Kevin Wolf wrote: > Am 23.06.2011 01:36, schrieb Andi Kleen: > > > > Running LTP testcases/kernel/io/direct_io/test_dma_thread_diotest7 > > causes IO errors in the guest. There are no IO errors on the host. > > > > Kernel Linux 3.0.0-rc* > > Using a standard emulated IDE -hda image. > > Couldn't reproduce this in a quick test with a random guest I had > available. What is your complete qemu command line? Is the problem new -m 1500M -smp 2 \ -hda ~/qemu/suse-11.1-64.img\ -kernel arch/x86/boot/bzImage -append "root=/dev/sda1 debug $EXTRA" "$@" Could it be related to the image? suse11.3-64.img: Qemu Image, Format: Qcow , Version: 1 , Disk Size could be: 83886080 * 256 bytes > with the 3.0 RCs or does it also happen with kernels that my existing > guests are likely to have in use - say, the F15 kernel? It happened on older kernels too. > > I guess with virtio-blk you don't see the problems? Will try later. -Andi -- a...@linux.intel.com -- Speaking for myself only.
Re: [Qemu-devel] [PATCH] Make SLIRP Ethernet packets size to 64 bytes minimum
On 27/06/2011 17:39, Stefan Hajnoczi wrote: > On Mon, Jun 27, 2011 at 3:23 PM, Fabien Chouteau wrote: >> On 27/06/2011 15:50, Stefan Hajnoczi wrote: >>> On Mon, Jun 27, 2011 at 1:41 PM, Fabien Chouteau >>> wrote: Signed-off-by: Fabien Chouteau --- slirp/slirp.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) >>> >>> Any particular bug that this fixes? >>> >>> There have been 64 byte minimum padding patches to several emulated >>> NICs. There has also been discussion about where the best place to do >>> this is. Why is this patch necessary? >>> >> >> This patch is necessary because some NICs are configured to drop short >> frames, >> therefore the OS will not receive some of the packets generated by Qemu. >> >> There's a first patch to fix this issue: >> http://git.savannah.gnu.org/cgit/qemu.git/commit/?id=dbf3c4b4baceb91eb64d09f787cbe92d65188813 >> >> My patch fixes two other sources of short frames. > > Thanks for the explanation. I stepped back from the discussion on > where the right place to fix this is last time around. Now I'm > wondering why do anything in slirp when the other sources (tap, ...) > aren't padding to 64 bytes? I think that packets generated by Qemu must follow RFC. For other sources, qemu should keep original size when possible and put padding otherwise. -- Fabien Chouteau
Re: [Qemu-devel] [PATCH 3/3] xen: implement unplug protocol in xen_platform
On Mon, 27 Jun 2011, Kevin Wolf wrote: > hw/ide/pci.h is just as internal as internal.h is. And even if you > managed to access the same things without any IDE header file, I still > think it's not the right level of abstraction because it relies on the > implementation details of IDE. > > Just this line: pci_ide->bus[di->bus].ifs[di->unit].bs = NULL; Does this > really look right to you to do anywhere outside IDE? > > I'm basically looking for the same as Michael who wanted to have network > unplug handled through qdev, just that the IDE code doesn't support > unplug yet. I understand. I created pci_piix3_xen_ide_init and moved the unplug code to hw/ide/piix.c so that we don't have any internal knowledge of IDE code in xen_platform.c any more, see below. One remaining problem is that the generic pci unplug function is not what I need in this case so I have to setup my own; but I hope that in general the changes are going in the right direction. --- diff --git a/hw/ide.h b/hw/ide.h index 34d9394..a490cbb 100644 --- a/hw/ide.h +++ b/hw/ide.h @@ -13,6 +13,7 @@ ISADevice *isa_ide_init(int iobase, int iobase2, int isairq, /* ide-pci.c */ void pci_cmd646_ide_init(PCIBus *bus, DriveInfo **hd_table, int secondary_ide_enabled); +PCIDevice *pci_piix3_xen_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn); PCIDevice *pci_piix3_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn); PCIDevice *pci_piix4_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn); void vt82c686b_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn); diff --git a/hw/ide/piix.c b/hw/ide/piix.c index c349644..8ae9ff0 100644 --- a/hw/ide/piix.c +++ b/hw/ide/piix.c @@ -167,6 +167,41 @@ static int pci_piix4_ide_initfn(PCIDevice *dev) return pci_piix_ide_initfn(d); } +static int pci_piix3_xen_ide_unplug(DeviceState *dev) +{ +PCIDevice *pci_dev; +PCIIDEState *pci_ide; +DriveInfo *di; +int i = 0; + +pci_dev = DO_UPCAST(PCIDevice, qdev, dev); +pci_ide = DO_UPCAST(PCIIDEState, dev, pci_dev); + +for (; i < 3; i++) { +di = drive_get_by_index(IF_IDE, i); +if (di != NULL && di->bdrv != NULL && !di->bdrv->removable) { +DeviceState *ds = bdrv_get_attached(di->bdrv); +if (ds) +bdrv_detach(di->bdrv, ds); +bdrv_close(di->bdrv); +pci_ide->bus[di->bus].ifs[di->unit].bs = NULL; +drive_put_ref(di); +} +} +qdev_reset_all(&(pci_ide->dev.qdev)); +return 0; +} + +PCIDevice *pci_piix3_xen_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn) +{ +PCIDevice *dev; + +dev = pci_create_simple(bus, devfn, "piix3-ide"); +dev->qdev.info->unplug = pci_piix3_xen_ide_unplug; +pci_ide_create_devs(dev, hd_table); +return dev; +} + /* hd_table must contain 4 block drivers */ /* NOTE: for the PIIX3, the IRQs and IOports are hardcoded */ PCIDevice *pci_piix3_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn) diff --git a/hw/pc_piix.c b/hw/pc_piix.c index 8dbeb0c..b59adcc 100644 --- a/hw/pc_piix.c +++ b/hw/pc_piix.c @@ -155,7 +155,11 @@ static void pc_init1(ram_addr_t ram_size, ide_drive_get(hd, MAX_IDE_BUS); if (pci_enabled) { PCIDevice *dev; -dev = pci_piix3_ide_init(pci_bus, hd, piix3_devfn + 1); +if (xen_enabled()) { +dev = pci_piix3_xen_ide_init(pci_bus, hd, piix3_devfn + 1); +} else { +dev = pci_piix3_ide_init(pci_bus, hd, piix3_devfn + 1); +} idebus[0] = qdev_get_child_bus(&dev->qdev, "ide.0"); idebus[1] = qdev_get_child_bus(&dev->qdev, "ide.1"); } else { diff --git a/hw/xen_platform.c b/hw/xen_platform.c index b167eee..a271369 100644 --- a/hw/xen_platform.c +++ b/hw/xen_platform.c @@ -76,6 +76,35 @@ static void log_writeb(PCIXenPlatformState *s, char val) } /* Xen Platform, Fixed IOPort */ +#define UNPLUG_ALL_IDE_DISKS 1 +#define UNPLUG_ALL_NICS 2 +#define UNPLUG_AUX_IDE_DISKS 4 + +static void unplug_nic(PCIBus *b, PCIDevice *d) +{ +if (pci_get_word(d->config + PCI_CLASS_DEVICE) == +PCI_CLASS_NETWORK_ETHERNET) { +qdev_unplug(&(d->qdev)); +} +} + +static void pci_unplug_nics(PCIBus *bus) +{ +pci_for_each_device(bus, 0, unplug_nic); +} + +static void unplug_disks(PCIBus *b, PCIDevice *d) +{ +if (pci_get_word(d->config + PCI_CLASS_DEVICE) == +PCI_CLASS_STORAGE_IDE) { +qdev_unplug(&(d->qdev)); +} +} + +static void pci_unplug_disks(PCIBus *bus) +{ +pci_for_each_device(bus, 0, unplug_disks); +} static void platform_fixed_ioport_writew(void *opaque, uint32_t addr, uint32_t val) { @@ -83,10 +112,22 @@ static void platform_fixed_ioport_writew(void *opaque, uint32_t addr, uint32_t v switch (addr - XEN_PLATFORM_IOPORT) { case 0: -/* TODO: */ /* Unplug devices. Value is a bitmask of which devices to unplug, with bit 0 the IDE devices, bit 1 the network
Re: [Qemu-devel] [RFC v2 00/20] Memory API
On 06/27/2011 06:52 PM, Michael S. Tsirkin wrote: On Mon, Jun 27, 2011 at 06:13:03PM +0300, Avi Kivity wrote: > On 06/27/2011 04:21 PM, Avi Kivity wrote: > >As expected, this is taking longer than expected, so I'm releasing something > >less complete than I'd have liked. Not even all of the PC machine is > >converted, but the difficult parts are (cirrus). It appears to work well. > > > >The major change compared to v1 is the introduction of > >memory_region_init_alias(), which defines a memory region in terms of another. > >With the current API, the ability to alias is provided by address arithmetic > >on ram_addr_t: > > > >ram_addr = qemu_ram_alloc(...); > >cpu_register_physical_memory(..., ram_addr, size, ...); > >/* alias: */ > >cpu_register_physical_memory(..., ram_addr + offset, another_size, ...); > > > >With the new API, you have to create an alias: > > > >memory_region_init_ram(&mem, ...); > >memory_region_register_subregion(...,&mem); > >/* alias: */ > >memory_region_init_alias(&alias, ...,&mem, offset, another_size); > >memory_region_register_subregion(...,&alias); > > > >The patchset is somewhat churny. One of the reasons is that we move from a > >handle/pointer scheme in ram_addr_t to an object constructor/destructor scheme. > >Another is that region size becomes a property of a region instead of being > >maintained externally. Also, container memory regions must be passed around, > >though we don't do that as well as we should. > > > >Todo: > >- eliminate calls to get_system_memory() (where we ignore the bus hierarchy) > >- add PCI APIs for the VGA window > >- support the PIO address space using the memory API (allowing simplified > > PCI BAR registration) > >- convert 440FX > >- convert everything else > > Michael, I'm looking at the pci bridge code, and it basically does > the same thing - clip each BAR to the intersection of the decode > window of all bridges it hides behind. > > How does a PCI bridge behave wrt VGA? is it a separate control? If > so I probably need to implement generalized clipping (i.e. decode > between 0xa-0xc or between 0xc000-0xf000). Per spec, VGA is special: - bridges have VGA enable bit The VGA Enable bit in the Bridge Control register (see Section 3.2.5.18) is used to control response by the bridge to both the VGA frame buffer addresses and to the VGA register addresses. When a VGA compatible device is located downstream of a PCI-to-PCI bridge, the VGA Enable bit must be set. When set, the bridge will positively decode and forward memory accesses to VGA frame buffer addresses and I/O accesses to VGA registers from the primary to secondary interface and block forwarding of these same accesses from the secondary to primary interface (see Section 4.5.1). VGA memory addresses: 0A h through 0B h VGA I/O addresses (including ISA aliases address - AD[15::10] are not decoded): AD[9::0] = 3B0h through 3BBh and 3C0h through 3DFh The bridge does not decode or forward VGA BIOS memory addresses when the VGA Enable bit is set. ROM code provided by PCI compatible devices may be mapped to any address in PCI memory address space via the Expansion ROM Base Address register in the device's configuration header and must be copied to system memory before execution. Okay, looks like generalized clipping is needed. It's nice anyway and guarantees me a job for life as maintainer of memory.c. - bridges might also enable subtractive decoding (required for isa behind the bridge) What does that mean? -- error compiling committee.c: too many arguments to function
[Qemu-devel] [PATCHv2 3/4] libcacard: introduce NEXT_TOKEN macro
vcard_emul_options now has repetitive code to read the current token and advance to the next. After the previous changes, this repetitive code can be moved in a NEXT_TOKEN macro to avoid having this code duplicated. Signed-off-by: Christophe Fergeau --- libcacard/vcard_emul_nss.c | 71 +++- 1 files changed, 24 insertions(+), 47 deletions(-) diff --git a/libcacard/vcard_emul_nss.c b/libcacard/vcard_emul_nss.c index 9271f58..2a20bd6 100644 --- a/libcacard/vcard_emul_nss.c +++ b/libcacard/vcard_emul_nss.c @@ -975,6 +975,26 @@ find_blank(const char *str) static VCardEmulOptions options; #define READER_STEP 4 +/* Expects "args" to be at the beginning of a token (ie right after the ',' + * ending the previous token), and puts the next token start in "token", + * and its length in "token_length". "token" will not be nul-terminated. + * After calling the macro, "args" will be advanced to the beginning of + * the next token. + * This macro may call continue or break. + */ +#define NEXT_TOKEN(token) \ +(token) = args; \ +args = strpbrk(args, ",)"); \ +if (*args == 0) { \ +break; \ +} \ +if (*args == ')') { \ +args++; \ +continue; \ +} \ +(token##_length) = args - (token); \ +args = strip(args+1); + VCardEmulOptions * vcard_emul_options(const char *args) { @@ -1010,58 +1030,15 @@ vcard_emul_options(const char *args) } args = strip(args+1); -name = args; -args = strpbrk(args, ",)"); -if (*args == 0) { -break; -} -if (*args == ')') { -args++; -continue; -} -name_length = args - name; -args = strip(args+1); - -vname = args; -args = strpbrk(args, ",)"); -if (*args == 0) { -break; -} -if (*args == ')') { -args++; -continue; -} -vname_length = args - vname; -args = strip(args+1); - -type_params = args; -args = strpbrk(args, ",)"); -if (*args == 0) { -break; -} -if (*args == ')') { -args++; -continue; -} -type_params_length = args - type_params; -args = strip(args+1); - +NEXT_TOKEN(name) +NEXT_TOKEN(vname) +NEXT_TOKEN(type_params) type_params_length = MIN(type_params_length, sizeof(type_str)-1); strncpy(type_str, type_params, type_params_length); type_str[type_params_length] = 0; type = vcard_emul_type_from_string(type_str); -type_params = args; -args = strpbrk(args, ",)"); -if (*args == 0) { -break; -} -if (*args == ')') { -args++; -continue; -} -type_params_length = args - type_params; -args = strip(args+1); +NEXT_TOKEN(type_params) if (*args == 0) { break; -- 1.7.5.4
Re: [Qemu-devel] [RFC v2 00/20] Memory API
On Mon, Jun 27, 2011 at 06:54:05PM +0300, Avi Kivity wrote: > On 06/27/2011 06:52 PM, Michael S. Tsirkin wrote: > >On Mon, Jun 27, 2011 at 06:13:03PM +0300, Avi Kivity wrote: > >> On 06/27/2011 04:21 PM, Avi Kivity wrote: > >> >As expected, this is taking longer than expected, so I'm releasing > >> something > >> >less complete than I'd have liked. Not even all of the PC machine is > >> >converted, but the difficult parts are (cirrus). It appears to work > >> well. > >> > > >> >The major change compared to v1 is the introduction of > >> >memory_region_init_alias(), which defines a memory region in terms of > >> another. > >> >With the current API, the ability to alias is provided by address > >> arithmetic > >> >on ram_addr_t: > >> > > >> >ram_addr = qemu_ram_alloc(...); > >> >cpu_register_physical_memory(..., ram_addr, size, ...); > >> >/* alias: */ > >> >cpu_register_physical_memory(..., ram_addr + offset, another_size, > >> ...); > >> > > >> >With the new API, you have to create an alias: > >> > > >> >memory_region_init_ram(&mem, ...); > >> >memory_region_register_subregion(...,&mem); > >> >/* alias: */ > >> >memory_region_init_alias(&alias, ...,&mem, offset, another_size); > >> >memory_region_register_subregion(...,&alias); > >> > > >> >The patchset is somewhat churny. One of the reasons is that we move > >> from a > >> >handle/pointer scheme in ram_addr_t to an object constructor/destructor > >> scheme. > >> >Another is that region size becomes a property of a region instead of > >> being > >> >maintained externally. Also, container memory regions must be passed > >> around, > >> >though we don't do that as well as we should. > >> > > >> >Todo: > >> >- eliminate calls to get_system_memory() (where we ignore the bus > >> hierarchy) > >> >- add PCI APIs for the VGA window > >> >- support the PIO address space using the memory API (allowing > >> simplified > >> > PCI BAR registration) > >> >- convert 440FX > >> >- convert everything else > >> > >> Michael, I'm looking at the pci bridge code, and it basically does > >> the same thing - clip each BAR to the intersection of the decode > >> window of all bridges it hides behind. > >> > >> How does a PCI bridge behave wrt VGA? is it a separate control? If > >> so I probably need to implement generalized clipping (i.e. decode > >> between 0xa-0xc or between 0xc000-0xf000). > > > >Per spec, VGA is special: > >- bridges have VGA enable bit > > > >The VGA Enable bit in the Bridge Control register (see Section 3.2.5.18) > >is used to control response by the bridge to both the VGA frame buffer > >addresses and to the VGA register addresses. When a VGA compatible > >device is located downstream of a PCI-to-PCI bridge, the VGA Enable bit > >must be set. When set, the bridge will positively decode and forward > >memory accesses to VGA frame buffer addresses and I/O accesses to VGA > >registers from the primary to secondary interface and block forwarding > >of these same accesses from the secondary to primary interface (see > >Section 4.5.1). > >VGA memory addresses: > >0A h through 0B h > >VGA I/O addresses (including ISA aliases address - AD[15::10] are not > >decoded): > >AD[9::0] = 3B0h through 3BBh and 3C0h through 3DFh > >The bridge does not decode or forward VGA BIOS memory addresses when the > >VGA Enable bit is set. ROM code provided by PCI compatible devices may > >be mapped to any address in PCI memory address space via the Expansion > >ROM Base Address register in the device's configuration header and must > >be copied to system memory before execution. > > > > Okay, looks like generalized clipping is needed. It's nice anyway > and guarantees me a job for life as maintainer of memory.c. > > > >- bridges might also enable subtractive decoding > > (required for isa behind the bridge) > > What does that mean? subtractive decoding is a method of address decoding in which a device accepts all accesses not positively decoded by another agent. > -- > error compiling committee.c: too many arguments to function
[Qemu-devel] [PATCHv2 1/4] libcacard: s/strip(args++)/strip(args+1)
vcard_emul_options used args = strip(args++) a few times, which was not returning the expected result since the rest of the code expected args to be increased by at least 1, which is not the case if *args is not a blank space when this function is called. Replace these calls by "strip(args+1)" which will do what we expect. Signed-off-by: Christophe Fergeau --- libcacard/vcard_emul_nss.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libcacard/vcard_emul_nss.c b/libcacard/vcard_emul_nss.c index f3db657..184252f 100644 --- a/libcacard/vcard_emul_nss.c +++ b/libcacard/vcard_emul_nss.c @@ -1041,7 +1041,7 @@ vcard_emul_options(const char *args) args++; continue; } -args = strip(args++); +args = strip(args+1); type_params = args; args = strpbrk(args + 1, ",)"); if (*args == 0) { @@ -1052,7 +1052,7 @@ vcard_emul_options(const char *args) continue; } type_params_length = args - name; -args = strip(args++); +args = strip(args+1); if (*args == 0) { break; } -- 1.7.5.4
Re: [Qemu-devel] [PATCH] Make SLIRP Ethernet packets size to 64 bytes minimum
On Mon, Jun 27, 2011 at 3:23 PM, Fabien Chouteau wrote: > On 27/06/2011 15:50, Stefan Hajnoczi wrote: >> On Mon, Jun 27, 2011 at 1:41 PM, Fabien Chouteau >> wrote: >>> >>> Signed-off-by: Fabien Chouteau >>> --- >>> slirp/slirp.c | 4 ++-- >>> 1 files changed, 2 insertions(+), 2 deletions(-) >> >> Any particular bug that this fixes? >> >> There have been 64 byte minimum padding patches to several emulated >> NICs. There has also been discussion about where the best place to do >> this is. Why is this patch necessary? >> > > This patch is necessary because some NICs are configured to drop short frames, > therefore the OS will not receive some of the packets generated by Qemu. > > There's a first patch to fix this issue: > http://git.savannah.gnu.org/cgit/qemu.git/commit/?id=dbf3c4b4baceb91eb64d09f787cbe92d65188813 > > My patch fixes two other sources of short frames. Thanks for the explanation. I stepped back from the discussion on where the right place to fix this is last time around. Now I'm wondering why do anything in slirp when the other sources (tap, ...) aren't padding to 64 bytes? Stefan
Re: [Qemu-devel] IO errors in guest caused by LTP dio test
Am 23.06.2011 01:36, schrieb Andi Kleen: > > Running LTP testcases/kernel/io/direct_io/test_dma_thread_diotest7 > causes IO errors in the guest. There are no IO errors on the host. > > Kernel Linux 3.0.0-rc* > Using a standard emulated IDE -hda image. Couldn't reproduce this in a quick test with a random guest I had available. What is your complete qemu command line? Is the problem new with the 3.0 RCs or does it also happen with kernels that my existing guests are likely to have in use - say, the F15 kernel? I guess with virtio-blk you don't see the problems? Kevin
[Qemu-devel] [PATCHv2 0/4] libcacard fixes
Hey, Alon asked me to split the parsing patches to make the review easier, to here they are. Changes since v1: - split first patch into 3 patches, v1 2/2 is unchanged Christophe Fergeau (4): libcacard: s/strip(args++)/strip(args+1) libcacard: fix soft=... parsing in vcard_emul_options libcacard: introduce NEXT_TOKEN macro libcacard: replace copy_string with strndup libcacard/vcard_emul_nss.c | 113 +-- 1 files changed, 45 insertions(+), 68 deletions(-) -- 1.7.5.4
[Qemu-devel] [PATCHv2 4/4] libcacard: replace copy_string with strndup
copy_string reimplements strndup, this commit removes it and replaces all copy_string uses with strndup. Signed-off-by: Christophe Fergeau --- libcacard/vcard_emul_nss.c | 23 ++- 1 files changed, 6 insertions(+), 17 deletions(-) diff --git a/libcacard/vcard_emul_nss.c b/libcacard/vcard_emul_nss.c index 2a20bd6..de324ba 100644 --- a/libcacard/vcard_emul_nss.c +++ b/libcacard/vcard_emul_nss.c @@ -925,17 +925,6 @@ vcard_emul_replay_insertion_events(void) /* * Silly little functions to help parsing our argument string */ -static char * -copy_string(const char *str, int str_len) -{ -char *new_str; - -new_str = qemu_malloc(str_len+1); -memcpy(new_str, str, str_len); -new_str[str_len] = 0; -return new_str; -} - static int count_tokens(const char *str, char token, char token_end) { @@ -1054,18 +1043,18 @@ vcard_emul_options(const char *args) } opts->vreader = vreaderOpt; vreaderOpt = &vreaderOpt[opts->vreader_count]; -vreaderOpt->name = copy_string(name, name_length); -vreaderOpt->vname = copy_string(vname, vname_length); +vreaderOpt->name = qemu_strndup(name, name_length); +vreaderOpt->vname = qemu_strndup(vname, vname_length); vreaderOpt->card_type = type; vreaderOpt->type_params = -copy_string(type_params, type_params_length); +qemu_strndup(type_params, type_params_length); count = count_tokens(args, ',', ')') + 1; vreaderOpt->cert_count = count; vreaderOpt->cert_name = (char **)qemu_malloc(count*sizeof(char *)); for (i = 0; i < count; i++) { const char *cert = args; args = strpbrk(args, ",)"); -vreaderOpt->cert_name[i] = copy_string(cert, args - cert); +vreaderOpt->cert_name[i] = qemu_strndup(cert, args - cert); args = strip(args+1); } if (*args == ')') { @@ -1092,7 +1081,7 @@ vcard_emul_options(const char *args) args = strip(args+10); params = args; args = find_blank(args); -opts->hw_type_params = copy_string(params, args-params); +opts->hw_type_params = qemu_strndup(params, args-params); /* db="/data/base/path" */ } else if (strncmp(args, "db=", 3) == 0) { const char *db; @@ -1103,7 +1092,7 @@ vcard_emul_options(const char *args) args++; db = args; args = strpbrk(args, "\"\n"); -opts->nss_db = copy_string(db, args-db); +opts->nss_db = qemu_strndup(db, args-db); if (*args != 0) { args++; } -- 1.7.5.4
Re: [Qemu-devel] [RFC v2 00/20] Memory API
On Mon, Jun 27, 2011 at 06:13:03PM +0300, Avi Kivity wrote: > On 06/27/2011 04:21 PM, Avi Kivity wrote: > >As expected, this is taking longer than expected, so I'm releasing something > >less complete than I'd have liked. Not even all of the PC machine is > >converted, but the difficult parts are (cirrus). It appears to work well. > > > >The major change compared to v1 is the introduction of > >memory_region_init_alias(), which defines a memory region in terms of > >another. > >With the current API, the ability to alias is provided by address arithmetic > >on ram_addr_t: > > > > ram_addr = qemu_ram_alloc(...); > > cpu_register_physical_memory(..., ram_addr, size, ...); > > /* alias: */ > > cpu_register_physical_memory(..., ram_addr + offset, another_size, ...); > > > >With the new API, you have to create an alias: > > > > memory_region_init_ram(&mem, ...); > > memory_region_register_subregion(...,&mem); > > /* alias: */ > > memory_region_init_alias(&alias, ...,&mem, offset, another_size); > > memory_region_register_subregion(...,&alias); > > > >The patchset is somewhat churny. One of the reasons is that we move from a > >handle/pointer scheme in ram_addr_t to an object constructor/destructor > >scheme. > >Another is that region size becomes a property of a region instead of being > >maintained externally. Also, container memory regions must be passed around, > >though we don't do that as well as we should. > > > >Todo: > > - eliminate calls to get_system_memory() (where we ignore the bus > > hierarchy) > > - add PCI APIs for the VGA window > > - support the PIO address space using the memory API (allowing simplified > > PCI BAR registration) > > - convert 440FX > > - convert everything else > > Michael, I'm looking at the pci bridge code, and it basically does > the same thing - clip each BAR to the intersection of the decode > window of all bridges it hides behind. > > How does a PCI bridge behave wrt VGA? is it a separate control? If > so I probably need to implement generalized clipping (i.e. decode > between 0xa-0xc or between 0xc000-0xf000). Per spec, VGA is special: - bridges have VGA enable bit The VGA Enable bit in the Bridge Control register (see Section 3.2.5.18) is used to control response by the bridge to both the VGA frame buffer addresses and to the VGA register addresses. When a VGA compatible device is located downstream of a PCI-to-PCI bridge, the VGA Enable bit must be set. When set, the bridge will positively decode and forward memory accesses to VGA frame buffer addresses and I/O accesses to VGA registers from the primary to secondary interface and block forwarding of these same accesses from the secondary to primary interface (see Section 4.5.1). VGA memory addresses: 0A h through 0B h VGA I/O addresses (including ISA aliases address - AD[15::10] are not decoded): AD[9::0] = 3B0h through 3BBh and 3C0h through 3DFh The bridge does not decode or forward VGA BIOS memory addresses when the VGA Enable bit is set. ROM code provided by PCI compatible devices may be mapped to any address in PCI memory address space via the Expansion ROM Base Address register in the device's configuration header and must be copied to system memory before execution. - bridges might also enable subtractive decoding (required for isa behind the bridge) Both are currently unimplemented. -- MST
[Qemu-devel] [PATCHv2 2/4] libcacard: fix soft=... parsing in vcard_emul_options
The previous parser had copy and paste errors when computing vname_length and type_params_length, "name" was used instead of respectively vname and type_params. This led to length that could be bigger than the input string, and to access out of the array bounds when trying to copy these strings. valgrind rightfully complained about this. It also didn't handle empty fields correctly, Signed-off-by: Christophe Fergeau --- libcacard/vcard_emul_nss.c | 45 +++ 1 files changed, 28 insertions(+), 17 deletions(-) diff --git a/libcacard/vcard_emul_nss.c b/libcacard/vcard_emul_nss.c index 184252f..9271f58 100644 --- a/libcacard/vcard_emul_nss.c +++ b/libcacard/vcard_emul_nss.c @@ -980,8 +980,6 @@ vcard_emul_options(const char *args) { int reader_count = 0; VCardEmulOptions *opts; -char type_str[100]; -int type_len; /* Allow the future use of allocating the options structure on the fly */ memcpy(&options, &default_options, sizeof(options)); @@ -996,18 +994,24 @@ vcard_emul_options(const char *args) * cert_2,cert_3...) */ if (strncmp(args, "soft=", 5) == 0) { const char *name; +size_t name_length; const char *vname; +size_t vname_length; const char *type_params; +size_t type_params_length; +char type_str[100]; VCardEmulType type; -int name_length, vname_length, type_params_length, count, i; +int count, i; VirtualReaderOptions *vreaderOpt = NULL; args = strip(args + 5); if (*args != '(') { continue; } +args = strip(args+1); + name = args; -args = strpbrk(args + 1, ",)"); +args = strpbrk(args, ",)"); if (*args == 0) { break; } @@ -1015,10 +1019,11 @@ vcard_emul_options(const char *args) args++; continue; } +name_length = args - name; args = strip(args+1); -name_length = args - name - 2; + vname = args; -args = strpbrk(args + 1, ",)"); +args = strpbrk(args, ",)"); if (*args == 0) { break; } @@ -1026,13 +1031,10 @@ vcard_emul_options(const char *args) args++; continue; } -vname_length = args - name - 2; +vname_length = args - vname; args = strip(args+1); -type_len = strpbrk(args, ",)") - args; -assert(sizeof(type_str) > type_len); -strncpy(type_str, args, type_len); -type_str[type_len] = 0; -type = vcard_emul_type_from_string(type_str); + +type_params = args; args = strpbrk(args, ",)"); if (*args == 0) { break; @@ -1041,9 +1043,16 @@ vcard_emul_options(const char *args) args++; continue; } +type_params_length = args - type_params; args = strip(args+1); + +type_params_length = MIN(type_params_length, sizeof(type_str)-1); +strncpy(type_str, type_params, type_params_length); +type_str[type_params_length] = 0; +type = vcard_emul_type_from_string(type_str); + type_params = args; -args = strpbrk(args + 1, ",)"); +args = strpbrk(args, ",)"); if (*args == 0) { break; } @@ -1051,8 +1060,9 @@ vcard_emul_options(const char *args) args++; continue; } -type_params_length = args - name; +type_params_length = args - type_params; args = strip(args+1); + if (*args == 0) { break; } @@ -1072,13 +1082,14 @@ vcard_emul_options(const char *args) vreaderOpt->card_type = type; vreaderOpt->type_params = copy_string(type_params, type_params_length); -count = count_tokens(args, ',', ')'); +count = count_tokens(args, ',', ')') + 1; vreaderOpt->cert_count = count; vreaderOpt->cert_name = (char **)qemu_malloc(count*sizeof(char *)); for (i = 0; i < count; i++) { -const char *cert = args + 1; -args = strpbrk(args + 1, ",)"); +const char *cert = args; +args = strpbrk(args, ",)"); vreaderOpt->cert_name[i] = copy_string(cert, args - cert); +args = strip(args+1); } if (*args == ')') { args++; -- 1.7.5.4
Re: [Qemu-devel] [RFC v2 00/20] Memory API
On 06/27/2011 06:37 PM, Anthony Liguori wrote: On 06/27/2011 08:21 AM, Avi Kivity wrote: As expected, this is taking longer than expected, so I'm releasing something less complete than I'd have liked. Not even all of the PC machine is converted, but the difficult parts are (cirrus). It appears to work well. The major change compared to v1 is the introduction of memory_region_init_alias(), which defines a memory region in terms of another. With the current API, the ability to alias is provided by address arithmetic on ram_addr_t: ram_addr = qemu_ram_alloc(...); cpu_register_physical_memory(..., ram_addr, size, ...); /* alias: */ cpu_register_physical_memory(..., ram_addr + offset, another_size, ...); With the new API, you have to create an alias: memory_region_init_ram(&mem, ...); memory_region_register_subregion(...,&mem); /* alias: */ memory_region_init_alias(&alias, ...,&mem, offset, another_size); memory_region_register_subregion(...,&alias); What's the rationale for explicit aliasing verses registering the same region to two different address spaces? Two: - an alias is usually just a portion of the original region (vga windows; the two main RAM sections below and above 4GB); so we need an object to hold the differences - easier for the implementation (a MemoryRegion object can be in just one child list instead of many) While I can work around the implementation difficulties, there's no point since the alias is usually not identical to the origin, so we need a new object anyway. (ram_addr_t works around that by carrying the offset in the handle, and letting the caller carry the size). -- error compiling committee.c: too many arguments to function
Re: [Qemu-devel] [RFC v2 00/20] Memory API
On 06/27/2011 04:21 PM, Avi Kivity wrote: As expected, this is taking longer than expected, so I'm releasing something less complete than I'd have liked. Not even all of the PC machine is converted, but the difficult parts are (cirrus). It appears to work well. The major change compared to v1 is the introduction of memory_region_init_alias(), which defines a memory region in terms of another. With the current API, the ability to alias is provided by address arithmetic on ram_addr_t: ram_addr = qemu_ram_alloc(...); cpu_register_physical_memory(..., ram_addr, size, ...); /* alias: */ cpu_register_physical_memory(..., ram_addr + offset, another_size, ...); With the new API, you have to create an alias: memory_region_init_ram(&mem, ...); memory_region_register_subregion(...,&mem); /* alias: */ memory_region_init_alias(&alias, ...,&mem, offset, another_size); memory_region_register_subregion(...,&alias); The patchset is somewhat churny. One of the reasons is that we move from a handle/pointer scheme in ram_addr_t to an object constructor/destructor scheme. Another is that region size becomes a property of a region instead of being maintained externally. Also, container memory regions must be passed around, though we don't do that as well as we should. Todo: - eliminate calls to get_system_memory() (where we ignore the bus hierarchy) - add PCI APIs for the VGA window - support the PIO address space using the memory API (allowing simplified PCI BAR registration) - convert 440FX - convert everything else Michael, I'm looking at the pci bridge code, and it basically does the same thing - clip each BAR to the intersection of the decode window of all bridges it hides behind. How does a PCI bridge behave wrt VGA? is it a separate control? If so I probably need to implement generalized clipping (i.e. decode between 0xa-0xc or between 0xc000-0xf000). -- error compiling committee.c: too many arguments to function
[Qemu-devel] [PATCH v3] xen_disk: cope with missing xenstore "params" node
From: Stefano Stabellini When disk is a cdrom and the drive is empty the "params" node in xenstore might be missing completely: cope with it instead of segfaulting. Updated in v2: - actually removed the strchr(blkdev->params, ':') that caused the segfault; - free all the allocated strings from xenstore before returning; Updated in v3: - set blkdev fields to NULL after free'ing them. Signed-off-by: Stefano Stabellini --- hw/xen_disk.c | 34 +++--- 1 files changed, 27 insertions(+), 7 deletions(-) diff --git a/hw/xen_disk.c b/hw/xen_disk.c index 096d1c9..faaa065 100644 --- a/hw/xen_disk.c +++ b/hw/xen_disk.c @@ -616,12 +616,14 @@ static int blk_init(struct XenDevice *xendev) { struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev); int index, qflags, have_barriers, info = 0; -char *h; /* read xenstore entries */ if (blkdev->params == NULL) { +char *h = NULL; blkdev->params = xenstore_read_be_str(&blkdev->xendev, "params"); -h = strchr(blkdev->params, ':'); +if (blkdev->params != NULL) { +h = strchr(blkdev->params, ':'); +} if (h != NULL) { blkdev->fileproto = blkdev->params; blkdev->filename = h+1; @@ -649,7 +651,7 @@ static int blk_init(struct XenDevice *xendev) blkdev->mode == NULL || blkdev->type == NULL || blkdev->dev == NULL) { -return -1; +goto out_error; } /* read-only ? */ @@ -672,10 +674,15 @@ static int blk_init(struct XenDevice *xendev) /* setup via xenbus -> create new block driver instance */ xen_be_printf(&blkdev->xendev, 2, "create new bdrv (xenbus setup)\n"); blkdev->bs = bdrv_new(blkdev->dev); -if (bdrv_open(blkdev->bs, blkdev->filename, qflags, - bdrv_find_whitelisted_format(blkdev->fileproto)) != 0) { -bdrv_delete(blkdev->bs); -return -1; +if (blkdev->bs) { +if (bdrv_open(blkdev->bs, blkdev->filename, qflags, +bdrv_find_whitelisted_format(blkdev->fileproto)) != 0) { +bdrv_delete(blkdev->bs); +blkdev->bs = NULL; +} +} +if (!blkdev->bs) { +goto out_error; } } else { /* setup via qemu cmdline -> already setup for us */ @@ -704,6 +711,19 @@ static int blk_init(struct XenDevice *xendev) xenstore_write_be_int(&blkdev->xendev, "sectors", blkdev->file_size / blkdev->file_blk); return 0; + +out_error: +qemu_free(blkdev->params); +blkdev->params = NULL; +qemu_free(blkdev->mode); +blkdev->mode = NULL; +qemu_free(blkdev->type); +blkdev->type = NULL; +qemu_free(blkdev->dev); +blkdev->dev = NULL; +qemu_free(blkdev->devtype); +blkdev->devtype = NULL; +return -1; } static int blk_connect(struct XenDevice *xendev) -- 1.7.2.3
[Qemu-devel] [RFC PATCH v2] Specification for qcow2 version 3
This is the second draft for what I think could be added when we increase qcow2's version number to 3. This includes points that have been made by several people over the past few months. We're probably not going to implement this next week, but I think it's important to get discussions started early, so here it is. Changes implemented in this RFC: - Added compatible/incompatible/auto-clear feature bits plus an optional feature name table to allow useful error messages even if an older version doesn't know some feature at all. - Added a dirty flag which tells that the refcount may not be accurate ("QED mode"). This means that we can save writes to the refcount table with cache=writethrough, but isn't really useful otherwise since Qcow2Cache. - Configurable refcount width. If you don't want to use internal snapshots, make refcounts one bit and save cache space and I/O. - Added subclusters. This separate the COW size (one subcluster, I'm thinking of 64k default size here) from the allocation size (one cluster, 2M). Less fragmentation, less metadata, but still reasonable COW granularity. This also allows to preallocate clusters, but none of their subclusters. You can have an image that is like raw + COW metadata, and you can also preallocate metadata for images with backing files. - Zero cluster flags. This allows discard even with a backing file that doesn't contain zeros. It is also useful for copy-on-read/image streaming, as you'll want to keep sparseness without accessing the remote image for an unallocated cluster all the time. - Fixed internal snapshot metadata to use 64 bit VM state size. You can't save a snapshot of a VM with >= 4 GB RAM today. Possible future additions: - Add per-L2-table dirty flag to L1? - Add per-refcount-block full flag to refcount table? --- docs/specs/qcow2.txt | 135 +- 1 files changed, 112 insertions(+), 23 deletions(-) diff --git a/docs/specs/qcow2.txt b/docs/specs/qcow2.txt index 8fc3cb2..e4722bc 100644 --- a/docs/specs/qcow2.txt +++ b/docs/specs/qcow2.txt @@ -18,7 +18,7 @@ The first cluster of a qcow2 image contains the file header: QCOW magic string ("QFI\xfb") 4 - 7: version -Version number (only valid value is 2) +Version number (valid values are 2 and 3) 8 - 15: backing_file_offset Offset into the image file at which the backing file name @@ -67,12 +67,53 @@ The first cluster of a qcow2 image contains the file header: Offset into the image file at which the snapshot table starts. Must be aligned to a cluster boundary. +If the version is 3 or higher, the header has the following additional fields. +For version 2, the values are assumed to be zero, unless specified otherwise +in the description of a field. + + 72 - 79: incompatible_features +Bitmask of incompatible features. An implementation must +fail to open an image if an unknown bit is set. + +Bit 0: The reference counts in the image file may be +inaccurate. Implementations must check/rebuild +them if they rely on them. + +Bit 1: Enable subclusters. This affects the L2 table +format. + +Bits 2-31: Reserved (set to 0) + + 80 - 87: compatible_features +Bitmask of compatible features. An implementation can +safely ignore any unknown bits that are set. + +Bits 0-31: Reserved (set to 0) + + 88 - 95: autoclear_features +Bitmask of auto-clear features. An implementation may only +write to an image with unknown auto-clear features if it +clears the respective bits from this field first. + +Bits 0-31: Reserved (set to 0) + + 96 - 99: refcount_bits +Size of a reference count block entry in bits. For version 2 +images, the size is always assumed to be 16 bits. The size +must be a power of two. +[ TODO: Define order in sub-byte sizes ] + +100 - 104: header_length +Length of the header structure in bytes. For version 2 +images, the length is always assumed to be 72 bytes. + Directly after the image header, optional sections called header extensions can be stored. Each extension has a structure like the following: Byte 0 - 3: Header extension type: 0x - End of the header extension area 0xE2792ACA - Backing file format name +0x6803f857 - Feature name table other
Re: [Qemu-devel] [PATCH 08/10] cocoa: Revert dependency on VNC
On 06/14/11 03:22, Andreas Färber wrote: > In 821601ea5b02a68ada479731a4d3d07a9876632a (Make VNC support optional) > cocoa.o was moved from ui-obj-$(CONFIG_COCOA) to vnc-obj-$(CONFIG_COCOA), > adding a dependency on $(CONFIG_VNC). That must've been unintentional. > > Cc: Jes Sorensen > Cc: Anthony Liguori > Signed-off-by: Andreas Färber > --- > Makefile.objs |2 +- > 1 files changed, 1 insertions(+), 1 deletions(-) Looks like an error from my side, sorry about that. Patch looks good. Jes
[Qemu-devel] KVM call agenda for June 28
Hi Please send in any agenda items you are interested in covering. Later, Juan.
Re: [Qemu-devel] [PATCH 0/2] iothread improvements for Mac OS X
On 06/09/2011 01:10 PM, Paolo Bonzini wrote: These are two old patches that I never submitted because I didn't really think they were useful except as cleanups. Recently, however, Alex Graf mentioned some problems that Mac OS X has with iothread, and they sounded to me like they were related to these patches. And quite surprisingly, both of them were fixing bugs! Mac OS X still has problems with iothread according to Alex's testing (Linux times out in libata, and reactos likewise hangs early on I/O), but at least the patches fix deadlocks and keep a responsive UI. Paolo Bonzini (2): iothread: replace fair_mutex with a condition variable qemu-timer: change unix timer to dynticks cpus.c | 24 +--- qemu-timer.c | 40 2 files changed, 37 insertions(+), 27 deletions(-) Ping? 1/2 is probably somehow working around the sigmask problem fixed by Alexandre (Mac people, can you check?), but it is way more readable than the fair_mutex IMNSHO. I would be surprised if 2/2 also turned out to be a workaround, but even if this were the case, it makes CPU usage lower. Paolo
Re: [Qemu-devel] [PATCH] Make SLIRP Ethernet packets size to 64 bytes minimum
On 27/06/2011 15:50, Stefan Hajnoczi wrote: > On Mon, Jun 27, 2011 at 1:41 PM, Fabien Chouteau wrote: >> >> Signed-off-by: Fabien Chouteau >> --- >> slirp/slirp.c |4 ++-- >> 1 files changed, 2 insertions(+), 2 deletions(-) > > Any particular bug that this fixes? > > There have been 64 byte minimum padding patches to several emulated > NICs. There has also been discussion about where the best place to do > this is. Why is this patch necessary? > This patch is necessary because some NICs are configured to drop short frames, therefore the OS will not receive some of the packets generated by Qemu. There's a first patch to fix this issue: http://git.savannah.gnu.org/cgit/qemu.git/commit/?id=dbf3c4b4baceb91eb64d09f787cbe92d65188813 My patch fixes two other sources of short frames. -- Fabien Chouteau
Re: [Qemu-devel] [RFC v2 03/20] memory: merge adjacent segments of a single memory region
On 06/27/2011 04:56 PM, Jan Kiszka wrote: On 2011-06-27 15:21, Avi Kivity wrote: > Simple implementations of memory routers, for example the Cirrus VGA memory banks > or the 440FX PAM registers can generate adjacent memory regions which are contiguous. > Detect these and merge them; this saves kvm memory slots and shortens lookup times. That reminds me of KVM_CAP_JOIN_MEMORY_REGIONS_WORKS. Have you checked if things still work in the absence of the feature or if we need to lift our requirements on the host kernel (would be 2.6.30, not that problematic)? Good catch. We should probably disable merging if it doesn't work. Or we should declare that a kernel bug should be fixed in the kernel, not userspace, and backport the fix to 2.6.27.whatever. -- error compiling committee.c: too many arguments to function
Re: [Qemu-devel] [PATCH v2] xen_disk: cope with missing xenstore "params" node
On Sat, 25 Jun 2011, Peter Maydell wrote: > On 24 June 2011 17:35, wrote: > > +out_error: > > + qemu_free(blkdev->params); > > + qemu_free(blkdev->mode); > > + qemu_free(blkdev->type); > > + qemu_free(blkdev->dev); > > + qemu_free(blkdev->devtype); > > + return -1; > > It occured to me that could result in a double-free if it's > possible to call init again (or to call free) after the init > routine has returned failure. I don't know enough about the > Xen device lifecycle to know if that's possible, though -- is it? It shouldn't happen, but xen_disk should be able to cope with it nonetheless. I am going to resend the patch again setting to NULL all the blkdev fields after freeing them.
Re: [Qemu-devel] Build break in current -git.
On Mon, Jun 27, 2011 at 1:31 PM, Rob Landley wrote: > In file included from /usr/include/png.h:510, > from ui/vnc-enc-tight.c:37: > /usr/include/pngconf.h:371: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or > ‘__attribute__’ before ‘.’ token > /usr/include/pngconf.h:372: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or > ‘__attribute__’ before ‘include’ > make: *** [ui/vnc-enc-tight.o] Error 1 > > Building on an Ubuntu 10.04 stock install. Yep, the buildbot sent out a bunch of emails about this breakage. Stefan Weil has posted a patch to fix it: http://patchwork.ozlabs.org/patch/102108/ Stefan
Re: [Qemu-devel] [PATCH] Make SLIRP Ethernet packets size to 64 bytes minimum
On Mon, Jun 27, 2011 at 1:41 PM, Fabien Chouteau wrote: > > Signed-off-by: Fabien Chouteau > --- > slirp/slirp.c | 4 ++-- > 1 files changed, 2 insertions(+), 2 deletions(-) Any particular bug that this fixes? There have been 64 byte minimum padding patches to several emulated NICs. There has also been discussion about where the best place to do this is. Why is this patch necessary? Stefan
Re: [Qemu-devel] [RFC v2 03/20] memory: merge adjacent segments of a single memory region
On 2011-06-27 15:21, Avi Kivity wrote: > Simple implementations of memory routers, for example the Cirrus VGA memory > banks > or the 440FX PAM registers can generate adjacent memory regions which are > contiguous. > Detect these and merge them; this saves kvm memory slots and shortens lookup > times. That reminds me of KVM_CAP_JOIN_MEMORY_REGIONS_WORKS. Have you checked if things still work in the absence of the feature or if we need to lift our requirements on the host kernel (would be 2.6.30, not that problematic)? Jan -- Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux
[Qemu-devel] [RFC v2 00/20] Memory API
As expected, this is taking longer than expected, so I'm releasing something less complete than I'd have liked. Not even all of the PC machine is converted, but the difficult parts are (cirrus). It appears to work well. The major change compared to v1 is the introduction of memory_region_init_alias(), which defines a memory region in terms of another. With the current API, the ability to alias is provided by address arithmetic on ram_addr_t: ram_addr = qemu_ram_alloc(...); cpu_register_physical_memory(..., ram_addr, size, ...); /* alias: */ cpu_register_physical_memory(..., ram_addr + offset, another_size, ...); With the new API, you have to create an alias: memory_region_init_ram(&mem, ...); memory_region_register_subregion(..., &mem); /* alias: */ memory_region_init_alias(&alias, ..., &mem, offset, another_size); memory_region_register_subregion(..., &alias); The patchset is somewhat churny. One of the reasons is that we move from a handle/pointer scheme in ram_addr_t to an object constructor/destructor scheme. Another is that region size becomes a property of a region instead of being maintained externally. Also, container memory regions must be passed around, though we don't do that as well as we should. Todo: - eliminate calls to get_system_memory() (where we ignore the bus hierarchy) - add PCI APIs for the VGA window - support the PIO address space using the memory API (allowing simplified PCI BAR registration) - convert 440FX - convert everything else Also available in git://git.kernel.org/pub/scm/virt/kvm/qemu-kvm.git memory-region with a complementary pair of noisy debug patches. Avi Kivity (20): Hierarchical memory region API memory: implement dirty tracking memory: merge adjacent segments of a single memory region Internal interfaces for memory API exec.c: initialize memory map pc: grab system_memory pc: convert pc_memory_init() to memory API pc: move global memory map out of pc_init1() and into its callers pci: pass address space to pci bus when created pci: add MemoryRegion based BAR management API sysbus: add MemoryRegion based memory management API usb-ohci: convert to MemoryRegion pci: add API to get a BAR's mapped address vmsvga: don't remember pci BAR address in callback any more vga: convert vga and its derivatives to the memory API cirrus: simplify mmio BAR access functions cirrus: simplify bitblt BAR access functions cirrus: simplify vga window mmio access functions vga: simplify vga window mmio access functions cirrus: simplify linear framebuffer access functions Makefile.target|1 + exec-memory.h | 17 ++ exec.c | 19 ++ hw/apb_pci.c |2 + hw/bonito.c|4 +- hw/cirrus_vga.c| 476 hw/grackle_pci.c |5 +- hw/gt64xxx.c |4 +- hw/pc.c| 62 +++-- hw/pc.h|9 +- hw/pc_piix.c | 20 +- hw/pci.c | 68 - hw/pci.h | 16 +- hw/pci_host.h |1 + hw/pci_internals.h |1 + hw/piix_pci.c | 13 +- hw/ppc4xx_pci.c|5 +- hw/ppc_mac.h |9 +- hw/ppc_newworld.c |5 +- hw/ppc_oldworld.c |3 +- hw/ppc_prep.c |3 +- hw/ppce500_pci.c |6 +- hw/prep_pci.c |5 +- hw/prep_pci.h |3 +- hw/sh_pci.c|4 +- hw/sysbus.c| 27 ++- hw/sysbus.h|3 + hw/unin_pci.c | 10 +- hw/usb-ohci.c | 42 ++-- hw/versatile_pci.c |2 + hw/vga-isa-mm.c| 66 -- hw/vga-isa.c | 13 +- hw/vga-pci.c | 28 +-- hw/vga.c | 178 +- hw/vga_int.h | 24 +- hw/vmware_vga.c| 94 +--- memory.c | 704 memory.h | 202 +++ 38 files changed, 1525 insertions(+), 629 deletions(-) create mode 100644 exec-memory.h create mode 100644 memory.c create mode 100644 memory.h -- 1.7.5.3
Re: [Qemu-devel] [PATCH] qemu_ram_ptr_length: take ram_addr_t as arguments
On Fri, 24 Jun 2011, Peter Maydell wrote: > On 24 June 2011 12:08, wrote: > > From: Stefano Stabellini > > > > qemu_ram_ptr_length should take ram_addr_t as argument rather than > > target_phys_addr_t because is doing comparisons with RAMBlock addresses. > > > > cpu_physical_memory_map should create a ram_addr_t address to pass to > > qemu_ram_ptr_length from PhysPageDesc phys_offset. > > > > Remove code after abort() in qemu_ram_ptr_length. > > This does fix vexpress. However I think we're still doing the wrong > thing if the bounce buffer is already in use and addr points at an > IO page. In the old code, we would break out of the loop on the > if (done || bounce.buffer) condition, set *plen to 0 [because done==0 > since this is the first page] and return. Now we break out of the > loop but will fall into the call to qemu_ram_ptr_length() with a > bogus addr1 and probably abort(). > > You probably want to only call qemu_ram_ptr_length() if (todo). > (I don't know if anybody ever calls this routine with a zero input > length, but that would handle that case too.) I would rather fix qemu_ram_ptr_length to handle 0 as size argument, and then call qemu_ram_ptr_length with 0 size from cpu_physical_memory_map (see appended patch). > It would also be better to either (a) not initialise addr1, if > the compiler is smart enough to know it can't get to the use > without it being initialised or The compiler is not smart enough, unfortunately. > (b) initialise it to an obviously > bogus value if we have to do so to shut the compiler up. All right, I am going to use ULONG_MAX. > (Also 'addr1' is not a fantastic variable name :-)) Agreed, but it is the same as before :) Do you have any better suggestion? Maybe raddr? I admit I am not very imaginative with names. --- diff --git a/exec.c b/exec.c index 7f62332..e6dbddb 100644 --- a/exec.c +++ b/exec.c @@ -3137,6 +3137,8 @@ void *qemu_safe_ram_ptr(ram_addr_t addr) * but takes a size argument */ void *qemu_ram_ptr_length(ram_addr_t addr, ram_addr_t *size) { +if (*size == 0) +return NULL; if (xen_mapcache_enabled()) return qemu_map_cache(addr, *size, 1); else { @@ -4017,7 +4019,7 @@ void *cpu_physical_memory_map(target_phys_addr_t addr, target_phys_addr_t page; unsigned long pd; PhysPageDesc *p; -ram_addr_t addr1 = addr; +ram_addr_t addr1 = ULONG_MAX; ram_addr_t rlen; void *raddr;
[Qemu-devel] [RFC v2 10/20] pci: add MemoryRegion based BAR management API
Allow registering a BAR using a MemoryRegion. Once all users are converted, pci_register_bar() and pci_register_bar_simple() will be removed. Signed-off-by: Avi Kivity --- hw/pci.c | 47 +++ hw/pci.h |3 +++ 2 files changed, 42 insertions(+), 8 deletions(-) diff --git a/hw/pci.c b/hw/pci.c index cf16f3b..36db58b 100644 --- a/hw/pci.c +++ b/hw/pci.c @@ -844,10 +844,15 @@ static void pci_unregister_io_regions(PCIDevice *pci_dev) if (r->type == PCI_BASE_ADDRESS_SPACE_IO) { isa_unassign_ioport(r->addr, r->filtered_size); } else { -cpu_register_physical_memory(pci_to_cpu_addr(pci_dev->bus, - r->addr), - r->filtered_size, - IO_MEM_UNASSIGNED); +if (r->memory) { +memory_region_del_subregion(pci_dev->bus->address_space, +r->memory); +} else { +cpu_register_physical_memory(pci_to_cpu_addr(pci_dev->bus, + r->addr), + r->filtered_size, + IO_MEM_UNASSIGNED); +} } } } @@ -893,6 +898,7 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num, r->type = type; r->map_func = map_func; r->ram_addr = IO_MEM_UNASSIGNED; +r->memory = NULL; wmask = ~(size - 1); addr = pci_bar(pci_dev, region_num); @@ -918,6 +924,16 @@ static void pci_simple_bar_mapfunc(PCIDevice *pci_dev, int region_num, pci_dev->io_regions[region_num].ram_addr); } +static void pci_simple_bar_mapfunc_region(PCIDevice *pci_dev, int region_num, + pcibus_t addr, pcibus_t size, + int type) +{ +memory_region_add_subregion_overlap(pci_dev->bus->address_space, +addr, +pci_dev->io_regions[region_num].memory, +1); +} + void pci_register_bar_simple(PCIDevice *pci_dev, int region_num, pcibus_t size, uint8_t attr, ram_addr_t ram_addr) { @@ -927,6 +943,15 @@ void pci_register_bar_simple(PCIDevice *pci_dev, int region_num, pci_dev->io_regions[region_num].ram_addr = ram_addr; } +void pci_register_bar_region(PCIDevice *pci_dev, int region_num, + uint8_t attr, MemoryRegion *memory) +{ +pci_register_bar(pci_dev, region_num, memory_region_size(memory), + PCI_BASE_ADDRESS_SPACE_MEMORY | attr, + pci_simple_bar_mapfunc_region); +pci_dev->io_regions[region_num].memory = memory; +} + static void pci_bridge_filter(PCIDevice *d, pcibus_t *addr, pcibus_t *size, uint8_t type) { @@ -1065,10 +1090,16 @@ static void pci_update_mappings(PCIDevice *d) isa_unassign_ioport(r->addr, r->filtered_size); } } else { -cpu_register_physical_memory(pci_to_cpu_addr(d->bus, r->addr), - r->filtered_size, - IO_MEM_UNASSIGNED); -qemu_unregister_coalesced_mmio(r->addr, r->filtered_size); +if (r->memory) { +memory_region_del_subregion(d->bus->address_space, +r->memory); +} else { +cpu_register_physical_memory(pci_to_cpu_addr(d->bus, + r->addr), + r->filtered_size, + IO_MEM_UNASSIGNED); +qemu_unregister_coalesced_mmio(r->addr, r->filtered_size); +} } } r->addr = new_addr; diff --git a/hw/pci.h b/hw/pci.h index cfeb042..c51156d 100644 --- a/hw/pci.h +++ b/hw/pci.h @@ -94,6 +94,7 @@ typedef struct PCIIORegion { uint8_t type; PCIMapIORegionFunc *map_func; ram_addr_t ram_addr; +MemoryRegion *memory; } PCIIORegion; #define PCI_ROM_SLOT 6 @@ -204,6 +205,8 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num, PCIMapIORegionFunc *map_func); void pci_register_bar_simple(PCIDevice *pci_dev, int region_num, pcibus_t size, uint8_t attr, ram_addr_t ram_addr); +void pci_register_bar_region(PCIDevice *pci_dev, int region_num, + uint8_t attr, MemoryRegion *memory); int pci_add_capability(PCIDevice *pdev, uint8_t cap_id, uint8_t offset, uint8_t size); -- 1.
[Qemu-devel] [RFC v2 01/20] Hierarchical memory region API
The memory API separates the attributes of a memory region (its size, how reads or writes are handled, dirty logging, and coalescing) from where it is mapped and whether it is enabled. This allows a device to configure a memory region once, then hand it off to its parent bus to map it according to the bus configuration. Hierarchical registration also allows a device to compose a region out of a number of sub-regions with different properties; for example some may be RAM while others may be MMIO. Signed-off-by: Avi Kivity --- Makefile.target |1 + memory.c| 659 +++ memory.h| 201 + 3 files changed, 861 insertions(+), 0 deletions(-) create mode 100644 memory.c create mode 100644 memory.h diff --git a/Makefile.target b/Makefile.target index 03d3646..5b24bd7 100644 --- a/Makefile.target +++ b/Makefile.target @@ -194,6 +194,7 @@ obj-$(CONFIG_REALLY_VIRTFS) += 9pfs/virtio-9p-device.o obj-y += rwhandler.o obj-$(CONFIG_KVM) += kvm.o kvm-all.o obj-$(CONFIG_NO_KVM) += kvm-stub.o +obj-y += memory.o LIBS+=-lz QEMU_CFLAGS += $(VNC_TLS_CFLAGS) diff --git a/memory.c b/memory.c new file mode 100644 index 000..43499c3 --- /dev/null +++ b/memory.c @@ -0,0 +1,659 @@ +/* + * Physical memory management + * + * Copyright 2011 Red Hat, Inc. and/or its affiliates + * + * Authors: + * Avi Kivity + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + */ + +#include "memory.h" +#include + +typedef struct AddrRange AddrRange; + +struct AddrRange { +uint64_t start; +uint64_t size; +}; + +static AddrRange addrrange_make(uint64_t start, uint64_t size) +{ +return (AddrRange) { start, size }; +} + +static bool addrrange_equal(AddrRange r1, AddrRange r2) +{ +return r1.start == r2.start && r1.size == r2.size; +} + +static uint64_t addrrange_end(AddrRange r) +{ +return r.start + r.size; +} + +static AddrRange addrrange_shift(AddrRange range, int64_t delta) +{ +range.start += delta; +return range; +} + +static bool addrrange_intersects(AddrRange r1, AddrRange r2) +{ +return (r1.start >= r2.start && r1.start < r2.start + r2.size) +|| (r2.start >= r1.start && r2.start < r1.start + r1.size); +} + +static AddrRange addrrange_intersection(AddrRange r1, AddrRange r2) +{ +uint64_t start = MAX(r1.start, r2.start); +/* off-by-one arithmetic to prevent overflow */ +uint64_t end = MIN(addrrange_end(r1) - 1, addrrange_end(r2) - 1); +return addrrange_make(start, end - start + 1); +} + +struct CoalescedMemoryRange { +AddrRange addr; +QTAILQ_ENTRY(CoalescedMemoryRange) link; +}; + +typedef struct FlatRange FlatRange; +typedef struct FlatView FlatView; + +/* Range of memory in the global map. Addresses are absolute. */ +struct FlatRange { +MemoryRegion *mr; +target_phys_addr_t offset_in_region; +AddrRange addr; +}; + +/* Flattened global view of current active memory hierarchy. Kept in sorted + * order. + */ +struct FlatView { +FlatRange *ranges; +unsigned nr; +unsigned nr_allocated; +}; + +#define FOR_EACH_FLAT_RANGE(var, view) \ +for (var = (view)->ranges; var < (view)->ranges + (view)->nr; ++var) + +static FlatView current_memory_map; +static MemoryRegion *root_memory_region; + +static bool flatrange_equal(FlatRange *a, FlatRange *b) +{ +return a->mr == b->mr +&& addrrange_equal(a->addr, b->addr) +&& a->offset_in_region == b->offset_in_region; +} + +static void flatview_init(FlatView *view) +{ +view->ranges = NULL; +view->nr = 0; +view->nr_allocated = 0; +} + +/* Insert a range into a given position. Caller is responsible for maintaining + * sorting order. + */ +static void flatview_insert(FlatView *view, unsigned pos, FlatRange *range) +{ +if (view->nr == view->nr_allocated) { +view->nr_allocated = MAX(2 * view->nr, 10); +view->ranges = qemu_realloc(view->ranges, +view->nr_allocated * sizeof(*view->ranges)); +} +memmove(view->ranges + pos + 1, view->ranges + pos, +(view->nr - pos) * sizeof(FlatRange)); +view->ranges[pos] = *range; +++view->nr; +} + +static void flatview_destroy(FlatView *view) +{ +qemu_free(view->ranges); +} + +/* Render a memory region into the global view. Ranges in @view obscure + * ranges in @mr. + */ +static void render_memory_region(FlatView *view, + MemoryRegion *mr, + target_phys_addr_t base, + AddrRange clip) +{ +MemoryRegion *subregion; +unsigned i; +target_phys_addr_t offset_in_region; +uint64_t remain; +uint64_t now; +FlatRange fr; +AddrRange tmp; + +base += mr->addr; + +tmp = addrrange_make(base, mr->size); + +if (!addrrange_intersects(tmp, clip)) { +return; +} + +cl
[Qemu-devel] [RFC v2 13/20] pci: add API to get a BAR's mapped address
This is a hack, for devices that have a back-channel to read this address back outside the normal configuration mechanisms, such as VMware svga. Signed-off-by: Avi Kivity --- hw/pci.c |5 + hw/pci.h |1 + 2 files changed, 6 insertions(+), 0 deletions(-) diff --git a/hw/pci.c b/hw/pci.c index 36db58b..912f849 100644 --- a/hw/pci.c +++ b/hw/pci.c @@ -952,6 +952,11 @@ void pci_register_bar_region(PCIDevice *pci_dev, int region_num, pci_dev->io_regions[region_num].memory = memory; } +pcibus_t pci_get_bar_addr(PCIDevice *pci_dev, int region_num) +{ +return pci_dev->io_regions[region_num].addr; +} + static void pci_bridge_filter(PCIDevice *d, pcibus_t *addr, pcibus_t *size, uint8_t type) { diff --git a/hw/pci.h b/hw/pci.h index c51156d..64282ad 100644 --- a/hw/pci.h +++ b/hw/pci.h @@ -207,6 +207,7 @@ void pci_register_bar_simple(PCIDevice *pci_dev, int region_num, pcibus_t size, uint8_t attr, ram_addr_t ram_addr); void pci_register_bar_region(PCIDevice *pci_dev, int region_num, uint8_t attr, MemoryRegion *memory); +pcibus_t pci_get_bar_addr(PCIDevice *pci_dev, int region_num); int pci_add_capability(PCIDevice *pdev, uint8_t cap_id, uint8_t offset, uint8_t size); -- 1.7.5.3
[Qemu-devel] [RFC v2 11/20] sysbus: add MemoryRegion based memory management API
Allow registering sysbus device memory using a MemoryRegion. Once all users are converted, sysbus_init_mmio() and sysbus_init_mmio_cb() will be removed. Signed-off-by: Avi Kivity --- hw/sysbus.c | 27 --- hw/sysbus.h |3 +++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/hw/sysbus.c b/hw/sysbus.c index 2e22be7..ea442ac 100644 --- a/hw/sysbus.c +++ b/hw/sysbus.c @@ -19,6 +19,7 @@ #include "sysbus.h" #include "monitor.h" +#include "exec-memory.h" static void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent); static char *sysbus_get_fw_dev_path(DeviceState *dev); @@ -49,11 +50,20 @@ void sysbus_mmio_map(SysBusDevice *dev, int n, target_phys_addr_t addr) } if (dev->mmio[n].addr != (target_phys_addr_t)-1) { /* Unregister previous mapping. */ -cpu_register_physical_memory(dev->mmio[n].addr, dev->mmio[n].size, - IO_MEM_UNASSIGNED); +if (dev->mmio[n].memory) { +memory_region_del_subregion(get_system_memory(), +dev->mmio[n].memory); +} else { +cpu_register_physical_memory(dev->mmio[n].addr, dev->mmio[n].size, + IO_MEM_UNASSIGNED); +} } dev->mmio[n].addr = addr; -if (dev->mmio[n].cb) { +if (dev->mmio[n].memory) { +memory_region_add_subregion(get_system_memory(), +addr, +dev->mmio[n].memory); +} else if (dev->mmio[n].cb) { dev->mmio[n].cb(dev, addr); } else { cpu_register_physical_memory(addr, dev->mmio[n].size, @@ -107,6 +117,17 @@ void sysbus_init_mmio_cb(SysBusDevice *dev, target_phys_addr_t size, dev->mmio[n].cb = cb; } +void sysbus_init_mmio_region(SysBusDevice *dev, MemoryRegion *memory) +{ +int n; + +assert(dev->num_mmio < QDEV_MAX_MMIO); +n = dev->num_mmio++; +dev->mmio[n].addr = -1; +dev->mmio[n].size = memory_region_size(memory); +dev->mmio[n].memory = memory; +} + void sysbus_init_ioports(SysBusDevice *dev, pio_addr_t ioport, pio_addr_t size) { pio_addr_t i; diff --git a/hw/sysbus.h b/hw/sysbus.h index 4e8cb16..5f62e2d 100644 --- a/hw/sysbus.h +++ b/hw/sysbus.h @@ -4,6 +4,7 @@ /* Devices attached directly to the main system bus. */ #include "qdev.h" +#include "memory.h" #define QDEV_MAX_MMIO 32 #define QDEV_MAX_PIO 32 @@ -23,6 +24,7 @@ struct SysBusDevice { target_phys_addr_t size; mmio_mapfunc cb; ram_addr_t iofunc; +MemoryRegion *memory; } mmio[QDEV_MAX_MMIO]; int num_pio; pio_addr_t pio[QDEV_MAX_PIO]; @@ -46,6 +48,7 @@ void sysbus_init_mmio(SysBusDevice *dev, target_phys_addr_t size, ram_addr_t iofunc); void sysbus_init_mmio_cb(SysBusDevice *dev, target_phys_addr_t size, mmio_mapfunc cb); +void sysbus_init_mmio_region(SysBusDevice *dev, MemoryRegion *memory); void sysbus_init_irq(SysBusDevice *dev, qemu_irq *p); void sysbus_pass_irq(SysBusDevice *dev, SysBusDevice *target); void sysbus_init_ioports(SysBusDevice *dev, pio_addr_t ioport, pio_addr_t size); -- 1.7.5.3
[Qemu-devel] [RFC v2 04/20] Internal interfaces for memory API
get_system_memory() provides the root of the memory hierarchy. This interface is intended to be private between memory.c and exec.c. If this file is included elsewhere, it should be regarded as a bug (or TODO item). However, it will be temporarily needed for the conversion to hierarchical memory routing. Signed-off-by: Avi Kivity --- exec-memory.h | 17 + 1 files changed, 17 insertions(+), 0 deletions(-) create mode 100644 exec-memory.h diff --git a/exec-memory.h b/exec-memory.h new file mode 100644 index 000..2722f7e --- /dev/null +++ b/exec-memory.h @@ -0,0 +1,17 @@ +#ifndef EXEC_MEMORY_H +#define EXEC_MEMORY_H + +/* + * Internal interfaces between memory.c/exec.c/vl.c. Do not #include unless + * you're one of them. + */ + +#include "memory.h" + +#ifndef CONFIG_USER_ONLY + +MemoryRegion *get_system_memory(void); + +#endif + +#endif -- 1.7.5.3
[Qemu-devel] [RFC v2 15/20] vga: convert vga and its derivatives to the memory API
Convert all vga memory to the memory API. Note we need to fall back to get_system_memory(), since the various buses don't pass the vga window as a memory region. Signed-off-by: Avi Kivity --- hw/cirrus_vga.c | 346 +-- hw/vga-isa-mm.c | 66 --- hw/vga-isa.c| 13 ++- hw/vga-pci.c| 28 + hw/vga.c| 146 +++- hw/vga_int.h| 20 ++-- hw/vmware_vga.c | 84 - 7 files changed, 395 insertions(+), 308 deletions(-) diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c index f39d1f8..0cce453 100644 --- a/hw/cirrus_vga.c +++ b/hw/cirrus_vga.c @@ -200,9 +200,14 @@ typedef void (*cirrus_fill_t)(struct CirrusVGAState *s, typedef struct CirrusVGAState { VGACommonState vga; -int cirrus_linear_io_addr; -int cirrus_linear_bitblt_io_addr; -int cirrus_mmio_io_addr; +MemoryRegion cirrus_linear_io; +MemoryRegion cirrus_linear_bitblt_io; +MemoryRegion cirrus_mmio_io; +MemoryRegion pci_bar; +bool linear_vram; /* vga.vram mapped over cirrus_linear_io */ +MemoryRegion low_mem_container; /* container for 0xa-0xc */ +MemoryRegion low_mem; /* always mapped, overridden by: */ +MemoryRegion *cirrus_bank[2]; /* aliases at 0xa-0xb */ uint32_t cirrus_addr_mask; uint32_t linear_mmio_mask; uint8_t cirrus_shadow_gr0; @@ -612,7 +617,7 @@ static void cirrus_invalidate_region(CirrusVGAState * s, int off_begin, off_cur_end = (off_cur + bytesperline) & s->cirrus_addr_mask; off_cur &= TARGET_PAGE_MASK; while (off_cur < off_cur_end) { - cpu_physical_memory_set_dirty(s->vga.vram_offset + off_cur); + memory_region_set_dirty(&s->vga.vram, off_cur); off_cur += TARGET_PAGE_SIZE; } off_begin += off_pitch; @@ -1177,12 +1182,6 @@ static void cirrus_update_bank_ptr(CirrusVGAState * s, unsigned bank_index) } if (limit > 0) { -/* Thinking about changing bank base? First, drop the dirty bitmap information - * on the current location, otherwise we lose this pointer forever */ -if (s->vga.lfb_vram_mapped) { -target_phys_addr_t base_addr = isa_mem_base + 0xa + bank_index * 0x8000; -cpu_physical_sync_dirty_bitmap(base_addr, base_addr + 0x8000); -} s->cirrus_bank_base[bank_index] = offset; s->cirrus_bank_limit[bank_index] = limit; } else { @@ -1921,8 +1920,8 @@ static void cirrus_mem_writeb_mode4and5_8bpp(CirrusVGAState * s, val <<= 1; dst++; } -cpu_physical_memory_set_dirty(s->vga.vram_offset + offset); -cpu_physical_memory_set_dirty(s->vga.vram_offset + offset + 7); +memory_region_set_dirty(&s->vga.vram, offset); +memory_region_set_dirty(&s->vga.vram, offset + 7); } static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s, @@ -1946,8 +1945,8 @@ static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s, val <<= 1; dst += 2; } -cpu_physical_memory_set_dirty(s->vga.vram_offset + offset); -cpu_physical_memory_set_dirty(s->vga.vram_offset + offset + 15); +memory_region_set_dirty(&s->vga.vram, offset); +memory_region_set_dirty(&s->vga.vram, offset + 15); } /*** @@ -2057,8 +2056,7 @@ static void cirrus_vga_mem_writeb(void *opaque, target_phys_addr_t addr, mode = s->vga.gr[0x05] & 0x7; if (mode < 4 || mode > 5 || ((s->vga.gr[0x0B] & 0x4) == 0)) { *(s->vga.vram_ptr + bank_offset) = mem_value; - cpu_physical_memory_set_dirty(s->vga.vram_offset + - bank_offset); + memory_region_set_dirty(&s->vga.vram, bank_offset); } else { if ((s->vga.gr[0x0B] & 0x14) != 0x14) { cirrus_mem_writeb_mode4and5_8bpp(s, mode, @@ -2099,16 +2097,37 @@ static void cirrus_vga_mem_writel(void *opaque, target_phys_addr_t addr, uint32_ cirrus_vga_mem_writeb(opaque, addr + 3, (val >> 24) & 0xff); } -static CPUReadMemoryFunc * const cirrus_vga_mem_read[3] = { -cirrus_vga_mem_readb, -cirrus_vga_mem_readw, -cirrus_vga_mem_readl, +static uint64_t cirrus_vga_mem_read(MemoryRegion *mr, +target_phys_addr_t addr, +uint32_t size) +{ +CirrusVGAState *s = container_of(mr, CirrusVGAState, low_mem); + +switch (size) { +case 1: return cirrus_vga_mem_readb(s, addr); +case 2: return cirrus_vga_mem_readw(s, addr); +case 4: return cirrus_vga_mem_readl(s, addr); +default: abort(); +} +} + +static void cirrus_vga_mem_write(MemoryRegion *mr, target_phys_addr_t addr, + uint64_t data, unsigned size) +{ +CirrusVGAState *s = container_of(mr, CirrusVGAState, low_mem)
[Qemu-devel] [RFC v2 03/20] memory: merge adjacent segments of a single memory region
Simple implementations of memory routers, for example the Cirrus VGA memory banks or the 440FX PAM registers can generate adjacent memory regions which are contiguous. Detect these and merge them; this saves kvm memory slots and shortens lookup times. Signed-off-by: Avi Kivity --- memory.c | 22 ++ 1 files changed, 22 insertions(+), 0 deletions(-) diff --git a/memory.c b/memory.c index d962fff..f136714 100644 --- a/memory.c +++ b/memory.c @@ -122,6 +122,27 @@ static void flatview_destroy(FlatView *view) qemu_free(view->ranges); } +/* Attempt to simplify a view by merging ajacent ranges */ +static void flatview_simplify(FlatView *view) +{ +unsigned i; +FlatRange *r1, *r2; + +for (i = 0; i + 1 < view->nr; ++i) { +r1 = &view->ranges[i]; +r2 = &view->ranges[i+1]; +if (addrrange_end(r1->addr) == r2->addr.start +&& r1->mr == r2->mr +&& r1->offset_in_region + r1->addr.size == r2->offset_in_region +&& r1->dirty_log_mask == r2->dirty_log_mask) { +r1->addr.size += r2->addr.size; +memmove(r2, r2 + 1, (view->nr - (i + 2)) * sizeof(*r2)); +--view->nr; +--i; +} +} +} + /* Render a memory region into the global view. Ranges in @view obscure * ranges in @mr. */ @@ -209,6 +230,7 @@ static FlatView generate_memory_topology(MemoryRegion *mr) flatview_init(&view); render_memory_region(&view, mr, 0, addrrange_make(0, UINT64_MAX)); +flatview_simplify(&view); return view; } -- 1.7.5.3
[Qemu-devel] [RFC v2 09/20] pci: pass address space to pci bus when created
This is now done sloppily, via get_system_memory(). Eventually callers will be converted to stop using that. Signed-off-by: Avi Kivity --- hw/apb_pci.c |2 ++ hw/bonito.c|4 +++- hw/grackle_pci.c |5 +++-- hw/gt64xxx.c |4 +++- hw/pc.h|4 +++- hw/pc_piix.c |3 ++- hw/pci.c | 16 +++- hw/pci.h | 12 +--- hw/pci_host.h |1 + hw/pci_internals.h |1 + hw/piix_pci.c | 13 + hw/ppc4xx_pci.c|5 - hw/ppc_mac.h |9 ++--- hw/ppc_newworld.c |5 +++-- hw/ppc_oldworld.c |3 ++- hw/ppc_prep.c |3 ++- hw/ppce500_pci.c |6 +- hw/prep_pci.c |5 +++-- hw/prep_pci.h |3 ++- hw/sh_pci.c|4 +++- hw/unin_pci.c | 10 ++ hw/versatile_pci.c |2 ++ 22 files changed, 85 insertions(+), 35 deletions(-) diff --git a/hw/apb_pci.c b/hw/apb_pci.c index 974c87a..8b9939c 100644 --- a/hw/apb_pci.c +++ b/hw/apb_pci.c @@ -34,6 +34,7 @@ #include "rwhandler.h" #include "apb_pci.h" #include "sysemu.h" +#include "exec-memory.h" /* debug APB */ //#define DEBUG_APB @@ -346,6 +347,7 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base, d->bus = pci_register_bus(&d->busdev.qdev, "pci", pci_apb_set_irq, pci_pbm_map_irq, d, + get_system_memory(), 0, 32); pci_bus_set_mem_base(d->bus, mem_base); diff --git a/hw/bonito.c b/hw/bonito.c index e8c57a3..5f62dda 100644 --- a/hw/bonito.c +++ b/hw/bonito.c @@ -42,6 +42,7 @@ #include "mips.h" #include "pci_host.h" #include "sysemu.h" +#include "exec-memory.h" //#define DEBUG_BONITO @@ -773,7 +774,8 @@ PCIBus *bonito_init(qemu_irq *pic) dev = qdev_create(NULL, "Bonito-pcihost"); pcihost = FROM_SYSBUS(BonitoState, sysbus_from_qdev(dev)); b = pci_register_bus(&pcihost->busdev.qdev, "pci", pci_bonito_set_irq, - pci_bonito_map_irq, pic, 0x28, 32); + pci_bonito_map_irq, pic, get_system_memory(), + 0x28, 32); pcihost->bus = b; qdev_init_nofail(dev); diff --git a/hw/grackle_pci.c b/hw/grackle_pci.c index cee07e0..da67cf9 100644 --- a/hw/grackle_pci.c +++ b/hw/grackle_pci.c @@ -61,7 +61,8 @@ static void pci_grackle_reset(void *opaque) { } -PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic) +PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic, + MemoryRegion *address_space) { DeviceState *dev; SysBusDevice *s; @@ -74,7 +75,7 @@ PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic) d->host_state.bus = pci_register_bus(&d->busdev.qdev, "pci", pci_grackle_set_irq, pci_grackle_map_irq, - pic, 0, 4); + pic, address_space, 0, 4); pci_create_simple(d->host_state.bus, 0, "grackle"); diff --git a/hw/gt64xxx.c b/hw/gt64xxx.c index 8e1f6a0..65e63dd 100644 --- a/hw/gt64xxx.c +++ b/hw/gt64xxx.c @@ -27,6 +27,7 @@ #include "pci.h" #include "pci_host.h" #include "pc.h" +#include "exec-memory.h" //#define DEBUG @@ -1092,7 +1093,8 @@ PCIBus *gt64120_register(qemu_irq *pic) d = FROM_SYSBUS(GT64120State, s); d->pci.bus = pci_register_bus(&d->busdev.qdev, "pci", gt64120_pci_set_irq, gt64120_pci_map_irq, - pic, PCI_DEVFN(18, 0), 4); + pic, get_system_memory(), + PCI_DEVFN(18, 0), 4); d->ISD_handle = cpu_register_io_memory(gt64120_read, gt64120_write, d, DEVICE_NATIVE_ENDIAN); diff --git a/hw/pc.h b/hw/pc.h index 40684f4..a2de0fe 100644 --- a/hw/pc.h +++ b/hw/pc.h @@ -178,7 +178,9 @@ int pcspk_audio_init(qemu_irq *pic); struct PCII440FXState; typedef struct PCII440FXState PCII440FXState; -PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix_devfn, qemu_irq *pic, ram_addr_t ram_size); +PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix_devfn, +qemu_irq *pic, MemoryRegion *address_space, +ram_addr_t ram_size); void i440fx_init_memory_mappings(PCII440FXState *d); /* piix4.c */ diff --git a/hw/pc_piix.c b/hw/pc_piix.c index f2d0476..2b9c2b1 100644 --- a/hw/pc_piix.c +++ b/hw/pc_piix.c @@ -128,7 +128,8 @@ static void pc_init1(MemoryRegion *system_memory, isa_irq = qemu_allocate_irqs(isa_irq_handler, isa_irq_state, 24); if (pci_enabled) { -pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, isa_irq, ram_size); +pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, isa_irq, + system_memory, ram_size); } else {
[Qemu-devel] [RFC v2 19/20] vga: simplify vga window mmio access functions
Make use of the memory API's ability to satisfy multi-byte accesses via multiple single-byte accesses. We have to keep vga_mem_{read,write}b() since they're used by cirrus. Signed-off-by: Avi Kivity --- hw/cirrus_vga.c |4 +- hw/vga.c| 56 +++--- hw/vga_int.h|4 +- 3 files changed, 12 insertions(+), 52 deletions(-) diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c index 6e9e83d..1036eb2 100644 --- a/hw/cirrus_vga.c +++ b/hw/cirrus_vga.c @@ -1965,7 +1965,7 @@ static uint64_t cirrus_vga_mem_read(MemoryRegion *mr, uint32_t val; if ((s->vga.sr[0x07] & 0x01) == 0) { - return vga_mem_readb(s, addr); +return vga_mem_readb(&s->vga, addr); } if (addr < 0x1) { @@ -2010,7 +2010,7 @@ static void cirrus_vga_mem_write(MemoryRegion *mr, unsigned mode; if ((s->vga.sr[0x07] & 0x01) == 0) { - vga_mem_writeb(s, addr, mem_value); +vga_mem_writeb(&s->vga, addr, mem_value); return; } diff --git a/hw/vga.c b/hw/vga.c index 7f7aeb1..38e14cf 100644 --- a/hw/vga.c +++ b/hw/vga.c @@ -707,9 +707,8 @@ static void vbe_ioport_write_data(void *opaque, uint32_t addr, uint32_t val) #endif /* called for accesses between 0xa and 0xc */ -uint32_t vga_mem_readb(void *opaque, target_phys_addr_t addr) +uint32_t vga_mem_readb(VGACommonState *s, target_phys_addr_t addr) { -VGACommonState *s = opaque; int memory_map_mode, plane; uint32_t ret; @@ -763,28 +762,9 @@ uint32_t vga_mem_readb(void *opaque, target_phys_addr_t addr) return ret; } -static uint32_t vga_mem_readw(void *opaque, target_phys_addr_t addr) -{ -uint32_t v; -v = vga_mem_readb(opaque, addr); -v |= vga_mem_readb(opaque, addr + 1) << 8; -return v; -} - -static uint32_t vga_mem_readl(void *opaque, target_phys_addr_t addr) -{ -uint32_t v; -v = vga_mem_readb(opaque, addr); -v |= vga_mem_readb(opaque, addr + 1) << 8; -v |= vga_mem_readb(opaque, addr + 2) << 16; -v |= vga_mem_readb(opaque, addr + 3) << 24; -return v; -} - /* called for accesses between 0xa and 0xc */ -void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) +void vga_mem_writeb(VGACommonState *s, target_phys_addr_t addr, uint32_t val) { -VGACommonState *s = opaque; int memory_map_mode, plane, write_mode, b, func_select, mask; uint32_t write_mask, bit_mask, set_mask; @@ -916,20 +896,6 @@ void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val) } } -static void vga_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val) -{ -vga_mem_writeb(opaque, addr, val & 0xff); -vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff); -} - -static void vga_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val) -{ -vga_mem_writeb(opaque, addr, val & 0xff); -vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff); -vga_mem_writeb(opaque, addr + 2, (val >> 16) & 0xff); -vga_mem_writeb(opaque, addr + 3, (val >> 24) & 0xff); -} - typedef void vga_draw_glyph8_func(uint8_t *d, int linesize, const uint8_t *font_ptr, int h, uint32_t fgcol, uint32_t bgcol); @@ -2104,12 +2070,7 @@ static uint64_t vga_mem_read(MemoryRegion *mr, target_phys_addr_t addr, { VGACommonState *s = container_of(mr, VGAMemoryRegion, mem)->s; -switch (size) { -case 1: return vga_mem_readb(s, addr); -case 2: return vga_mem_readw(s, addr); -case 4: return vga_mem_readl(s, addr); -default: abort(); -} +return vga_mem_readb(s, addr); } static void vga_mem_write(MemoryRegion *mr, target_phys_addr_t addr, @@ -2117,18 +2078,17 @@ static void vga_mem_write(MemoryRegion *mr, target_phys_addr_t addr, { VGACommonState *s = container_of(mr, VGAMemoryRegion, mem)->s; -switch (size) { -case 1: return vga_mem_writeb(s, addr, data); -case 2: return vga_mem_writew(s, addr, data); -case 4: return vga_mem_writel(s, addr, data); -default: abort(); -} +return vga_mem_writeb(s, addr, data); } MemoryRegionOps vga_mem_ops = { .read = vga_mem_read, .write = vga_mem_write, .endianness = DEVICE_LITTLE_ENDIAN, +.impl = { +.min_access_size = 1, +.max_access_size = 1, +}, }; static int vga_common_post_load(void *opaque, int version_id) diff --git a/hw/vga_int.h b/hw/vga_int.h index 0ef9962..37b0a09 100644 --- a/hw/vga_int.h +++ b/hw/vga_int.h @@ -202,8 +202,8 @@ void vga_dirty_log_restart(VGACommonState *s); extern const VMStateDescription vmstate_vga_common; uint32_t vga_ioport_read(void *opaque, uint32_t addr); void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val); -uint32_t vga_mem_readb(void *opaque, target_phys_addr_t addr); -void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val); +uint32_t vga_mem_readb(VGACommonState *s, target_phys_addr_t addr); +void vga_m
[Qemu-devel] [RFC v2 20/20] cirrus: simplify linear framebuffer access functions
Make use of the memory API's ability to satisfy multi-byte accesses via multiple single-byte accesses. Signed-off-by: Avi Kivity --- hw/cirrus_vga.c | 78 +++--- 1 files changed, 10 insertions(+), 68 deletions(-) diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c index 1036eb2..88cb274 100644 --- a/hw/cirrus_vga.c +++ b/hw/cirrus_vga.c @@ -2249,9 +2249,10 @@ static void cirrus_cursor_draw_line(VGACommonState *s1, uint8_t *d1, int scr_y) * ***/ -static uint32_t cirrus_linear_readb(void *opaque, target_phys_addr_t addr) +static uint64_t cirrus_linear_read(MemoryRegion *mr, target_phys_addr_t addr, + unsigned size) { -CirrusVGAState *s = opaque; +CirrusVGAState *s = container_of(mr, CirrusVGAState, cirrus_linear_io); uint32_t ret; addr &= s->cirrus_addr_mask; @@ -2277,30 +2278,10 @@ static uint32_t cirrus_linear_readb(void *opaque, target_phys_addr_t addr) return ret; } -static uint32_t cirrus_linear_readw(void *opaque, target_phys_addr_t addr) -{ -uint32_t v; - -v = cirrus_linear_readb(opaque, addr); -v |= cirrus_linear_readb(opaque, addr + 1) << 8; -return v; -} - -static uint32_t cirrus_linear_readl(void *opaque, target_phys_addr_t addr) -{ -uint32_t v; - -v = cirrus_linear_readb(opaque, addr); -v |= cirrus_linear_readb(opaque, addr + 1) << 8; -v |= cirrus_linear_readb(opaque, addr + 2) << 16; -v |= cirrus_linear_readb(opaque, addr + 3) << 24; -return v; -} - -static void cirrus_linear_writeb(void *opaque, target_phys_addr_t addr, -uint32_t val) +static void cirrus_linear_write(MemoryRegion *mr, target_phys_addr_t addr, +uint64_t val, unsigned size) { -CirrusVGAState *s = opaque; +CirrusVGAState *s = container_of(mr, CirrusVGAState, cirrus_linear_io); unsigned mode; addr &= s->cirrus_addr_mask; @@ -2338,49 +2319,6 @@ static void cirrus_linear_writeb(void *opaque, target_phys_addr_t addr, } } -static void cirrus_linear_writew(void *opaque, target_phys_addr_t addr, -uint32_t val) -{ -cirrus_linear_writeb(opaque, addr, val & 0xff); -cirrus_linear_writeb(opaque, addr + 1, (val >> 8) & 0xff); -} - -static void cirrus_linear_writel(void *opaque, target_phys_addr_t addr, -uint32_t val) -{ -cirrus_linear_writeb(opaque, addr, val & 0xff); -cirrus_linear_writeb(opaque, addr + 1, (val >> 8) & 0xff); -cirrus_linear_writeb(opaque, addr + 2, (val >> 16) & 0xff); -cirrus_linear_writeb(opaque, addr + 3, (val >> 24) & 0xff); -} - - -static uint64_t cirrus_linear_read(MemoryRegion *mr, target_phys_addr_t addr, - unsigned size) -{ -CirrusVGAState *s = container_of(mr, CirrusVGAState, cirrus_linear_io); - -switch (size) { -case 1: return cirrus_linear_readb(s, addr); -case 2: return cirrus_linear_readw(s, addr); -case 4: return cirrus_linear_readl(s, addr); -default: abort(); -} -} - -static void cirrus_linear_write(MemoryRegion *mr, target_phys_addr_t addr, -uint64_t data, unsigned size) -{ -CirrusVGAState *s = container_of(mr, CirrusVGAState, cirrus_linear_io); - -switch (size) { -case 1: return cirrus_linear_writeb(s, addr, data); -case 2: return cirrus_linear_writew(s, addr, data); -case 4: return cirrus_linear_writel(s, addr, data); -default: abort(); -} -} - /*** * * system to screen memory access @@ -2862,6 +2800,10 @@ static MemoryRegionOps cirrus_linear_io_ops = { .read = cirrus_linear_read, .write = cirrus_linear_write, .endianness = DEVICE_LITTLE_ENDIAN, +.impl = { +.min_access_size = 1, +.max_access_size = 1, +}, }; static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci) -- 1.7.5.3
[Qemu-devel] [RFC v2 12/20] usb-ohci: convert to MemoryRegion
Signed-off-by: Avi Kivity --- hw/usb-ohci.c | 42 +- 1 files changed, 17 insertions(+), 25 deletions(-) diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c index 5d2ae01..e6a901f 100644 --- a/hw/usb-ohci.c +++ b/hw/usb-ohci.c @@ -62,7 +62,7 @@ typedef struct OHCIPort { typedef struct { USBBus bus; qemu_irq irq; -int mem; +MemoryRegion mem; int num_ports; const char *name; @@ -1415,13 +1415,13 @@ static void ohci_port_set_status(OHCIState *ohci, int portnum, uint32_t val) return; } -static uint32_t ohci_mem_read(void *ptr, target_phys_addr_t addr) +static uint64_t ohci_mem_read(MemoryRegion *mem, + target_phys_addr_t addr, + unsigned size) { -OHCIState *ohci = ptr; +OHCIState *ohci = container_of(mem, OHCIState, mem); uint32_t retval; -addr &= 0xff; - /* Only aligned reads are allowed on OHCI */ if (addr & 3) { fprintf(stderr, "usb-ohci: Mis-aligned read\n"); @@ -1538,11 +1538,12 @@ static uint32_t ohci_mem_read(void *ptr, target_phys_addr_t addr) return retval; } -static void ohci_mem_write(void *ptr, target_phys_addr_t addr, uint32_t val) +static void ohci_mem_write(MemoryRegion *mem, + target_phys_addr_t addr, + uint64_t val, + unsigned size) { -OHCIState *ohci = ptr; - -addr &= 0xff; +OHCIState *ohci = container_of(mem, OHCIState, mem); /* Only aligned reads are allowed on OHCI */ if (addr & 3) { @@ -1674,18 +1675,10 @@ static void ohci_device_destroy(USBBus *bus, USBDevice *dev) } } -/* Only dword reads are defined on OHCI register space */ -static CPUReadMemoryFunc * const ohci_readfn[3]={ -ohci_mem_read, -ohci_mem_read, -ohci_mem_read -}; - -/* Only dword writes are defined on OHCI register space */ -static CPUWriteMemoryFunc * const ohci_writefn[3]={ -ohci_mem_write, -ohci_mem_write, -ohci_mem_write +static const MemoryRegionOps ohci_mem_ops = { +.read = ohci_mem_read, +.write = ohci_mem_write, +.endianness = DEVICE_LITTLE_ENDIAN, }; static USBPortOps ohci_port_ops = { @@ -1720,8 +1713,7 @@ static void usb_ohci_init(OHCIState *ohci, DeviceState *dev, usb_frame_time, usb_bit_time); } -ohci->mem = cpu_register_io_memory(ohci_readfn, ohci_writefn, ohci, - DEVICE_LITTLE_ENDIAN); +memory_region_init_io(&ohci->mem, &ohci_mem_ops, "ohci", 256); ohci->localmem_base = localmem_base; ohci->name = dev->info->name; @@ -1756,7 +1748,7 @@ static int usb_ohci_initfn_pci(struct PCIDevice *dev) ohci->state.irq = ohci->pci_dev.irq[0]; /* TODO: avoid cast below by using dev */ -pci_register_bar_simple(&ohci->pci_dev, 0, 256, 0, ohci->state.mem); +pci_register_bar_region(&ohci->pci_dev, 0, 0, &ohci->state.mem); return 0; } @@ -1778,7 +1770,7 @@ static int ohci_init_pxa(SysBusDevice *dev) usb_ohci_init(&s->ohci, &dev->qdev, s->num_ports, s->dma_offset); sysbus_init_irq(dev, &s->ohci.irq); -sysbus_init_mmio(dev, 0x1000, s->ohci.mem); +sysbus_init_mmio_region(dev, &s->ohci.mem); return 0; } -- 1.7.5.3
[Qemu-devel] [RFC v2 16/20] cirrus: simplify mmio BAR access functions
Make use of the memory API's ability to satisfy multi-byte accesses via multiple single-byte accesses. Signed-off-by: Avi Kivity --- hw/cirrus_vga.c | 82 +++ 1 files changed, 10 insertions(+), 72 deletions(-) diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c index 0cce453..0cb34d9 100644 --- a/hw/cirrus_vga.c +++ b/hw/cirrus_vga.c @@ -2830,11 +2830,10 @@ static void cirrus_vga_ioport_write(void *opaque, uint32_t addr, uint32_t val) * ***/ -static uint32_t cirrus_mmio_readb(void *opaque, target_phys_addr_t addr) +static uint64_t cirrus_mmio_read(MemoryRegion *mr, target_phys_addr_t addr, + unsigned size) { -CirrusVGAState *s = opaque; - -addr &= CIRRUS_PNPMMIO_SIZE - 1; +CirrusVGAState *s = container_of(mr, CirrusVGAState, cirrus_mmio_io); if (addr >= 0x100) { return cirrus_mmio_blt_read(s, addr - 0x100); @@ -2843,32 +2842,10 @@ static uint32_t cirrus_mmio_readb(void *opaque, target_phys_addr_t addr) } } -static uint32_t cirrus_mmio_readw(void *opaque, target_phys_addr_t addr) -{ -uint32_t v; - -v = cirrus_mmio_readb(opaque, addr); -v |= cirrus_mmio_readb(opaque, addr + 1) << 8; -return v; -} - -static uint32_t cirrus_mmio_readl(void *opaque, target_phys_addr_t addr) -{ -uint32_t v; - -v = cirrus_mmio_readb(opaque, addr); -v |= cirrus_mmio_readb(opaque, addr + 1) << 8; -v |= cirrus_mmio_readb(opaque, addr + 2) << 16; -v |= cirrus_mmio_readb(opaque, addr + 3) << 24; -return v; -} - -static void cirrus_mmio_writeb(void *opaque, target_phys_addr_t addr, - uint32_t val) +static void cirrus_mmio_write(MemoryRegion *mr, target_phys_addr_t addr, + uint64_t val, unsigned size) { -CirrusVGAState *s = opaque; - -addr &= CIRRUS_PNPMMIO_SIZE - 1; +CirrusVGAState *s = container_of(mr, CirrusVGAState, cirrus_mmio_io); if (addr >= 0x100) { cirrus_mmio_blt_write(s, addr - 0x100, val); @@ -2877,53 +2854,14 @@ static void cirrus_mmio_writeb(void *opaque, target_phys_addr_t addr, } } -static void cirrus_mmio_writew(void *opaque, target_phys_addr_t addr, - uint32_t val) -{ -cirrus_mmio_writeb(opaque, addr, val & 0xff); -cirrus_mmio_writeb(opaque, addr + 1, (val >> 8) & 0xff); -} - -static void cirrus_mmio_writel(void *opaque, target_phys_addr_t addr, - uint32_t val) -{ -cirrus_mmio_writeb(opaque, addr, val & 0xff); -cirrus_mmio_writeb(opaque, addr + 1, (val >> 8) & 0xff); -cirrus_mmio_writeb(opaque, addr + 2, (val >> 16) & 0xff); -cirrus_mmio_writeb(opaque, addr + 3, (val >> 24) & 0xff); -} - - -static uint64_t cirrus_mmio_read(MemoryRegion *mr, target_phys_addr_t addr, - unsigned size) -{ -CirrusVGAState *s = container_of(mr, CirrusVGAState, cirrus_mmio_io); - -switch (size) { -case 1: return cirrus_mmio_readb(s, addr); -case 2: return cirrus_mmio_readw(s, addr); -case 4: return cirrus_mmio_readl(s, addr); -default: abort(); -} -}; - -static void cirrus_mmio_write(MemoryRegion *mr, target_phys_addr_t addr, - uint64_t data, unsigned size) -{ -CirrusVGAState *s = container_of(mr, CirrusVGAState, cirrus_mmio_io); - -switch (size) { -case 1: return cirrus_mmio_writeb(s, addr, data); -case 2: return cirrus_mmio_writew(s, addr, data); -case 4: return cirrus_mmio_writel(s, addr, data); -default: abort(); -} -}; - static MemoryRegionOps cirrus_mmio_io_ops = { .read = cirrus_mmio_read, .write = cirrus_mmio_write, .endianness = DEVICE_LITTLE_ENDIAN, +.impl = { +.min_access_size = 1, +.max_access_size = 1, +}, }; /* load/save state */ -- 1.7.5.3
[Qemu-devel] [RFC v2 05/20] exec.c: initialize memory map
Allocate the root memory region and initialize it. Signed-off-by: Avi Kivity --- exec.c | 19 +++ 1 files changed, 19 insertions(+), 0 deletions(-) diff --git a/exec.c b/exec.c index b03b5be..9b894b9 100644 --- a/exec.c +++ b/exec.c @@ -34,6 +34,8 @@ #include "kvm.h" #include "hw/xen.h" #include "qemu-timer.h" +#include "memory.h" +#include "exec-memory.h" #if defined(CONFIG_USER_ONLY) #include #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) @@ -110,6 +112,9 @@ int phys_ram_fd; static int in_migration; RAMList ram_list = { .blocks = QLIST_HEAD_INITIALIZER(ram_list) }; + +static MemoryRegion *system_memory; + #endif CPUState *first_cpu; @@ -198,6 +203,7 @@ typedef struct PhysPageDesc { static void *l1_phys_map[P_L1_SIZE]; static void io_mem_init(void); +static void memory_map_init(void); /* io memory support */ CPUWriteMemoryFunc *io_mem_write[IO_MEM_NB_ENTRIES][4]; @@ -572,6 +578,7 @@ void cpu_exec_init_all(unsigned long tb_size) code_gen_ptr = code_gen_buffer; page_init(); #if !defined(CONFIG_USER_ONLY) +memory_map_init(); io_mem_init(); #endif #if !defined(CONFIG_USER_ONLY) || !defined(CONFIG_USE_GUEST_BASE) @@ -3802,6 +3809,18 @@ static void io_mem_init(void) DEVICE_NATIVE_ENDIAN); } +static void memory_map_init(void) +{ +system_memory = qemu_malloc(sizeof(*system_memory)); +memory_region_init(system_memory, "system", UINT64_MAX); +set_system_memory_map(system_memory); +} + +MemoryRegion *get_system_memory(void) +{ +return system_memory; +} + #endif /* !defined(CONFIG_USER_ONLY) */ /* physical memory access (slow version, mainly for debug) */ -- 1.7.5.3
[Qemu-devel] [RFC v2 14/20] vmsvga: don't remember pci BAR address in callback any more
We're going to remove the callback, so we can't use it to save the address. Use the pci API instead. Signed-off-by: Avi Kivity --- hw/vmware_vga.c | 12 ++-- 1 files changed, 6 insertions(+), 6 deletions(-) diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c index 354c221..190b005 100644 --- a/hw/vmware_vga.c +++ b/hw/vmware_vga.c @@ -52,8 +52,6 @@ struct vmsvga_state_s { int on; } cursor; -target_phys_addr_t vram_base; - int index; int scratch_size; uint32_t *scratch; @@ -761,8 +759,11 @@ static uint32_t vmsvga_value_read(void *opaque, uint32_t address) case SVGA_REG_BYTES_PER_LINE: return ((s->depth + 7) >> 3) * s->new_width; -case SVGA_REG_FB_START: -return s->vram_base; +case SVGA_REG_FB_START: { +struct pci_vmsvga_state_s *pci_vmsvga += container_of(s, struct pci_vmsvga_state_s, chip); +return pci_get_bar_addr(&pci_vmsvga->card, 1); +} case SVGA_REG_FB_OFFSET: return 0x0; @@ -1247,14 +1248,13 @@ static void pci_vmsvga_map_mem(PCIDevice *pci_dev, int region_num, struct vmsvga_state_s *s = &d->chip; ram_addr_t iomemtype; -s->vram_base = addr; #ifdef DIRECT_VRAM iomemtype = cpu_register_io_memory(vmsvga_vram_read, vmsvga_vram_write, s, DEVICE_NATIVE_ENDIAN); #else iomemtype = s->vga.vram_offset | IO_MEM_RAM; #endif -cpu_register_physical_memory(s->vram_base, s->vga.vram_size, +cpu_register_physical_memory(addr, s->vga.vram_size, iomemtype); s->vga.map_addr = addr; -- 1.7.5.3
[Qemu-devel] [RFC v2 17/20] cirrus: simplify bitblt BAR access functions
Make use of the memory API's ability to satisfy multi-byte accesses via multiple single-byte accesses. Signed-off-by: Avi Kivity --- hw/cirrus_vga.c | 87 ++ 1 files changed, 16 insertions(+), 71 deletions(-) diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c index 0cb34d9..6312c6e 100644 --- a/hw/cirrus_vga.c +++ b/hw/cirrus_vga.c @@ -2445,39 +2445,27 @@ static void cirrus_linear_write(MemoryRegion *mr, target_phys_addr_t addr, ***/ -static uint32_t cirrus_linear_bitblt_readb(void *opaque, target_phys_addr_t addr) +static uint64_t cirrus_linear_bitblt_read(MemoryRegion *mr, + target_phys_addr_t addr, + unsigned size) { +CirrusVGAState *s = container_of(mr, CirrusVGAState, + cirrus_linear_bitblt_io); uint32_t ret; /* XXX handle bitblt */ +(void)s; ret = 0xff; return ret; } -static uint32_t cirrus_linear_bitblt_readw(void *opaque, target_phys_addr_t addr) -{ -uint32_t v; - -v = cirrus_linear_bitblt_readb(opaque, addr); -v |= cirrus_linear_bitblt_readb(opaque, addr + 1) << 8; -return v; -} - -static uint32_t cirrus_linear_bitblt_readl(void *opaque, target_phys_addr_t addr) -{ -uint32_t v; - -v = cirrus_linear_bitblt_readb(opaque, addr); -v |= cirrus_linear_bitblt_readb(opaque, addr + 1) << 8; -v |= cirrus_linear_bitblt_readb(opaque, addr + 2) << 16; -v |= cirrus_linear_bitblt_readb(opaque, addr + 3) << 24; -return v; -} - -static void cirrus_linear_bitblt_writeb(void *opaque, target_phys_addr_t addr, -uint32_t val) +static void cirrus_linear_bitblt_write(MemoryRegion *mr, + target_phys_addr_t addr, + uint64_t val, + unsigned size) { -CirrusVGAState *s = opaque; +CirrusVGAState *s = container_of(mr, CirrusVGAState, + cirrus_linear_bitblt_io); if (s->cirrus_srcptr != s->cirrus_srcptr_end) { /* bitblt */ @@ -2488,57 +2476,14 @@ static void cirrus_linear_bitblt_writeb(void *opaque, target_phys_addr_t addr, } } -static void cirrus_linear_bitblt_writew(void *opaque, target_phys_addr_t addr, -uint32_t val) -{ -cirrus_linear_bitblt_writeb(opaque, addr, val & 0xff); -cirrus_linear_bitblt_writeb(opaque, addr + 1, (val >> 8) & 0xff); -} - -static void cirrus_linear_bitblt_writel(void *opaque, target_phys_addr_t addr, -uint32_t val) -{ -cirrus_linear_bitblt_writeb(opaque, addr, val & 0xff); -cirrus_linear_bitblt_writeb(opaque, addr + 1, (val >> 8) & 0xff); -cirrus_linear_bitblt_writeb(opaque, addr + 2, (val >> 16) & 0xff); -cirrus_linear_bitblt_writeb(opaque, addr + 3, (val >> 24) & 0xff); -} - -static uint64_t cirrus_linear_bitblt_read(MemoryRegion *mr, - target_phys_addr_t addr, - unsigned size) -{ -CirrusVGAState *s = container_of(mr, CirrusVGAState, - cirrus_linear_bitblt_io); - -switch (size) { -case 1: return cirrus_linear_bitblt_readb(s, addr); -case 2: return cirrus_linear_bitblt_readw(s, addr); -case 4: return cirrus_linear_bitblt_readl(s, addr); -default: abort(); -} -}; - -static void cirrus_linear_bitblt_write(MemoryRegion *mr, - target_phys_addr_t addr, - uint64_t data, - unsigned size) -{ -CirrusVGAState *s = container_of(mr, CirrusVGAState, - cirrus_linear_bitblt_io); - -switch (size) { -case 1: return cirrus_linear_bitblt_writeb(s, addr, data); -case 2: return cirrus_linear_bitblt_writew(s, addr, data); -case 4: return cirrus_linear_bitblt_writel(s, addr, data); -default: abort(); -} -}; - static MemoryRegionOps cirrus_linear_bitblt_io_ops = { .read = cirrus_linear_bitblt_read, .write = cirrus_linear_bitblt_write, .endianness = DEVICE_LITTLE_ENDIAN, +.impl = { +.min_access_size = 1, +.max_access_size = 1, +}, }; #include "exec-memory.h" -- 1.7.5.3
[Qemu-devel] [RFC v2 07/20] pc: convert pc_memory_init() to memory API
Signed-off-by: Avi Kivity --- hw/pc.c | 59 --- hw/pc.h |1 + 2 files changed, 41 insertions(+), 19 deletions(-) diff --git a/hw/pc.c b/hw/pc.c index 369566a..1c9d89a 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -41,6 +41,7 @@ #include "sysemu.h" #include "blockdev.h" #include "ui/qemu-spice.h" +#include "memory.h" /* output Bochs bios info messages */ //#define DEBUG_BIOS @@ -966,22 +967,30 @@ void pc_memory_init(MemoryRegion *system_memory, { char *filename; int ret, linux_boot, i; -ram_addr_t ram_addr, bios_offset, option_rom_offset; +MemoryRegion *ram, *bios, *isa_bios, *option_rom_mr; +MemoryRegion *ram_below_4g, *ram_above_4g; int bios_size, isa_bios_size; void *fw_cfg; linux_boot = (kernel_filename != NULL); -/* allocate RAM */ -ram_addr = qemu_ram_alloc(NULL, "pc.ram", - below_4g_mem_size + above_4g_mem_size); -cpu_register_physical_memory(0, 0xa, ram_addr); -cpu_register_physical_memory(0x10, - below_4g_mem_size - 0x10, - ram_addr + 0x10); +/* Allocate RAM. We allocate it as a single memory region and use + * aliases to address portions of it, mostly for backwards compatiblity + * with older qemus that used qemu_ram_alloc(). + */ +ram = qemu_malloc(sizeof(*ram)); +memory_region_init_ram(ram, NULL, "pc.ram", + below_4g_mem_size + above_4g_mem_size); +ram_below_4g = qemu_malloc(sizeof(*ram_below_4g)); +memory_region_init_alias(ram_below_4g, "ram-below-4g", ram, + 0, below_4g_mem_size); +memory_region_add_subregion(system_memory, 0, ram_below_4g); if (above_4g_mem_size > 0) { -cpu_register_physical_memory(0x1ULL, above_4g_mem_size, - ram_addr + below_4g_mem_size); +ram_above_4g = qemu_malloc(sizeof(*ram_above_4g)); +memory_region_init_alias(ram_above_4g, "ram-above-4g", ram, + below_4g_mem_size, above_4g_mem_size); +memory_region_add_subregion(system_memory, 0x1ULL, +ram_above_4g); } /* BIOS load */ @@ -997,7 +1006,9 @@ void pc_memory_init(MemoryRegion *system_memory, (bios_size % 65536) != 0) { goto bios_error; } -bios_offset = qemu_ram_alloc(NULL, "pc.bios", bios_size); +bios = qemu_malloc(sizeof(*bios)); +memory_region_init_ram(bios, NULL, "pc.bios", bios_size); +memory_region_set_readonly(bios, true); ret = rom_add_file_fixed(bios_name, (uint32_t)(-bios_size), -1); if (ret != 0) { bios_error: @@ -1011,16 +1022,26 @@ void pc_memory_init(MemoryRegion *system_memory, isa_bios_size = bios_size; if (isa_bios_size > (128 * 1024)) isa_bios_size = 128 * 1024; -cpu_register_physical_memory(0x10 - isa_bios_size, - isa_bios_size, - (bios_offset + bios_size - isa_bios_size) | IO_MEM_ROM); - -option_rom_offset = qemu_ram_alloc(NULL, "pc.rom", PC_ROM_SIZE); -cpu_register_physical_memory(PC_ROM_MIN_VGA, PC_ROM_SIZE, option_rom_offset); +isa_bios = qemu_malloc(sizeof(*isa_bios)); +memory_region_init_alias(isa_bios, "isa-bios", bios, + bios_size - isa_bios_size, isa_bios_size); +memory_region_add_subregion_overlap(system_memory, +0x10 - isa_bios_size, +isa_bios, +1); +memory_region_set_readonly(isa_bios, true); + +option_rom_mr = qemu_malloc(sizeof(*option_rom_mr)); +memory_region_init_ram(option_rom_mr, NULL, "pc.rom", PC_ROM_SIZE); +memory_region_add_subregion_overlap(system_memory, +PC_ROM_MIN_VGA, +option_rom_mr, +1); /* map all the bios at the top of memory */ -cpu_register_physical_memory((uint32_t)(-bios_size), - bios_size, bios_offset | IO_MEM_ROM); +memory_region_add_subregion(system_memory, +(uint32_t)(-bios_size), +bios); fw_cfg = bochs_bios_init(); rom_set_fw(fw_cfg); diff --git a/hw/pc.h b/hw/pc.h index fa57583..40684f4 100644 --- a/hw/pc.h +++ b/hw/pc.h @@ -2,6 +2,7 @@ #define HW_PC_H #include "qemu-common.h" +#include "memory.h" #include "ioport.h" #include "isa.h" #include "fdc.h" -- 1.7.5.3
[Qemu-devel] [RFC v2 18/20] cirrus: simplify vga window mmio access functions
Make use of the memory API's ability to satisfy multi-byte accesses via multiple single-byte accesses. Signed-off-by: Avi Kivity --- hw/cirrus_vga.c | 83 -- 1 files changed, 13 insertions(+), 70 deletions(-) diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c index 6312c6e..6e9e83d 100644 --- a/hw/cirrus_vga.c +++ b/hw/cirrus_vga.c @@ -1955,9 +1955,11 @@ static void cirrus_mem_writeb_mode4and5_16bpp(CirrusVGAState * s, * ***/ -static uint32_t cirrus_vga_mem_readb(void *opaque, target_phys_addr_t addr) +static uint64_t cirrus_vga_mem_read(MemoryRegion *mr, +target_phys_addr_t addr, +uint32_t size) { -CirrusVGAState *s = opaque; +CirrusVGAState *s = container_of(mr, CirrusVGAState, low_mem); unsigned bank_index; unsigned bank_offset; uint32_t val; @@ -1966,8 +1968,6 @@ static uint32_t cirrus_vga_mem_readb(void *opaque, target_phys_addr_t addr) return vga_mem_readb(s, addr); } -addr &= 0x1; - if (addr < 0x1) { /* XXX handle bitblt */ /* video memory */ @@ -1999,30 +1999,12 @@ static uint32_t cirrus_vga_mem_readb(void *opaque, target_phys_addr_t addr) return val; } -static uint32_t cirrus_vga_mem_readw(void *opaque, target_phys_addr_t addr) +static void cirrus_vga_mem_write(MemoryRegion *mr, + target_phys_addr_t addr, + uint64_t mem_value, + uint32_t size) { -uint32_t v; - -v = cirrus_vga_mem_readb(opaque, addr); -v |= cirrus_vga_mem_readb(opaque, addr + 1) << 8; -return v; -} - -static uint32_t cirrus_vga_mem_readl(void *opaque, target_phys_addr_t addr) -{ -uint32_t v; - -v = cirrus_vga_mem_readb(opaque, addr); -v |= cirrus_vga_mem_readb(opaque, addr + 1) << 8; -v |= cirrus_vga_mem_readb(opaque, addr + 2) << 16; -v |= cirrus_vga_mem_readb(opaque, addr + 3) << 24; -return v; -} - -static void cirrus_vga_mem_writeb(void *opaque, target_phys_addr_t addr, - uint32_t mem_value) -{ -CirrusVGAState *s = opaque; +CirrusVGAState *s = container_of(mr, CirrusVGAState, low_mem); unsigned bank_index; unsigned bank_offset; unsigned mode; @@ -2032,8 +2014,6 @@ static void cirrus_vga_mem_writeb(void *opaque, target_phys_addr_t addr, return; } -addr &= 0x1; - if (addr < 0x1) { if (s->cirrus_srcptr != s->cirrus_srcptr_end) { /* bitblt */ @@ -2083,51 +2063,14 @@ static void cirrus_vga_mem_writeb(void *opaque, target_phys_addr_t addr, } } -static void cirrus_vga_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val) -{ -cirrus_vga_mem_writeb(opaque, addr, val & 0xff); -cirrus_vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff); -} - -static void cirrus_vga_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val) -{ -cirrus_vga_mem_writeb(opaque, addr, val & 0xff); -cirrus_vga_mem_writeb(opaque, addr + 1, (val >> 8) & 0xff); -cirrus_vga_mem_writeb(opaque, addr + 2, (val >> 16) & 0xff); -cirrus_vga_mem_writeb(opaque, addr + 3, (val >> 24) & 0xff); -} - -static uint64_t cirrus_vga_mem_read(MemoryRegion *mr, -target_phys_addr_t addr, -uint32_t size) -{ -CirrusVGAState *s = container_of(mr, CirrusVGAState, low_mem); - -switch (size) { -case 1: return cirrus_vga_mem_readb(s, addr); -case 2: return cirrus_vga_mem_readw(s, addr); -case 4: return cirrus_vga_mem_readl(s, addr); -default: abort(); -} -} - -static void cirrus_vga_mem_write(MemoryRegion *mr, target_phys_addr_t addr, - uint64_t data, unsigned size) -{ -CirrusVGAState *s = container_of(mr, CirrusVGAState, low_mem); - -switch (size) { -case 1: return cirrus_vga_mem_writeb(s, addr, data); -case 2: return cirrus_vga_mem_writew(s, addr, data); -case 4: return cirrus_vga_mem_writel(s, addr, data); -default: abort(); -} -}; - static MemoryRegionOps cirrus_vga_mem_ops = { .read = cirrus_vga_mem_read, .write = cirrus_vga_mem_write, .endianness = DEVICE_LITTLE_ENDIAN, +.impl = { +.min_access_size = 1, +.max_access_size = 1, +}, }; /*** -- 1.7.5.3
[Qemu-devel] [RFC v2 08/20] pc: move global memory map out of pc_init1() and into its callers
Signed-off-by: Avi Kivity --- hw/pc_piix.c | 15 --- 1 files changed, 8 insertions(+), 7 deletions(-) diff --git a/hw/pc_piix.c b/hw/pc_piix.c index d83854c..f2d0476 100644 --- a/hw/pc_piix.c +++ b/hw/pc_piix.c @@ -68,7 +68,8 @@ static void ioapic_init(IsaIrqState *isa_irq_state) } /* PC hardware initialisation */ -static void pc_init1(ram_addr_t ram_size, +static void pc_init1(MemoryRegion *system_memory, + ram_addr_t ram_size, const char *boot_device, const char *kernel_filename, const char *kernel_cmdline, @@ -91,9 +92,6 @@ static void pc_init1(ram_addr_t ram_size, DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; BusState *idebus[MAX_IDE_BUS]; ISADevice *rtc_state; -MemoryRegion *system_memory; - -system_memory = get_system_memory(); pc_cpus_init(cpu_model); @@ -214,7 +212,8 @@ static void pc_init_pci(ram_addr_t ram_size, const char *initrd_filename, const char *cpu_model) { -pc_init1(ram_size, boot_device, +pc_init1(get_system_memory(), + ram_size, boot_device, kernel_filename, kernel_cmdline, initrd_filename, cpu_model, 1, 1); } @@ -226,7 +225,8 @@ static void pc_init_pci_no_kvmclock(ram_addr_t ram_size, const char *initrd_filename, const char *cpu_model) { -pc_init1(ram_size, boot_device, +pc_init1(get_system_memory(), + ram_size, boot_device, kernel_filename, kernel_cmdline, initrd_filename, cpu_model, 1, 0); } @@ -240,7 +240,8 @@ static void pc_init_isa(ram_addr_t ram_size, { if (cpu_model == NULL) cpu_model = "486"; -pc_init1(ram_size, boot_device, +pc_init1(get_system_memory(), + ram_size, boot_device, kernel_filename, kernel_cmdline, initrd_filename, cpu_model, 0, 1); } -- 1.7.5.3
[Qemu-devel] [RFC v2 02/20] memory: implement dirty tracking
Currently dirty tracking is implemented by passing through all calls to the underlying cpu_physical_memory_*() calls. Signed-off-by: Avi Kivity --- memory.c | 39 +++ memory.h |1 + 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/memory.c b/memory.c index 43499c3..d962fff 100644 --- a/memory.c +++ b/memory.c @@ -69,6 +69,7 @@ struct FlatRange { MemoryRegion *mr; target_phys_addr_t offset_in_region; AddrRange addr; +uint8_t dirty_log_mask; }; /* Flattened global view of current active memory hierarchy. Kept in sorted @@ -177,6 +178,7 @@ static void render_memory_region(FlatView *view, fr.mr = mr; fr.offset_in_region = offset_in_region; fr.addr = addrrange_make(base, now); +fr.dirty_log_mask = mr->dirty_log_mask; flatview_insert(view, i, &fr); ++i; base += now; @@ -194,6 +196,7 @@ static void render_memory_region(FlatView *view, fr.mr = mr; fr.offset_in_region = offset_in_region; fr.addr = addrrange_make(base, remain); +fr.dirty_log_mask = mr->dirty_log_mask; flatview_insert(view, i, &fr); } } @@ -247,9 +250,14 @@ static void memory_region_update_topology(void) } else if (frold && frnew && flatrange_equal(frold, frnew)) { /* In both (logging may have changed) */ +if (frold->dirty_log_mask && !frnew->dirty_log_mask) { +cpu_physical_log_stop(frnew->addr.start, frnew->addr.size); +} else if (frnew->dirty_log_mask && !frold->dirty_log_mask) { +cpu_physical_log_start(frnew->addr.start, frnew->addr.size); +} + ++iold; ++inew; -/* FIXME: dirty logging */ } else { /* In new */ @@ -267,7 +275,7 @@ static void memory_region_update_topology(void) frnew->addr.size, phys_offset, region_offset, - 0); + frnew->dirty_log_mask); ++inew; } } @@ -292,6 +300,7 @@ void memory_region_init(MemoryRegion *mr, memset(&mr->subregions_link, 0, sizeof mr->subregions_link); QTAILQ_INIT(&mr->coalesced); mr->name = qemu_strdup(name); +mr->dirty_log_mask = 0; } static bool memory_region_access_valid(MemoryRegion *mr, @@ -494,24 +503,35 @@ void memory_region_set_offset(MemoryRegion *mr, target_phys_addr_t offset) void memory_region_set_log(MemoryRegion *mr, bool log, unsigned client) { -/* FIXME */ +uint8_t mask = 1 << client; + +mr->dirty_log_mask = (mr->dirty_log_mask & ~mask) | (log * mask); +memory_region_update_topology(); } bool memory_region_get_dirty(MemoryRegion *mr, target_phys_addr_t addr, unsigned client) { -/* FIXME */ -return true; +assert(mr->has_ram_addr); +return cpu_physical_memory_get_dirty(mr->ram_addr + addr, 1 << client); } void memory_region_set_dirty(MemoryRegion *mr, target_phys_addr_t addr) { -/* FIXME */ +assert(mr->has_ram_addr); +return cpu_physical_memory_set_dirty(mr->ram_addr + addr); } void memory_region_sync_dirty_bitmap(MemoryRegion *mr) { -/* FIXME */ +FlatRange *fr; + +FOR_EACH_FLAT_RANGE(fr, ¤t_memory_map) { +if (fr->mr == mr) { +cpu_physical_sync_dirty_bitmap(fr->addr.start, + fr->addr.start + fr->addr.size); +} +} } void memory_region_set_readonly(MemoryRegion *mr, bool readonly) @@ -522,7 +542,10 @@ void memory_region_set_readonly(MemoryRegion *mr, bool readonly) void memory_region_reset_dirty(MemoryRegion *mr, target_phys_addr_t addr, target_phys_addr_t size, unsigned client) { -/* FIXME */ +assert(mr->has_ram_addr); +cpu_physical_memory_reset_dirty(mr->ram_addr + addr, +mr->ram_addr + addr + size, +1 << client); } void *memory_region_get_ram_ptr(MemoryRegion *mr) diff --git a/memory.h b/memory.h index a67ff94..2bf9625 100644 --- a/memory.h +++ b/memory.h @@ -85,6 +85,7 @@ struct MemoryRegion { QTAILQ_ENTRY(MemoryRegion) subregions_link; QTAILQ_HEAD(coalesced_ranges, CoalescedMemoryRange) coalesced; const char *name; +uint8_t dirty_log_mask; }; /* Initialize a memory region -- 1.7.5.3
[Qemu-devel] [RFC v2 06/20] pc: grab system_memory
While eventually this should come from the machine initialization function, take a short cut to avoid converting all machines now. Signed-off-by: Avi Kivity --- hw/pc.c |3 ++- hw/pc.h |4 +++- hw/pc_piix.c |8 +++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/hw/pc.c b/hw/pc.c index a3e8539..369566a 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -957,7 +957,8 @@ void pc_cpus_init(const char *cpu_model) } } -void pc_memory_init(const char *kernel_filename, +void pc_memory_init(MemoryRegion *system_memory, +const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, ram_addr_t below_4g_mem_size, diff --git a/hw/pc.h b/hw/pc.h index 6d5730b..fa57583 100644 --- a/hw/pc.h +++ b/hw/pc.h @@ -6,6 +6,7 @@ #include "isa.h" #include "fdc.h" #include "net.h" +#include "memory.h" /* PC-style peripherals (also used by other machines). */ @@ -129,7 +130,8 @@ void pc_cmos_set_s3_resume(void *opaque, int irq, int level); void pc_acpi_smi_interrupt(void *opaque, int irq, int level); void pc_cpus_init(const char *cpu_model); -void pc_memory_init(const char *kernel_filename, +void pc_memory_init(MemoryRegion *system_memory, +const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, ram_addr_t below_4g_mem_size, diff --git a/hw/pc_piix.c b/hw/pc_piix.c index c5c16b4..d83854c 100644 --- a/hw/pc_piix.c +++ b/hw/pc_piix.c @@ -39,6 +39,8 @@ #include "blockdev.h" #include "smbus.h" #include "xen.h" +#include "memory.h" +#include "exec-memory.h" #ifdef CONFIG_XEN # include #endif @@ -89,6 +91,9 @@ static void pc_init1(ram_addr_t ram_size, DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; BusState *idebus[MAX_IDE_BUS]; ISADevice *rtc_state; +MemoryRegion *system_memory; + +system_memory = get_system_memory(); pc_cpus_init(cpu_model); @@ -106,7 +111,8 @@ static void pc_init1(ram_addr_t ram_size, /* allocate ram and load rom/bios */ if (!xen_enabled()) { -pc_memory_init(kernel_filename, kernel_cmdline, initrd_filename, +pc_memory_init(system_memory, + kernel_filename, kernel_cmdline, initrd_filename, below_4g_mem_size, above_4g_mem_size); } -- 1.7.5.3
[Qemu-devel] [PATCH] Add e500 instructions dcblc, dcbtls and dcbtstl as no-op
Signed-off-by: Fabien Chouteau --- target-ppc/translate.c | 21 + 1 files changed, 21 insertions(+), 0 deletions(-) diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 0a03b44..d0ca821 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -3995,6 +3995,24 @@ static void gen_dcbt(DisasContext *ctx) */ } +/* dcblc */ +static void gen_dcblc(DisasContext *ctx) +{ +/* interpreted as no-op */ +} + +/* dcbtls */ +static void gen_dcbtls(DisasContext *ctx) +{ +/* interpreted as no-op */ +} + +/* dcbtstls */ +static void gen_dcbtstls(DisasContext *ctx) +{ +/* interpreted as no-op */ +} + /* dcbtst */ static void gen_dcbtst(DisasContext *ctx) { @@ -8404,6 +8422,9 @@ GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E1, PPC_CACHE), GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E1, PPC_CACHE), GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x0201, PPC_CACHE), GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x0201, PPC_CACHE), +GEN_HANDLER(dcblc, 0x1F, 0x6, 0x0C, 0x0201, PPC_CACHE), +GEN_HANDLER(dcbtls, 0x1F, 0x6, 0x05, 0x0201, PPC_CACHE), +GEN_HANDLER(dcbtstls, 0x1F, 0x6, 0x04, 0x0201, PPC_CACHE), GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03E1, PPC_CACHE_DCBZ), GEN_HANDLER2(dcbz_970, "dcbz", 0x1F, 0x16, 0x1F, 0x03C1, PPC_CACHE_DCBZT), GEN_HANDLER(dst, 0x1F, 0x16, 0x0A, 0x0181, PPC_ALTIVEC), -- 1.7.4.1
Re: [Qemu-devel] [PATCH 0/4] A few cleanups of qdev users
Amit Shah writes: > On (Fri) 24 Jun 2011 [13:57:28], Markus Armbruster wrote: >> Ping? > > There were a couple of things: > >> port 0, guest on, host off, throttle off > > guest on/off, host on/off doesn't convey much -- what's on/off? > > Also, 'throttle' could be 'thottled'? Discussion petered out with my message[*]: I chose on/off to stay consistent with how qdev shows bool properties (print_bit() in qdev-properties.c). May be misguided. Like you, I'm having difficulties coming up with a better version that is still consise. But: should "info qtree" show such device state? It's about configuration of the device tree, isn't it? Connection status is useful to know, but it's not device configuration. Other print_dev() methods may cross that line, too. For instance, usb_bus_dev_print() prints attached, which looks suspicious (commit 66a6593a). Should info qtree continue to show this information? If yes, care to suggest a better format? [*] http://lists.gnu.org/archive/html/qemu-devel/2011-05/msg01919.html
[Qemu-devel] [PATCH] Make SLIRP Ethernet packets size to 64 bytes minimum
Signed-off-by: Fabien Chouteau --- slirp/slirp.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/slirp/slirp.c b/slirp/slirp.c index 1593be1..be30501 100644 --- a/slirp/slirp.c +++ b/slirp/slirp.c @@ -697,7 +697,7 @@ void if_encap(Slirp *slirp, const uint8_t *ip_data, int ip_data_len) return; if (!memcmp(slirp->client_ethaddr, zero_ethaddr, ETH_ALEN)) { -uint8_t arp_req[ETH_HLEN + sizeof(struct arphdr)]; +uint8_t arp_req[max(ETH_HLEN + sizeof(struct arphdr), 64)]; struct ethhdr *reh = (struct ethhdr *)arp_req; struct arphdr *rah = (struct arphdr *)(arp_req + ETH_HLEN); const struct ip *iph = (const struct ip *)ip_data; @@ -734,7 +734,7 @@ void if_encap(Slirp *slirp, const uint8_t *ip_data, int ip_data_len) memcpy(&eh->h_source[2], &slirp->vhost_addr, 4); eh->h_proto = htons(ETH_P_IP); memcpy(buf + sizeof(struct ethhdr), ip_data, ip_data_len); -slirp_output(slirp->opaque, buf, ip_data_len + ETH_HLEN); +slirp_output(slirp->opaque, buf, max(ip_data_len + ETH_HLEN, 64)); } } -- 1.7.4.1
[Qemu-devel] Build break in current -git.
In file included from /usr/include/png.h:510, from ui/vnc-enc-tight.c:37: /usr/include/pngconf.h:371: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘.’ token /usr/include/pngconf.h:372: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘include’ make: *** [ui/vnc-enc-tight.o] Error 1 Building on an Ubuntu 10.04 stock install. Relevant chunk of said header: # ifndef PNG_SKIP_SETJMP_CHECK #ifdef __linux__ # ifdef _BSD_SOURCE #define PNG_SAVE_BSD_SOURCE #undef _BSD_SOURCE # endif # ifdef _SETJMP_H /* If you encounter a compiler error here, see the explanation * near the end of INSTALL. */ __pngconf.h__ in libpng already includes setjmp.h; __dont__ include it again.; # endif #endif /* __linux__ */ # endif /* PNG_SKIP_SETJMP_CHECK */ Rob