Opensuse 2.6 [MS: BSC#1008519] #12

Closed
hramrach wants to merge 58 commits from opensuse-2.6 into opensuse-2.6
64 changed files with 6444 additions and 173 deletions

View File

@@ -36,6 +36,10 @@ endif
PROGS=$(QEMU_PROG) $(QEMU_PROGW)
STPFILES=
ifdef CONFIG_LINUX_USER
PROGS+=$(QEMU_PROG)-binfmt
endif
config-target.h: config-target.h-timestamp
config-target.h-timestamp: config-target.mak
@@ -113,6 +117,8 @@ QEMU_CFLAGS+=-I$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR) -I$(SRC_PATH)/linux-user
obj-y += linux-user/
obj-y += gdbstub.o thunk.o user-exec.o
obj-binfmt-y += linux-user/
endif #CONFIG_LINUX_USER
#########################################################
@@ -161,7 +167,11 @@ endif # CONFIG_SOFTMMU
# Workaround for http://gcc.gnu.org/PR55489, see configure.
%/translate.o: QEMU_CFLAGS += $(TRANSLATE_OPT_CFLAGS)
ifdef CONFIG_LINUX_USER
dummy := $(call unnest-vars,,obj-y obj-binfmt-y)
else
dummy := $(call unnest-vars,,obj-y)
endif
all-obj-y := $(obj-y)
target-obj-y :=
@@ -198,6 +208,9 @@ ifdef CONFIG_DARWIN
$(call quiet-command,SetFile -a C $@," SETFILE $(TARGET_DIR)$@")
endif
$(QEMU_PROG)-binfmt: $(obj-binfmt-y)
$(call LINK,$^)
gdbstub-xml.c: $(TARGET_XML_FILES) $(SRC_PATH)/scripts/feature_to_c.sh
$(call quiet-command,rm -f $@ && $(SHELL) $(SRC_PATH)/scripts/feature_to_c.sh $@ $(TARGET_XML_FILES)," GEN $(TARGET_DIR)$@")

View File

@@ -3588,6 +3588,9 @@ void bdrv_img_create(const char *filename, const char *fmt,
if (!quiet) {
printf("Formatting '%s', fmt=%s ", filename, fmt);
qemu_opts_print(opts, " ");
if (qemu_opt_get_bool(opts, BLOCK_OPT_SCSI, false)) {
printf(", SCSI");
}
puts("");
}

View File

@@ -21,6 +21,8 @@ block-obj-$(CONFIG_GLUSTERFS) += gluster.o
block-obj-$(CONFIG_ARCHIPELAGO) += archipelago.o
block-obj-$(CONFIG_LIBSSH2) += ssh.o
block-obj-y += accounting.o dirty-bitmap.o
block-obj-y += dictzip.o
block-obj-y += tar.o
block-obj-y += write-threshold.o
block-obj-y += crypto.o

586
block/dictzip.c Normal file
View File

@@ -0,0 +1,586 @@
/*
* DictZip Block driver for dictzip enabled gzip files
*
* Use the "dictzip" tool from the "dictd" package to create gzip files that
* contain the extra DictZip headers.
*
* dictzip(1) is a compression program which creates compressed files in the
* gzip format (see RFC 1952). However, unlike gzip(1), dictzip(1) compresses
* the file in pieces and stores an index to the pieces in the gzip header.
* This allows random access to the file at the granularity of the compressed
* pieces (currently about 64kB) while maintaining good compression ratios
* (within 5% of the expected ratio for dictionary data).
* dictd(8) uses files stored in this format.
*
* For details on DictZip see http://dict.org/.
*
* Copyright (c) 2009 Alexander Graf <agraf@suse.de>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu-common.h"
#include "block/block_int.h"
#include <zlib.h>
// #define DEBUG
#ifdef DEBUG
#define dprintf(fmt, ...) do { printf("dzip: " fmt, ## __VA_ARGS__); } while (0)
#else
#define dprintf(fmt, ...) do { } while (0)
#endif
#define SECTOR_SIZE 512
#define Z_STREAM_COUNT 4
#define CACHE_COUNT 20
/* magic values */
#define GZ_MAGIC1 0x1f
#define GZ_MAGIC2 0x8b
#define DZ_MAGIC1 'R'
#define DZ_MAGIC2 'A'
#define GZ_FEXTRA 0x04 /* Optional field (random access index) */
#define GZ_FNAME 0x08 /* Original name */
#define GZ_COMMENT 0x10 /* Zero-terminated, human-readable comment */
#define GZ_FHCRC 0x02 /* Header CRC16 */
/* offsets */
#define GZ_ID 0 /* GZ_MAGIC (16bit) */
#define GZ_FLG 3 /* FLaGs (see above) */
#define GZ_XLEN 10 /* eXtra LENgth (16bit) */
#define GZ_SI 12 /* Subfield ID (16bit) */
#define GZ_VERSION 16 /* Version for subfield format */
#define GZ_CHUNKSIZE 18 /* Chunk size (16bit) */
#define GZ_CHUNKCNT 20 /* Number of chunks (16bit) */
#define GZ_RNDDATA 22 /* Random access data (16bit) */
#define GZ_99_CHUNKSIZE 18 /* Chunk size (32bit) */
#define GZ_99_CHUNKCNT 22 /* Number of chunks (32bit) */
#define GZ_99_FILESIZE 26 /* Size of unpacked file (64bit) */
#define GZ_99_RNDDATA 34 /* Random access data (32bit) */
struct BDRVDictZipState;
typedef struct DictZipAIOCB {
BlockAIOCB common;
struct BDRVDictZipState *s;
QEMUIOVector *qiov; /* QIOV of the original request */
QEMUIOVector *qiov_gz; /* QIOV of the gz subrequest */
QEMUBH *bh; /* BH for cache */
z_stream *zStream; /* stream to use for decoding */
int zStream_id; /* stream id of the above pointer */
size_t start; /* offset into the uncompressed file */
size_t len; /* uncompressed bytes to read */
uint8_t *gzipped; /* the gzipped data */
uint8_t *buf; /* cached result */
size_t gz_len; /* amount of gzip data */
size_t gz_start; /* uncompressed starting point of gzip data */
uint64_t offset; /* offset for "start" into the uncompressed chunk */
int chunks_len; /* amount of uncompressed data in all gzip data */
} DictZipAIOCB;
typedef struct dict_cache {
size_t start;
size_t len;
uint8_t *buf;
} DictCache;
typedef struct BDRVDictZipState {
BlockDriverState *hd;
z_stream zStream[Z_STREAM_COUNT];
DictCache cache[CACHE_COUNT];
int cache_index;
uint8_t stream_in_use;
uint64_t chunk_len;
uint32_t chunk_cnt;
uint16_t *chunks;
uint32_t *chunks32;
uint64_t *offsets;
int64_t file_len;
} BDRVDictZipState;
static int start_zStream(z_stream *zStream)
{
zStream->zalloc = NULL;
zStream->zfree = NULL;
zStream->opaque = NULL;
zStream->next_in = 0;
zStream->avail_in = 0;
zStream->next_out = NULL;
zStream->avail_out = 0;
return inflateInit2( zStream, -15 );
}
static QemuOptsList runtime_opts = {
.name = "dzip",
.head = QTAILQ_HEAD_INITIALIZER(runtime_opts.head),
.desc = {
{
.name = "filename",
.type = QEMU_OPT_STRING,
.help = "URL to the dictzip file",
},
{ /* end of list */ }
},
};
static int dictzip_open(BlockDriverState *bs, QDict *options, int flags, Error **errp)
{
BDRVDictZipState *s = bs->opaque;
const char *err = "Unknown (read error?)";
uint8_t magic[2];
char buf[100];
uint8_t header_flags;
uint16_t chunk_len16;
uint16_t chunk_cnt16;
uint32_t chunk_len32;
uint16_t header_ver;
uint16_t tmp_short;
uint64_t offset;
int chunks_len;
int headerLength = GZ_XLEN - 1;
int rnd_offs;
int ret;
int i;
QemuOpts *opts;
Error *local_err = NULL;
const char *filename;
opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err);
if (local_err != NULL) {
error_propagate(errp, local_err);
ret = -EINVAL;
goto fail;
}
filename = qemu_opt_get(opts, "filename");
if (!strncmp(filename, "dzip://", 7))
filename += 7;
else if (!strncmp(filename, "dzip:", 5))
filename += 5;
ret = bdrv_open(&s->hd, filename, NULL, NULL, flags | BDRV_O_PROTOCOL, &local_err);
if (ret < 0) {
error_propagate(errp, local_err);
qemu_opts_del(opts);
return ret;
}
/* initialize zlib streams */
for (i = 0; i < Z_STREAM_COUNT; i++) {
if (start_zStream( &s->zStream[i] ) != Z_OK) {
err = s->zStream[i].msg;
goto fail;
}
}
/* gzip header */
if (bdrv_pread(s->hd, GZ_ID, &magic, sizeof(magic)) != sizeof(magic))
goto fail;
if (!((magic[0] == GZ_MAGIC1) && (magic[1] == GZ_MAGIC2))) {
err = "No gzip file";
goto fail;
}
/* dzip header */
if (bdrv_pread(s->hd, GZ_FLG, &header_flags, 1) != 1)
goto fail;
if (!(header_flags & GZ_FEXTRA)) {
err = "Not a dictzip file (wrong flags)";
goto fail;
}
/* extra length */
if (bdrv_pread(s->hd, GZ_XLEN, &tmp_short, 2) != 2)
goto fail;
headerLength += le16_to_cpu(tmp_short) + 2;
/* DictZip magic */
if (bdrv_pread(s->hd, GZ_SI, &magic, 2) != 2)
goto fail;
if (magic[0] != DZ_MAGIC1 || magic[1] != DZ_MAGIC2) {
err = "Not a dictzip file (missing extra magic)";
goto fail;
}
/* DictZip version */
if (bdrv_pread(s->hd, GZ_VERSION, &header_ver, 2) != 2)
goto fail;
header_ver = le16_to_cpu(header_ver);
switch (header_ver) {
case 1: /* Normal DictZip */
/* number of chunks */
if (bdrv_pread(s->hd, GZ_CHUNKSIZE, &chunk_len16, 2) != 2)
goto fail;
s->chunk_len = le16_to_cpu(chunk_len16);
/* chunk count */
if (bdrv_pread(s->hd, GZ_CHUNKCNT, &chunk_cnt16, 2) != 2)
goto fail;
s->chunk_cnt = le16_to_cpu(chunk_cnt16);
chunks_len = sizeof(short) * s->chunk_cnt;
rnd_offs = GZ_RNDDATA;
break;
case 99: /* Special Alex pigz version */
/* number of chunks */
if (bdrv_pread(s->hd, GZ_99_CHUNKSIZE, &chunk_len32, 4) != 4)
goto fail;
dprintf("chunk len [%#x] = %d\n", GZ_99_CHUNKSIZE, chunk_len32);
s->chunk_len = le32_to_cpu(chunk_len32);
/* chunk count */
if (bdrv_pread(s->hd, GZ_99_CHUNKCNT, &s->chunk_cnt, 4) != 4)
goto fail;
s->chunk_cnt = le32_to_cpu(s->chunk_cnt);
dprintf("chunk len | count = %"PRId64" | %d\n", s->chunk_len, s->chunk_cnt);
/* file size */
if (bdrv_pread(s->hd, GZ_99_FILESIZE, &s->file_len, 8) != 8)
goto fail;
s->file_len = le64_to_cpu(s->file_len);
chunks_len = sizeof(int) * s->chunk_cnt;
rnd_offs = GZ_99_RNDDATA;
break;
default:
err = "Invalid DictZip version";
goto fail;
}
/* random access data */
s->chunks = g_malloc(chunks_len);
if (header_ver == 99)
s->chunks32 = (uint32_t *)s->chunks;
if (bdrv_pread(s->hd, rnd_offs, s->chunks, chunks_len) != chunks_len)
goto fail;
/* orig filename */
if (header_flags & GZ_FNAME) {
if (bdrv_pread(s->hd, headerLength + 1, buf, sizeof(buf)) != sizeof(buf))
goto fail;
buf[sizeof(buf) - 1] = '\0';
headerLength += strlen(buf) + 1;
if (strlen(buf) == sizeof(buf))
goto fail;
dprintf("filename: %s\n", buf);
}
/* comment field */
if (header_flags & GZ_COMMENT) {
if (bdrv_pread(s->hd, headerLength, buf, sizeof(buf)) != sizeof(buf))
goto fail;
buf[sizeof(buf) - 1] = '\0';
headerLength += strlen(buf) + 1;
if (strlen(buf) == sizeof(buf))
goto fail;
dprintf("comment: %s\n", buf);
}
if (header_flags & GZ_FHCRC)
headerLength += 2;
/* uncompressed file length*/
if (!s->file_len) {
uint32_t file_len;
if (bdrv_pread(s->hd, bdrv_getlength(s->hd) - 4, &file_len, 4) != 4)
goto fail;
s->file_len = le32_to_cpu(file_len);
}
/* compute offsets */
s->offsets = g_malloc(sizeof( *s->offsets ) * s->chunk_cnt);
for (offset = headerLength + 1, i = 0; i < s->chunk_cnt; i++) {
s->offsets[i] = offset;
switch (header_ver) {
case 1:
offset += le16_to_cpu(s->chunks[i]);
break;
case 99:
offset += le32_to_cpu(s->chunks32[i]);
break;
}
dprintf("chunk %#"PRIx64" - %#"PRIx64" = offset %#"PRIx64" -> %#"PRIx64"\n", i * s->chunk_len, (i+1) * s->chunk_len, s->offsets[i], offset);
}
qemu_opts_del(opts);
return 0;
fail:
fprintf(stderr, "DictZip: Error opening file: %s\n", err);
bdrv_unref(s->hd);
if (s->chunks)
g_free(s->chunks);
qemu_opts_del(opts);
return -EINVAL;
}
/* This callback gets invoked when we have the result in cache already */
static void dictzip_cache_cb(void *opaque)
{
DictZipAIOCB *acb = (DictZipAIOCB *)opaque;
qemu_iovec_from_buf(acb->qiov, 0, acb->buf, acb->len);
acb->common.cb(acb->common.opaque, 0);
qemu_bh_delete(acb->bh);
qemu_aio_unref(acb);
}
/* This callback gets invoked by the underlying block reader when we have
* all compressed data. We uncompress in here. */
static void dictzip_read_cb(void *opaque, int ret)
{
DictZipAIOCB *acb = (DictZipAIOCB *)opaque;
struct BDRVDictZipState *s = acb->s;
uint8_t *buf;
DictCache *cache;
int r, i;
buf = g_malloc(acb->chunks_len);
/* try to find zlib stream for decoding */
do {
for (i = 0; i < Z_STREAM_COUNT; i++) {
if (!(s->stream_in_use & (1 << i))) {
s->stream_in_use |= (1 << i);
acb->zStream_id = i;
acb->zStream = &s->zStream[i];
break;
}
}
} while(!acb->zStream);
/* sure, we could handle more streams, but this callback should be single
threaded and when it's not, we really want to know! */
assert(i == 0);
/* uncompress the chunk */
acb->zStream->next_in = acb->gzipped;
acb->zStream->avail_in = acb->gz_len;
acb->zStream->next_out = buf;
acb->zStream->avail_out = acb->chunks_len;
r = inflate( acb->zStream, Z_PARTIAL_FLUSH );
if ( (r != Z_OK) && (r != Z_STREAM_END) )
fprintf(stderr, "Error inflating: [%d] %s\n", r, acb->zStream->msg);
if ( r == Z_STREAM_END )
inflateReset(acb->zStream);
dprintf("inflating [%d] left: %d | %d bytes\n", r, acb->zStream->avail_in, acb->zStream->avail_out);
s->stream_in_use &= ~(1 << acb->zStream_id);
/* nofity the caller */
qemu_iovec_from_buf(acb->qiov, 0, buf + acb->offset, acb->len);
acb->common.cb(acb->common.opaque, 0);
/* fill the cache */
cache = &s->cache[s->cache_index];
s->cache_index++;
if (s->cache_index == CACHE_COUNT)
s->cache_index = 0;
cache->len = 0;
if (cache->buf)
g_free(cache->buf);
cache->start = acb->gz_start;
cache->buf = buf;
cache->len = acb->chunks_len;
/* free occupied ressources */
g_free(acb->qiov_gz);
qemu_aio_unref(acb);
}
static const AIOCBInfo dictzip_aiocb_info = {
.aiocb_size = sizeof(DictZipAIOCB),
};
/* This is where we get a request from a caller to read something */
static BlockAIOCB *dictzip_aio_readv(BlockDriverState *bs,
int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
BlockCompletionFunc *cb, void *opaque)
{
BDRVDictZipState *s = bs->opaque;
DictZipAIOCB *acb;
QEMUIOVector *qiov_gz;
struct iovec *iov;
uint8_t *buf;
size_t start = sector_num * SECTOR_SIZE;
size_t len = nb_sectors * SECTOR_SIZE;
size_t end = start + len;
size_t gz_start;
size_t gz_len;
int64_t gz_sector_num;
int gz_nb_sectors;
int first_chunk, last_chunk;
int first_offset;
int i;
acb = qemu_aio_get(&dictzip_aiocb_info, bs, cb, opaque);
if (!acb)
return NULL;
/* Search Cache */
for (i = 0; i < CACHE_COUNT; i++) {
if (!s->cache[i].len)
continue;
if ((start >= s->cache[i].start) &&
(end <= (s->cache[i].start + s->cache[i].len))) {
acb->buf = s->cache[i].buf + (start - s->cache[i].start);
acb->len = len;
acb->qiov = qiov;
acb->bh = qemu_bh_new(dictzip_cache_cb, acb);
qemu_bh_schedule(acb->bh);
return &acb->common;
}
}
/* No cache, so let's decode */
/* We need to read these chunks */
first_chunk = start / s->chunk_len;
first_offset = start - first_chunk * s->chunk_len;
last_chunk = end / s->chunk_len;
gz_start = s->offsets[first_chunk];
gz_len = 0;
for (i = first_chunk; i <= last_chunk; i++) {
if (s->chunks32)
gz_len += le32_to_cpu(s->chunks32[i]);
else
gz_len += le16_to_cpu(s->chunks[i]);
}
gz_sector_num = gz_start / SECTOR_SIZE;
gz_nb_sectors = (gz_len / SECTOR_SIZE);
/* account for tail and heads */
while ((gz_start + gz_len) > ((gz_sector_num + gz_nb_sectors) * SECTOR_SIZE))
gz_nb_sectors++;
/* Allocate qiov, iov and buf in one chunk so we only need to free qiov */
qiov_gz = g_malloc0(sizeof(QEMUIOVector) + sizeof(struct iovec) +
(gz_nb_sectors * SECTOR_SIZE));
iov = (struct iovec *)(((char *)qiov_gz) + sizeof(QEMUIOVector));
buf = ((uint8_t *)iov) + sizeof(struct iovec *);
/* Kick off the read by the backing file, so we can start decompressing */
iov->iov_base = (void *)buf;
iov->iov_len = gz_nb_sectors * 512;
qemu_iovec_init_external(qiov_gz, iov, 1);
dprintf("read %zd - %zd => %zd - %zd\n", start, end, gz_start, gz_start + gz_len);
acb->s = s;
acb->qiov = qiov;
acb->qiov_gz = qiov_gz;
acb->start = start;
acb->len = len;
acb->gzipped = buf + (gz_start % SECTOR_SIZE);
acb->gz_len = gz_len;
acb->gz_start = first_chunk * s->chunk_len;
acb->offset = first_offset;
acb->chunks_len = (last_chunk - first_chunk + 1) * s->chunk_len;
return bdrv_aio_readv(s->hd, gz_sector_num, qiov_gz, gz_nb_sectors,
dictzip_read_cb, acb);
}
static void dictzip_close(BlockDriverState *bs)
{
BDRVDictZipState *s = bs->opaque;
int i;
for (i = 0; i < CACHE_COUNT; i++) {
if (!s->cache[i].len)
continue;
g_free(s->cache[i].buf);
}
for (i = 0; i < Z_STREAM_COUNT; i++) {
inflateEnd(&s->zStream[i]);
}
if (s->chunks)
g_free(s->chunks);
if (s->offsets)
g_free(s->offsets);
dprintf("Close\n");
}
static int64_t dictzip_getlength(BlockDriverState *bs)
{
BDRVDictZipState *s = bs->opaque;
dprintf("getlength -> %ld\n", s->file_len);
return s->file_len;
}
static BlockDriver bdrv_dictzip = {
.format_name = "dzip",
.protocol_name = "dzip",
.instance_size = sizeof(BDRVDictZipState),
.bdrv_file_open = dictzip_open,
.bdrv_close = dictzip_close,
.bdrv_getlength = dictzip_getlength,
.bdrv_aio_readv = dictzip_aio_readv,
};
static void dictzip_block_init(void)
{
bdrv_register(&bdrv_dictzip);
}
block_init(dictzip_block_init);

View File

@@ -2487,7 +2487,7 @@ static void coroutine_fn bdrv_discard_co_entry(void *opaque)
rwco->ret = bdrv_co_discard(rwco->bs, rwco->sector_num, rwco->nb_sectors);
}
int coroutine_fn bdrv_co_discard(BlockDriverState *bs, int64_t sector_num,
static int __bdrv_co_discard(BlockDriverState *bs, int64_t sector_num,
int nb_sectors)
{
BdrvTrackedRequest req;
@@ -2569,6 +2569,26 @@ out:
return ret;
}
int coroutine_fn bdrv_co_discard(BlockDriverState *bs, int64_t sector_num,
int nb_sectors)
{
int num, ret;
int limit = BDRV_REQUEST_MAX_SECTORS;
int remaining = nb_sectors;
int64_t sector_offset = sector_num;
do {
num = remaining > limit ? limit : remaining;
ret = __bdrv_co_discard(bs, sector_offset, num);
if (ret < 0)
break;
remaining -= num;
sector_offset += num;
} while (remaining > 0);
return ret;
}
int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors)
{
Coroutine *co;

View File

@@ -226,7 +226,7 @@ static int qcow2_cache_entry_flush(BlockDriverState *bs, Qcow2Cache *c, int i)
return 0;
}
int qcow2_cache_flush(BlockDriverState *bs, Qcow2Cache *c)
int qcow2_cache_write(BlockDriverState *bs, Qcow2Cache *c)
{
BDRVQcow2State *s = bs->opaque;
int result = 0;
@@ -242,8 +242,15 @@ int qcow2_cache_flush(BlockDriverState *bs, Qcow2Cache *c)
}
}
return result;
}
int qcow2_cache_flush(BlockDriverState *bs, Qcow2Cache *c)
{
int result = qcow2_cache_write(bs, c);
if (result == 0) {
ret = bdrv_flush(bs->file->bs);
int ret = bdrv_flush(bs->file->bs);
if (ret < 0) {
result = ret;
}

View File

@@ -2774,14 +2774,14 @@ static coroutine_fn int qcow2_co_flush_to_os(BlockDriverState *bs)
int ret;
qemu_co_mutex_lock(&s->lock);
ret = qcow2_cache_flush(bs, s->l2_table_cache);
ret = qcow2_cache_write(bs, s->l2_table_cache);
if (ret < 0) {
qemu_co_mutex_unlock(&s->lock);
return ret;
}
if (qcow2_need_accurate_refcounts(s)) {
ret = qcow2_cache_flush(bs, s->refcount_block_cache);
ret = qcow2_cache_write(bs, s->refcount_block_cache);
if (ret < 0) {
qemu_co_mutex_unlock(&s->lock);
return ret;

View File

@@ -583,6 +583,7 @@ int qcow2_cache_destroy(BlockDriverState* bs, Qcow2Cache *c);
void qcow2_cache_entry_mark_dirty(BlockDriverState *bs, Qcow2Cache *c,
void *table);
int qcow2_cache_flush(BlockDriverState *bs, Qcow2Cache *c);
int qcow2_cache_write(BlockDriverState *bs, Qcow2Cache *c);
int qcow2_cache_set_dependency(BlockDriverState *bs, Qcow2Cache *c,
Qcow2Cache *dependency);
void qcow2_cache_depends_on_flush(Qcow2Cache *c);

379
block/tar.c Normal file
View File

@@ -0,0 +1,379 @@
/*
* Tar block driver
*
* Copyright (c) 2009 Alexander Graf <agraf@suse.de>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu-common.h"
#include "block/block_int.h"
// #define DEBUG
#ifdef DEBUG
#define dprintf(fmt, ...) do { printf("tar: " fmt, ## __VA_ARGS__); } while (0)
#else
#define dprintf(fmt, ...) do { } while (0)
#endif
#define SECTOR_SIZE 512
#define POSIX_TAR_MAGIC "ustar"
#define OFFS_LENGTH 0x7c
#define OFFS_TYPE 0x9c
#define OFFS_MAGIC 0x101
#define OFFS_S_SP 0x182
#define OFFS_S_EXT 0x1e2
#define OFFS_S_LENGTH 0x1e3
#define OFFS_SX_EXT 0x1f8
typedef struct SparseCache {
uint64_t start;
uint64_t end;
} SparseCache;
typedef struct BDRVTarState {
BlockDriverState *hd;
size_t file_sec;
uint64_t file_len;
SparseCache *sparse;
int sparse_num;
uint64_t last_end;
char longfile[2048];
} BDRVTarState;
static int str_ends(char *str, const char *end)
{
int end_len = strlen(end);
int str_len = strlen(str);
if (str_len < end_len)
return 0;
return !strncmp(str + str_len - end_len, end, end_len);
}
static int is_target_file(BlockDriverState *bs, char *filename,
char *header)
{
int retval = 0;
if (str_ends(filename, ".raw"))
retval = 1;
if (str_ends(filename, ".qcow"))
retval = 1;
if (str_ends(filename, ".qcow2"))
retval = 1;
if (str_ends(filename, ".vmdk"))
retval = 1;
if (retval &&
(header[OFFS_TYPE] != '0') &&
(header[OFFS_TYPE] != 'S')) {
retval = 0;
}
dprintf("does filename %s match? %s\n", filename, retval ? "yes" : "no");
/* make sure we're not using this name again */
filename[0] = '\0';
return retval;
}
static uint64_t tar2u64(char *ptr)
{
uint64_t retval;
char oldend = ptr[12];
ptr[12] = '\0';
if (*ptr & 0x80) {
/* XXX we only support files up to 64 bit length */
retval = be64_to_cpu(*(uint64_t *)(ptr+4));
dprintf("Convert %lx -> %#lx\n", *(uint64_t*)(ptr+4), retval);
} else {
retval = strtol(ptr, NULL, 8);
dprintf("Convert %s -> %#lx\n", ptr, retval);
}
ptr[12] = oldend;
return retval;
}
static void tar_sparse(BDRVTarState *s, uint64_t offs, uint64_t len)
{
SparseCache *sparse;
if (!len)
return;
if (!(offs - s->last_end)) {
s->last_end += len;
return;
}
if (s->last_end > offs)
return;
dprintf("Last chunk until %lx new chunk at %lx\n", s->last_end, offs);
s->sparse = g_realloc(s->sparse, (s->sparse_num + 1) * sizeof(SparseCache));
sparse = &s->sparse[s->sparse_num];
sparse->start = s->last_end;
sparse->end = offs;
s->last_end = offs + len;
s->sparse_num++;
dprintf("Sparse at %lx end=%lx\n", sparse->start,
sparse->end);
}
static QemuOptsList runtime_opts = {
.name = "tar",
.head = QTAILQ_HEAD_INITIALIZER(runtime_opts.head),
.desc = {
{
.name = "filename",
.type = QEMU_OPT_STRING,
.help = "URL to the tar file",
},
{ /* end of list */ }
},
};
static int tar_open(BlockDriverState *bs, QDict *options, int flags, Error **errp)
{
BDRVTarState *s = bs->opaque;
char header[SECTOR_SIZE];
char *real_file = header;
char *magic;
size_t header_offs = 0;
int ret;
QemuOpts *opts;
Error *local_err = NULL;
const char *filename;
opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err);
if (local_err != NULL) {
error_propagate(errp, local_err);
ret = -EINVAL;
goto fail;
}
filename = qemu_opt_get(opts, "filename");
if (!strncmp(filename, "tar://", 6))
filename += 6;
else if (!strncmp(filename, "tar:", 4))
filename += 4;
ret = bdrv_open(&s->hd, filename, NULL, NULL, flags | BDRV_O_PROTOCOL, &local_err);
if (ret < 0) {
error_propagate(errp, local_err);
qemu_opts_del(opts);
return ret;
}
/* Search the file for an image */
do {
/* tar header */
if (bdrv_pread(s->hd, header_offs, header, SECTOR_SIZE) != SECTOR_SIZE)
goto fail;
if ((header_offs > 1) && !header[0]) {
fprintf(stderr, "Tar: No image file found in archive\n");
goto fail;
}
magic = &header[OFFS_MAGIC];
if (strncmp(magic, POSIX_TAR_MAGIC, 5)) {
fprintf(stderr, "Tar: Invalid magic: %s\n", magic);
goto fail;
}
dprintf("file type: %c\n", header[OFFS_TYPE]);
/* file length*/
s->file_len = (tar2u64(&header[OFFS_LENGTH]) + (SECTOR_SIZE - 1)) &
~(SECTOR_SIZE - 1);
s->file_sec = (header_offs / SECTOR_SIZE) + 1;
header_offs += s->file_len + SECTOR_SIZE;
if (header[OFFS_TYPE] == 'L') {
bdrv_pread(s->hd, header_offs - s->file_len, s->longfile,
sizeof(s->longfile));
s->longfile[sizeof(s->longfile)-1] = '\0';
real_file = header;
} else if (s->longfile[0]) {
real_file = s->longfile;
} else {
real_file = header;
}
} while(!is_target_file(bs, real_file, header));
/* We found an image! */
if (header[OFFS_TYPE] == 'S') {
uint8_t isextended;
int i;
for (i = OFFS_S_SP; i < (OFFS_S_SP + (4 * 24)); i += 24)
tar_sparse(s, tar2u64(&header[i]), tar2u64(&header[i+12]));
s->file_len = tar2u64(&header[OFFS_S_LENGTH]);
isextended = header[OFFS_S_EXT];
while (isextended) {
if (bdrv_pread(s->hd, s->file_sec * SECTOR_SIZE, header,
SECTOR_SIZE) != SECTOR_SIZE)
goto fail;
for (i = 0; i < (21 * 24); i += 24)
tar_sparse(s, tar2u64(&header[i]), tar2u64(&header[i+12]));
isextended = header[OFFS_SX_EXT];
s->file_sec++;
}
tar_sparse(s, s->file_len, 1);
}
qemu_opts_del(opts);
return 0;
fail:
fprintf(stderr, "Tar: Error opening file\n");
bdrv_unref(s->hd);
qemu_opts_del(opts);
return -EINVAL;
}
typedef struct TarAIOCB {
BlockAIOCB common;
QEMUBH *bh;
} TarAIOCB;
/* This callback gets invoked when we have pure sparseness */
static void tar_sparse_cb(void *opaque)
{
TarAIOCB *acb = (TarAIOCB *)opaque;
acb->common.cb(acb->common.opaque, 0);
qemu_bh_delete(acb->bh);
qemu_aio_unref(acb);
}
static AIOCBInfo tar_aiocb_info = {
.aiocb_size = sizeof(TarAIOCB),
};
/* This is where we get a request from a caller to read something */
static BlockAIOCB *tar_aio_readv(BlockDriverState *bs,
int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
BlockCompletionFunc *cb, void *opaque)
{
BDRVTarState *s = bs->opaque;
SparseCache *sparse;
int64_t sec_file = sector_num + s->file_sec;
int64_t start = sector_num * SECTOR_SIZE;
int64_t end = start + (nb_sectors * SECTOR_SIZE);
int i;
TarAIOCB *acb;
for (i = 0; i < s->sparse_num; i++) {
sparse = &s->sparse[i];
if (sparse->start > end) {
/* We expect the cache to be start increasing */
break;
} else if ((sparse->start < start) && (sparse->end <= start)) {
/* sparse before our offset */
sec_file -= (sparse->end - sparse->start) / SECTOR_SIZE;
} else if ((sparse->start <= start) && (sparse->end >= end)) {
/* all our sectors are sparse */
char *buf = g_malloc0(nb_sectors * SECTOR_SIZE);
acb = qemu_aio_get(&tar_aiocb_info, bs, cb, opaque);
qemu_iovec_from_buf(qiov, 0, buf, nb_sectors * SECTOR_SIZE);
g_free(buf);
acb->bh = qemu_bh_new(tar_sparse_cb, acb);
qemu_bh_schedule(acb->bh);
return &acb->common;
} else if (((sparse->start >= start) && (sparse->start < end)) ||
((sparse->end >= start) && (sparse->end < end))) {
/* we're semi-sparse (worst case) */
/* let's go synchronous and read all sectors individually */
char *buf = g_malloc(nb_sectors * SECTOR_SIZE);
uint64_t offs;
for (offs = 0; offs < (nb_sectors * SECTOR_SIZE);
offs += SECTOR_SIZE) {
bdrv_pread(bs, (sector_num * SECTOR_SIZE) + offs,
buf + offs, SECTOR_SIZE);
}
qemu_iovec_from_buf(qiov, 0, buf, nb_sectors * SECTOR_SIZE);
acb = qemu_aio_get(&tar_aiocb_info, bs, cb, opaque);
acb->bh = qemu_bh_new(tar_sparse_cb, acb);
qemu_bh_schedule(acb->bh);
return &acb->common;
}
}
return bdrv_aio_readv(s->hd, sec_file, qiov, nb_sectors,
cb, opaque);
}
static void tar_close(BlockDriverState *bs)
{
dprintf("Close\n");
}
static int64_t tar_getlength(BlockDriverState *bs)
{
BDRVTarState *s = bs->opaque;
dprintf("getlength -> %ld\n", s->file_len);
return s->file_len;
}
static BlockDriver bdrv_tar = {
.format_name = "tar",
.protocol_name = "tar",
.instance_size = sizeof(BDRVTarState),
.bdrv_file_open = tar_open,
.bdrv_close = tar_close,
.bdrv_getlength = tar_getlength,
.bdrv_aio_readv = tar_aio_readv,
};
static void tar_block_init(void)
{
bdrv_register(&bdrv_tar);
}
block_init(tar_block_init);

View File

@@ -1885,9 +1885,12 @@ static int vmdk_create(const char *filename, QemuOpts *opts, Error **errp)
if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ZEROED_GRAIN, false)) {
zeroed_grain = true;
}
if (qemu_opt_get_bool_del(opts, BLOCK_OPT_SCSI, false)) {
flags |= BLOCK_FLAG_SCSI;
}
if (!adapter_type) {
adapter_type = g_strdup("ide");
adapter_type = g_strdup(flags & BLOCK_FLAG_SCSI ? "lsilogic" : "ide");
} else if (strcmp(adapter_type, "ide") &&
strcmp(adapter_type, "buslogic") &&
strcmp(adapter_type, "lsilogic") &&
@@ -2310,6 +2313,11 @@ static QemuOptsList vmdk_create_opts = {
.help = "Enable efficient zero writes "
"using the zeroed-grain GTE feature"
},
{
.name = BLOCK_OPT_SCSI,
.type = QEMU_OPT_BOOL,
.help = "SCSI image"
},
{ /* end of list */ }
}
};

67
configure vendored
View File

@@ -1537,7 +1537,7 @@ fi
if test "$pie" = ""; then
case "$cpu-$targetos" in
i386-Linux|x86_64-Linux|x32-Linux|i386-OpenBSD|x86_64-OpenBSD)
i386-Linux|x86_64-Linux|x32-Linux|ppc*-Linux|i386-OpenBSD|x86_64-OpenBSD)
;;
*)
pie="no"
@@ -1879,6 +1879,9 @@ if test "$seccomp" != "no" ; then
arm|aarch64)
libseccomp_minver="2.2.3"
;;
ppc|ppc64)
libseccomp_minver="2.2.0"
;;
*)
libseccomp_minver=""
;;
@@ -2393,20 +2396,25 @@ fi
if test "$vte" != "no"; then
if test "$gtkabi" = "3.0"; then
vtepackage="vte-2.90"
vteversion="0.32.0"
vteminversion="0.32.0"
if $pkg_config --exists "vte-2.91"; then
vtepackage="vte-2.91"
else
vtepackage="vte-2.90"
fi
else
vtepackage="vte"
vteversion="0.24.0"
vteminversion="0.24.0"
fi
if $pkg_config --exists "$vtepackage >= $vteversion"; then
if $pkg_config --exists "$vtepackage >= $vteminversion"; then
vte_cflags=`$pkg_config --cflags $vtepackage`
vte_libs=`$pkg_config --libs $vtepackage`
vteversion=`$pkg_config --modversion $vtepackage`
libs_softmmu="$vte_libs $libs_softmmu"
vte="yes"
elif test "$vte" = "yes"; then
if test "$gtkabi" = "3.0"; then
feature_not_found "vte" "Install libvte-2.90 devel"
feature_not_found "vte" "Install libvte-2.90/2.91 devel"
else
feature_not_found "vte" "Install libvte devel"
fi
@@ -4030,6 +4038,33 @@ if test "$usb_redir" != "no" ; then
fi
fi
if test "$linux_user" = "no" -a "$cpu" = "ppc" -a "$targetos" = "Linux" ; then
# Do we need libm
cat > $TMPC << EOF
#include <unistd.h>
#include <stdint.h>
#include <qemu/atomic.h>
int64_t val;
int main(int argc, char **argv)
{
val = (int64_t)read(0, NULL, 0);
if (atomic_read(&val) == -1) {
return 0;
}
return 1;
}
EOF
if compile_prog "-Iinclude" "" ; then
:
echo "No need to link with -latomic on powerpc-linux"
elif compile_prog "-Iinclude" "-latomic" ; then
echo "Link with -latomic on powerpc-linux"
libs_softmmu="$libs_softmmu -latomic"
else
error_exit "libatomic check failed"
fi
fi
##########################################
# check if we have VSS SDK headers for win
@@ -4719,6 +4754,12 @@ EOF
fi
fi
echo_version() {
if test "$1" = "yes" ; then
echo "($2)"
fi
}
# prepend pixman and ftd flags after all config tests are done
QEMU_CFLAGS="$pixman_cflags $fdt_cflags $QEMU_CFLAGS"
libs_softmmu="$pixman_libs $libs_softmmu"
@@ -4771,19 +4812,15 @@ echo "pixman $pixman"
echo "SDL support $sdl"
echo "GTK support $gtk"
echo "GTK GL support $gtk_gl"
echo "VTE support $vte `echo_version $vte $vteversion`"
echo "GNUTLS support $gnutls"
echo "GNUTLS hash $gnutls_hash"
echo "GNUTLS rnd $gnutls_rnd"
echo "libgcrypt $gcrypt"
echo "libgcrypt kdf $gcrypt_kdf"
if test "$nettle" = "yes"; then
echo "nettle $nettle ($nettle_version)"
else
echo "nettle $nettle"
fi
echo "nettle $nettle `echo_version $nettle $nettle_version`"
echo "nettle kdf $nettle_kdf"
echo "libtasn1 $tasn1"
echo "VTE support $vte"
echo "curses support $curses"
echo "virgl support $virglrenderer"
echo "curl support $curl"
@@ -4832,11 +4869,7 @@ echo "Trace backends $trace_backends"
if have_backend "simple"; then
echo "Trace output file $trace_file-<pid>"
fi
if test "$spice" = "yes"; then
echo "spice support $spice ($spice_protocol_version/$spice_server_version)"
else
echo "spice support $spice"
fi
echo "spice support $spice `echo_version $spice $spice_protocol_version/$spice_server_version`"
echo "rbd support $rbd"
echo "xfsctl support $xfs"
echo "smartcard support $smartcard"

View File

@@ -2,8 +2,10 @@
include pci.mak
include usb.mak
CONFIG_QXL=$(CONFIG_SPICE)
CONFIG_VGA=y
CONFIG_ISA_MMIO=y
CONFIG_VIRTIO_VGA=y
CONFIG_NAND=y
CONFIG_ECC=y
CONFIG_SERIAL=y

View File

@@ -3,11 +3,13 @@
include pci.mak
include sound.mak
include usb.mak
CONFIG_QXL=$(CONFIG_SPICE)
CONFIG_ESP=y
CONFIG_VGA_ISA=y
CONFIG_VGA_ISA_MM=y
CONFIG_VGA_CIRRUS=y
CONFIG_VMWARE_VGA=y
CONFIG_VIRTIO_VGA=y
CONFIG_SERIAL=y
CONFIG_PARALLEL=y
CONFIG_I8254=y

View File

@@ -3,6 +3,8 @@
include pci.mak
include sound.mak
include usb.mak
CONFIG_QXL=$(CONFIG_SPICE)
CONFIG_VIRTIO_VGA=y
CONFIG_ISA_MMIO=y
CONFIG_ESCC=y
CONFIG_M48T59=y

View File

@@ -3,6 +3,7 @@
include pci.mak
include sound.mak
include usb.mak
CONFIG_QXL=$(CONFIG_SPICE)
CONFIG_VIRTIO_VGA=y
CONFIG_ISA_MMIO=y
CONFIG_ESCC=y

2
exec.c
View File

@@ -1242,11 +1242,13 @@ static void *file_ram_alloc(RAMBlock *block,
int fd = -1;
int64_t page_size;
#ifndef TARGET_PPC
if (kvm_enabled() && !kvm_has_sync_mmu()) {
error_setg(errp,
"host lacks kvm mmu notifiers, -mem-path unsupported");
return NULL;
}
#endif
for (;;) {
fd = open(path, O_RDWR);

View File

@@ -9,6 +9,13 @@
* the COPYING file in the top-level directory.
*/
/* work around a broken sys/capability.h */
#if defined(__i386__)
typedef unsigned long long __u64;
#endif
#if defined(__powerpc64__)
#include <asm/types.h>
#endif
#include "qemu/osdep.h"
#include <sys/resource.h>
#include <getopt.h>

View File

@@ -950,6 +950,7 @@ static void create_pcie(const VirtBoardInfo *vbi, qemu_irq *pic,
qemu_fdt_setprop_cell(vbi->fdt, nodename, "#size-cells", 2);
qemu_fdt_setprop_cells(vbi->fdt, nodename, "bus-range", 0,
nr_pcie_buses - 1);
qemu_fdt_setprop(vbi->fdt, nodename, "dma-coherent", NULL, 0);
if (vbi->v2m_phandle) {
qemu_fdt_setprop_cells(vbi->fdt, nodename, "msi-parent",

View File

@@ -112,6 +112,7 @@ struct XenBlkDev {
int requests_inflight;
int requests_finished;
gboolean cache_unsafe;
/* Persistent grants extension */
gboolean feature_discard;
gboolean feature_persistent;
@@ -793,6 +794,16 @@ static void blk_parse_discard(struct XenBlkDev *blkdev)
}
}
static void blk_parse_cache_unsafe(struct XenBlkDev *blkdev)
{
int enable;
blkdev->cache_unsafe = false;
if (xenstore_read_be_int(&blkdev->xendev, "suse-diskcache-disable-flush", &enable) == 0)
blkdev->cache_unsafe = !!enable;
}
static int blk_init(struct XenDevice *xendev)
{
struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
@@ -864,6 +875,7 @@ static int blk_init(struct XenDevice *xendev)
xenstore_write_be_int(&blkdev->xendev, "info", info);
blk_parse_discard(blkdev);
blk_parse_cache_unsafe(blkdev);
g_free(directiosafe);
return 0;
@@ -906,6 +918,9 @@ static int blk_connect(struct XenDevice *xendev)
qflags |= BDRV_O_UNMAP;
}
if (blkdev->cache_unsafe)
qflags |= BDRV_O_NO_FLUSH;
/* init qemu block driver */
index = (blkdev->xendev.dev - 202 * 256) / 16;
blkdev->dinfo = drive_get(IF_XEN, 0, index);

View File

@@ -314,6 +314,28 @@ static void xen_platform_ioport_writeb(void *opaque, hwaddr addr,
case 0: /* Platform flags */
platform_fixed_ioport_writeb(opaque, 0, (uint32_t)val);
break;
case 4:
if (val == 1 && size == 1) {
/*
* SUSE unplug for Xenlinux
* xen-kmp used this since xen-3.0.4, instead the official protocol from xen-3.3+
* It did an unconditional "outl(1, (ioaddr + 4));"
* This approach was used until openSUSE 12.3, up to SLE11SP3 and in SLE10.
* Starting with openSUSE 13.1, SLE11SP4 and SLE12 the official protocol is used.
* pre VMDP 1.7 made use of 4 and 8 depending on how vmdp was configured.
* If VMDP was to control both disk and LAN it would use 4.
* If it controlled just disk or just LAN, it would use 8 below.
*/
PCIDevice *pci_dev = PCI_DEVICE(s);
DPRINTF("unplug disks\n");
blk_drain_all();
blk_flush_all();
pci_unplug_disks(pci_dev->bus);
DPRINTF("unplug nics\n");
pci_unplug_nics(pci_dev->bus);
DPRINTF("done\n");
}
break;
case 8:
log_writeb(s, (uint32_t)val);
break;

View File

@@ -574,7 +574,7 @@ static bool esp_mem_accepts(void *opaque, hwaddr addr,
const VMStateDescription vmstate_esp = {
.name ="esp",
.version_id = 3,
.version_id = 4,
.minimum_version_id = 3,
.fields = (VMStateField[]) {
VMSTATE_BUFFER(rregs, ESPState),
@@ -585,7 +585,8 @@ const VMStateDescription vmstate_esp = {
VMSTATE_BUFFER(ti_buf, ESPState),
VMSTATE_UINT32(status, ESPState),
VMSTATE_UINT32(dma, ESPState),
VMSTATE_BUFFER(cmdbuf, ESPState),
VMSTATE_PARTIAL_BUFFER(cmdbuf, ESPState, 16),
VMSTATE_BUFFER_START_MIDDLE_V(cmdbuf, ESPState, 16, 4),
VMSTATE_UINT32(cmdlen, ESPState),
VMSTATE_UINT32(do_cmd, ESPState),
VMSTATE_UINT32(dma_left, ESPState),

View File

@@ -38,3 +38,7 @@ common-obj-$(CONFIG_USB_REDIR) += redirect.o quirks.o
# usb pass-through
common-obj-y += $(patsubst %,host-%.o,$(HOST_USB))
ifeq ($(CONFIG_USB_LIBUSB),y)
common-obj-$(CONFIG_XEN_BACKEND) += xen-usb.o
endif

1107
hw/usb/xen-usb.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -27,12 +27,17 @@
#include <sys/signal.h>
#include "hw/hw.h"
#include "hw/sysbus.h"
#include "sysemu/char.h"
#include "qemu/log.h"
#include "hw/xen/xen_backend.h"
#include <xen/grant_table.h>
#define TYPE_XENSYSDEV "xensysdev"
DeviceState *xen_sysdev;
/* ------------------------------------------------------------- */
/* public */
@@ -42,11 +47,36 @@ struct xs_handle *xenstore = NULL;
const char *xen_protocol;
/* private */
struct xs_dirs {
char *xs_dir;
QTAILQ_ENTRY(xs_dirs) list;
};
static QTAILQ_HEAD(xs_dirs_head, xs_dirs) xs_cleanup =
QTAILQ_HEAD_INITIALIZER(xs_cleanup);
static QTAILQ_HEAD(XenDeviceHead, XenDevice) xendevs = QTAILQ_HEAD_INITIALIZER(xendevs);
static int debug = 0;
/* ------------------------------------------------------------- */
static void xenstore_cleanup_dir(char *dir)
{
struct xs_dirs *d;
d = g_malloc(sizeof(*d));
d->xs_dir = dir;
QTAILQ_INSERT_TAIL(&xs_cleanup, d, list);
}
void xen_config_cleanup(void)
{
struct xs_dirs *d;
QTAILQ_FOREACH(d, &xs_cleanup, list) {
xs_rm(xenstore, 0, d->xs_dir);
}
}
int xenstore_write_str(const char *base, const char *node, const char *val)
{
char abspath[XEN_BUFSIZE];
@@ -75,6 +105,30 @@ char *xenstore_read_str(const char *base, const char *node)
return ret;
}
int xenstore_mkdir(char *path, int p)
{
struct xs_permissions perms[2] = {
{
.id = 0, /* set owner: dom0 */
}, {
.id = xen_domid,
.perms = p,
}
};
if (!xs_mkdir(xenstore, 0, path)) {
xen_be_printf(NULL, 0, "xs_mkdir %s: failed\n", path);
return -1;
}
xenstore_cleanup_dir(g_strdup(path));
if (!xs_set_permissions(xenstore, 0, path, perms, 2)) {
xen_be_printf(NULL, 0, "xs_set_permissions %s: failed\n", path);
return -1;
}
return 0;
}
int xenstore_write_int(const char *base, const char *node, int ival)
{
char val[12];
@@ -268,48 +322,28 @@ static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev,
/*
* release xen backend device.
*/
static struct XenDevice *xen_be_del_xendev(int dom, int dev)
static void xen_be_del_xendev(struct XenDevice *xendev)
{
struct XenDevice *xendev, *xnext;
/*
* This is pretty much like QTAILQ_FOREACH(xendev, &xendevs, next) but
* we save the next pointer in xnext because we might free xendev.
*/
xnext = xendevs.tqh_first;
while (xnext) {
xendev = xnext;
xnext = xendev->next.tqe_next;
if (xendev->dom != dom) {
continue;
}
if (xendev->dev != dev && dev != -1) {
continue;
}
if (xendev->ops->free) {
xendev->ops->free(xendev);
}
if (xendev->fe) {
char token[XEN_BUFSIZE];
snprintf(token, sizeof(token), "fe:%p", xendev);
xs_unwatch(xenstore, xendev->fe, token);
g_free(xendev->fe);
}
if (xendev->evtchndev != NULL) {
xenevtchn_close(xendev->evtchndev);
}
if (xendev->gnttabdev != NULL) {
xengnttab_close(xendev->gnttabdev);
}
QTAILQ_REMOVE(&xendevs, xendev, next);
g_free(xendev);
if (xendev->ops->free) {
xendev->ops->free(xendev);
}
return NULL;
if (xendev->fe) {
char token[XEN_BUFSIZE];
snprintf(token, sizeof(token), "fe:%p", xendev);
xs_unwatch(xenstore, xendev->fe, token);
g_free(xendev->fe);
}
if (xendev->evtchndev != NULL) {
xenevtchn_close(xendev->evtchndev);
}
if (xendev->gnttabdev != NULL) {
xengnttab_close(xendev->gnttabdev);
}
QTAILQ_REMOVE(&xendevs, xendev, next);
g_free(xendev);
}
/*
@@ -629,7 +663,7 @@ static void xenstore_update_be(char *watch, char *type, int dom,
if (xendev != NULL) {
bepath = xs_read(xenstore, 0, xendev->be, &len);
if (bepath == NULL) {
xen_be_del_xendev(dom, dev);
xen_be_del_xendev(xendev);
} else {
free(bepath);
xen_be_backend_changed(xendev, path);
@@ -714,6 +748,10 @@ int xen_be_init(void)
/* Check if xen_init() have been called */
goto err;
}
xen_sysdev = qdev_create(NULL, TYPE_XENSYSDEV);
qdev_init_nofail(xen_sysdev);
return 0;
err:
@@ -726,9 +764,33 @@ err:
int xen_be_register(const char *type, struct XenDevOps *ops)
{
char path[50];
int rc;
if (ops->backend_register) {
rc = ops->backend_register();
if (rc) {
return rc;
}
}
snprintf(path, sizeof(path), "device-model/%u/backends/%s", xen_domid,
type);
xenstore_mkdir(path, XS_PERM_NONE);
return xenstore_scan(type, xen_domid, ops);
}
void xen_be_register_common(void)
{
xen_be_register("console", &xen_console_ops);
xen_be_register("vkbd", &xen_kbdmouse_ops);
xen_be_register("qdisk", &xen_blkdev_ops);
#ifdef CONFIG_USB_LIBUSB
xen_be_register("qusb", &xen_usb_ops);
#endif
}
int xen_be_bind_evtchn(struct XenDevice *xendev)
{
if (xendev->local_port != -1) {
@@ -800,3 +862,35 @@ void xen_be_printf(struct XenDevice *xendev, int msg_level, const char *fmt, ...
}
qemu_log_flush();
}
static int xen_sysdev_init(SysBusDevice *dev)
{
return 0;
}
static Property xen_sysdev_properties[] = {
{/* end of property list */},
};
static void xen_sysdev_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
k->init = xen_sysdev_init;
dc->props = xen_sysdev_properties;
}
static const TypeInfo xensysdev_info = {
.name = TYPE_XENSYSDEV,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(SysBusDevice),
.class_init = xen_sysdev_class_init,
};
static void xenbe_register_types(void)
{
type_register_static(&xensysdev_info);
}
type_init(xenbe_register_types);

View File

@@ -5,54 +5,6 @@
/* ------------------------------------------------------------- */
struct xs_dirs {
char *xs_dir;
QTAILQ_ENTRY(xs_dirs) list;
};
static QTAILQ_HEAD(xs_dirs_head, xs_dirs) xs_cleanup = QTAILQ_HEAD_INITIALIZER(xs_cleanup);
static void xen_config_cleanup_dir(char *dir)
{
struct xs_dirs *d;
d = g_malloc(sizeof(*d));
d->xs_dir = dir;
QTAILQ_INSERT_TAIL(&xs_cleanup, d, list);
}
void xen_config_cleanup(void)
{
struct xs_dirs *d;
QTAILQ_FOREACH(d, &xs_cleanup, list) {
xs_rm(xenstore, 0, d->xs_dir);
}
}
/* ------------------------------------------------------------- */
static int xen_config_dev_mkdir(char *dev, int p)
{
struct xs_permissions perms[2] = {{
.id = 0, /* set owner: dom0 */
},{
.id = xen_domid,
.perms = p,
}};
if (!xs_mkdir(xenstore, 0, dev)) {
xen_be_printf(NULL, 0, "xs_mkdir %s: failed\n", dev);
return -1;
}
xen_config_cleanup_dir(g_strdup(dev));
if (!xs_set_permissions(xenstore, 0, dev, perms, 2)) {
xen_be_printf(NULL, 0, "xs_set_permissions %s: failed\n", dev);
return -1;
}
return 0;
}
static int xen_config_dev_dirs(const char *ftype, const char *btype, int vdev,
char *fe, char *be, int len)
{
@@ -66,8 +18,8 @@ static int xen_config_dev_dirs(const char *ftype, const char *btype, int vdev,
snprintf(be, len, "%s/backend/%s/%d/%d", dom, btype, xen_domid, vdev);
free(dom);
xen_config_dev_mkdir(fe, XS_PERM_READ | XS_PERM_WRITE);
xen_config_dev_mkdir(be, XS_PERM_READ);
xenstore_mkdir(fe, XS_PERM_READ | XS_PERM_WRITE);
xenstore_mkdir(be, XS_PERM_READ);
return 0;
}

View File

@@ -67,10 +67,8 @@ static void xen_init_pv(MachineState *machine)
break;
}
xen_be_register("console", &xen_console_ops);
xen_be_register("vkbd", &xen_kbdmouse_ops);
xen_be_register_common();
xen_be_register("vfb", &xen_framebuffer_ops);
xen_be_register("qdisk", &xen_blkdev_ops);
xen_be_register("qnic", &xen_netdev_ops);
/* configure framebuffer */

View File

@@ -40,10 +40,12 @@
#define BLOCK_FLAG_ENCRYPT 1
#define BLOCK_FLAG_COMPAT6 4
#define BLOCK_FLAG_LAZY_REFCOUNTS 8
#define BLOCK_FLAG_SCSI 16
#define BLOCK_OPT_SIZE "size"
#define BLOCK_OPT_ENCRYPT "encryption"
#define BLOCK_OPT_COMPAT6 "compat6"
#define BLOCK_OPT_SCSI "scsi"
#define BLOCK_OPT_BACKING_FILE "backing_file"
#define BLOCK_OPT_BACKING_FMT "backing_fmt"
#define BLOCK_OPT_CLUSTER_SIZE "cluster_size"

View File

@@ -37,6 +37,7 @@ typedef enum argtype {
TYPE_ARRAY,
TYPE_STRUCT,
TYPE_OLDDEVT,
TYPE_INTBITFIELD,
} argtype;
#define MK_PTR(type) TYPE_PTR, type
@@ -90,6 +91,7 @@ static inline int thunk_type_size(const argtype *type_ptr, int is_host)
case TYPE_SHORT:
return 2;
case TYPE_INT:
case TYPE_INTBITFIELD:
return 4;
case TYPE_LONGLONG:
case TYPE_ULONGLONG:
@@ -152,6 +154,7 @@ static inline int thunk_type_align(const argtype *type_ptr, int is_host)
case TYPE_SHORT:
return 2;
case TYPE_INT:
case TYPE_INTBITFIELD:
return 4;
case TYPE_LONGLONG:
case TYPE_ULONGLONG:

View File

@@ -28,6 +28,7 @@ struct XenDevOps {
int (*free)(struct XenDevice *xendev);
void (*backend_changed)(struct XenDevice *xendev, const char *node);
void (*frontend_changed)(struct XenDevice *xendev, const char *node);
int (*backend_register)(void);
};
struct XenDevice {
@@ -60,8 +61,10 @@ extern xc_interface *xen_xc;
extern xenforeignmemory_handle *xen_fmem;
extern struct xs_handle *xenstore;
extern const char *xen_protocol;
extern DeviceState *xen_sysdev;
/* xenstore helper functions */
int xenstore_mkdir(char *path, int p);
int xenstore_write_str(const char *base, const char *node, const char *val);
int xenstore_write_int(const char *base, const char *node, int ival);
int xenstore_write_int64(const char *base, const char *node, int64_t ival);
@@ -84,6 +87,7 @@ void xen_be_check_state(struct XenDevice *xendev);
/* xen backend driver bits */
int xen_be_init(void);
void xen_be_register_common(void);
int xen_be_register(const char *type, struct XenDevOps *ops);
int xen_be_set_state(struct XenDevice *xendev, enum xenbus_state state);
int xen_be_bind_evtchn(struct XenDevice *xendev);
@@ -98,6 +102,9 @@ extern struct XenDevOps xen_kbdmouse_ops; /* xen_framebuffer.c */
extern struct XenDevOps xen_framebuffer_ops; /* xen_framebuffer.c */
extern struct XenDevOps xen_blkdev_ops; /* xen_disk.c */
extern struct XenDevOps xen_netdev_ops; /* xen_nic.c */
#ifdef CONFIG_USB_LIBUSB
extern struct XenDevOps xen_usb_ops; /* xen-usb.c */
#endif
void xen_init_display(int domid);

View File

@@ -49,6 +49,8 @@ typedef xc_gnttab xengnttab_handle;
#define xengnttab_unmap(h, a, n) xc_gnttab_munmap(h, a, n)
#define xengnttab_map_grant_refs(h, c, d, r, p) \
xc_gnttab_map_grant_refs(h, c, d, r, p)
#define xengnttab_map_domain_grant_refs(h, c, d, r, p) \
xc_gnttab_map_domain_grant_refs(h, c, d, r, p)
#define xenforeignmemory_open(l, f) xen_xc

View File

@@ -888,8 +888,11 @@ extern const VMStateInfo vmstate_info_bitmap;
#define VMSTATE_PARTIAL_BUFFER(_f, _s, _size) \
VMSTATE_STATIC_BUFFER(_f, _s, 0, NULL, 0, _size)
#define VMSTATE_BUFFER_START_MIDDLE_V(_f, _s, _start, _v) \
VMSTATE_STATIC_BUFFER(_f, _s, _v, NULL, _start, sizeof(typeof_field(_s, _f)))
#define VMSTATE_BUFFER_START_MIDDLE(_f, _s, _start) \
VMSTATE_STATIC_BUFFER(_f, _s, 0, NULL, _start, sizeof(typeof_field(_s, _f)))
VMSTATE_BUFFER_START_MIDDLE_V(_f, _s, _start, 0)
#define VMSTATE_PARTIAL_VBUFFER(_f, _s, _size) \
VMSTATE_VBUFFER(_f, _s, 0, NULL, 0, _size)

View File

@@ -5,3 +5,5 @@ obj-$(TARGET_HAS_BFLT) += flatload.o
obj-$(TARGET_I386) += vm86.o
obj-$(TARGET_ARM) += arm/nwfpe/
obj-$(TARGET_M68K) += m68k-sim.o
obj-binfmt-y = binfmt.o

68
linux-user/binfmt.c Normal file
View File

@@ -0,0 +1,68 @@
#include <stdio.h>
#include <stdarg.h>
#include <unistd.h>
#include <libgen.h>
#include <string.h>
#include <stdlib.h>
#ifdef __x86_64__
#define ARCH_NAME "x86_64"
#endif
int main(int argc, char **argv, char **envp)
{
char *binfmt;
char **new_argv;
/*
* Check if our file name ends with -binfmt
*/
binfmt = argv[0] + strlen(argv[0]) - strlen("-binfmt");
if (strcmp(binfmt, "-binfmt")) {
fprintf(stderr, "%s: Invalid executable name\n", argv[0]);
exit(1);
}
if (argc < 3) {
fprintf(stderr, "%s: Please use me through binfmt with P flag\n",
argv[0]);
exit(1);
}
binfmt[0] = '\0';
/* Now argv[0] is the real qemu binary name */
#ifdef ARCH_NAME
{
char *hostbin;
char *guestarch;
int r;
guestarch = strrchr(argv[0], '-') ;
if (!guestarch) {
goto skip;
}
guestarch++;
r = asprintf(&hostbin, "/emul/" ARCH_NAME "-for-%s/%s", guestarch, argv[1]);
if ((r > 0) && !access(hostbin, X_OK)) {
/*
* We found a host binary replacement for the non-host binary. Let's
* use that instead!
*/
return execve(hostbin, &argv[2], envp);
}
}
skip:
#endif
new_argv = (char **)malloc((argc + 2) * sizeof(*new_argv));
if (argc > 3) {
memcpy(&new_argv[4], &argv[3], (argc - 3) * sizeof(*new_argv));
}
new_argv[0] = argv[0];
new_argv[1] = (char *)"-0";
new_argv[2] = argv[2];
new_argv[3] = argv[1];
new_argv[argc + 1] = NULL;
return execve(new_argv[0], new_argv, envp);
}

View File

@@ -72,6 +72,24 @@
IOCTL(BLKGETSIZE, IOC_R, MK_PTR(TYPE_ULONG))
#ifdef BLKGETSIZE64
IOCTL(BLKGETSIZE64, IOC_R, MK_PTR(TYPE_ULONGLONG))
#endif
#ifdef BLKDISCARD
IOCTL(BLKDISCARD, IOC_W, MK_PTR(MK_STRUCT(STRUCT_blkdiscard)))
#endif
#ifdef BLKIOMIN
IOCTL(BLKIOMIN, IOC_R, MK_PTR(TYPE_INT))
#endif
#ifdef BLKIOOPT
IOCTL(BLKIOOPT, IOC_R, MK_PTR(TYPE_INT))
#endif
#ifdef BLKALIGNOFF
IOCTL(BLKALIGNOFF, IOC_R, MK_PTR(TYPE_INT))
#endif
#ifdef BLKPBSZGET
IOCTL(BLKPBSZGET, IOC_R, MK_PTR(TYPE_INT))
#endif
#ifdef BLKDISCARDZEROES
IOCTL(BLKDISCARDZEROES, IOC_R, MK_PTR(TYPE_INT))
#endif
IOCTL(BLKFLSBUF, 0, TYPE_NULL)
IOCTL(BLKRASET, 0, TYPE_INT)
@@ -90,6 +108,8 @@
IOCTL_SPECIAL(FS_IOC_FIEMAP, IOC_W | IOC_R, do_ioctl_fs_ioc_fiemap,
MK_PTR(MK_STRUCT(STRUCT_fiemap)))
#endif
IOCTL(FS_IOC_GETFLAGS, IOC_R, MK_PTR(TYPE_LONG))
IOCTL(FS_IOC_SETFLAGS, IOC_W, MK_PTR(TYPE_LONG))
IOCTL(SIOCATMARK, 0, TYPE_NULL)
IOCTL(SIOCGIFNAME, IOC_RW, MK_PTR(TYPE_INT))
@@ -319,6 +339,11 @@
IOCTL(VFAT_IOCTL_READDIR_BOTH, IOC_R, MK_PTR(MK_ARRAY(MK_STRUCT(STRUCT_dirent), 2)))
IOCTL(VFAT_IOCTL_READDIR_SHORT, IOC_R, MK_PTR(MK_ARRAY(MK_STRUCT(STRUCT_dirent), 2)))
/* FIXME: including these on x86 / x86_64 breaks qemu-i386 */
#ifdef __powerpc__
#include "ioctls_alsa.h"
#endif
IOCTL(LOOP_SET_FD, 0, TYPE_INT)
IOCTL(LOOP_CLR_FD, 0, TYPE_INT)
IOCTL(LOOP_SET_STATUS, IOC_W, MK_PTR(MK_STRUCT(STRUCT_loop_info)))
@@ -326,6 +351,7 @@
IOCTL(LOOP_SET_STATUS64, IOC_W, MK_PTR(MK_STRUCT(STRUCT_loop_info64)))
IOCTL(LOOP_GET_STATUS64, IOC_W, MK_PTR(MK_STRUCT(STRUCT_loop_info64)))
IOCTL(LOOP_CHANGE_FD, 0, TYPE_INT)
IOCTL_SPECIAL(LOOP_BOGUS_CMD, 0, do_ioctl_fail, TYPE_INT)
IOCTL(MTIOCTOP, IOC_W, MK_PTR(MK_STRUCT(STRUCT_mtop)))
IOCTL(MTIOCGET, IOC_R, MK_PTR(MK_STRUCT(STRUCT_mtget)))

467
linux-user/ioctls_alsa.h Normal file
View File

@@ -0,0 +1,467 @@
#define SNDRV_SEQ_IOCTL_PVERSION _IOR ('S', 0x00, int)
#define SNDRV_SEQ_IOCTL_CLIENT_ID _IOR ('S', 0x01, int)
#define SNDRV_SEQ_IOCTL_SYSTEM_INFO _IOWR('S', 0x02, struct sndrv_seq_system_info)
#define SNDRV_SEQ_IOCTL_RUNNING_MODE _IOWR('S', 0x03, struct sndrv_seq_running_info)
#define SNDRV_SEQ_IOCTL_GET_CLIENT_INFO _IOWR('S', 0x10, struct sndrv_seq_client_info)
#define SNDRV_SEQ_IOCTL_SET_CLIENT_INFO _IOW ('S', 0x11, struct sndrv_seq_client_info)
#define SNDRV_SEQ_IOCTL_CREATE_PORT _IOWR('S', 0x20, struct sndrv_seq_port_info)
#define SNDRV_SEQ_IOCTL_DELETE_PORT _IOW ('S', 0x21, struct sndrv_seq_port_info)
#define SNDRV_SEQ_IOCTL_GET_PORT_INFO _IOWR('S', 0x22, struct sndrv_seq_port_info)
#define SNDRV_SEQ_IOCTL_SET_PORT_INFO _IOW ('S', 0x23, struct sndrv_seq_port_info)
#define SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT _IOW ('S', 0x30, struct sndrv_seq_port_subscribe)
#define SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT _IOW ('S', 0x31, struct sndrv_seq_port_subscribe)
#define SNDRV_SEQ_IOCTL_CREATE_QUEUE _IOWR('S', 0x32, struct sndrv_seq_queue_info)
#define SNDRV_SEQ_IOCTL_DELETE_QUEUE _IOW ('S', 0x33, struct sndrv_seq_queue_info)
#define SNDRV_SEQ_IOCTL_GET_QUEUE_INFO _IOWR('S', 0x34, struct sndrv_seq_queue_info)
#define SNDRV_SEQ_IOCTL_SET_QUEUE_INFO _IOWR('S', 0x35, struct sndrv_seq_queue_info)
#define SNDRV_SEQ_IOCTL_GET_NAMED_QUEUE _IOWR('S', 0x36, struct sndrv_seq_queue_info)
#define SNDRV_SEQ_IOCTL_GET_QUEUE_STATUS _IOWR('S', 0x40, struct sndrv_seq_queue_status)
#define SNDRV_SEQ_IOCTL_GET_QUEUE_TEMPO _IOWR('S', 0x41, struct sndrv_seq_queue_tempo)
#define SNDRV_SEQ_IOCTL_SET_QUEUE_TEMPO _IOW ('S', 0x42, struct sndrv_seq_queue_tempo)
#define SNDRV_SEQ_IOCTL_GET_QUEUE_OWNER _IOWR('S', 0x43, struct sndrv_seq_queue_owner)
#define SNDRV_SEQ_IOCTL_SET_QUEUE_OWNER _IOW ('S', 0x44, struct sndrv_seq_queue_owner)
#define SNDRV_SEQ_IOCTL_GET_QUEUE_TIMER _IOWR('S', 0x45, struct sndrv_seq_queue_timer)
#define SNDRV_SEQ_IOCTL_SET_QUEUE_TIMER _IOW ('S', 0x46, struct sndrv_seq_queue_timer)
#define SNDRV_SEQ_IOCTL_GET_QUEUE_SYNC _IOWR('S', 0x53, struct sndrv_seq_queue_sync)
#define SNDRV_SEQ_IOCTL_SET_QUEUE_SYNC _IOW ('S', 0x54, struct sndrv_seq_queue_sync)
#define SNDRV_SEQ_IOCTL_GET_QUEUE_CLIENT _IOWR('S', 0x49, struct sndrv_seq_queue_client)
#define SNDRV_SEQ_IOCTL_SET_QUEUE_CLIENT _IOW ('S', 0x4a, struct sndrv_seq_queue_client)
#define SNDRV_SEQ_IOCTL_GET_CLIENT_POOL _IOWR('S', 0x4b, struct sndrv_seq_client_pool)
#define SNDRV_SEQ_IOCTL_SET_CLIENT_POOL _IOW ('S', 0x4c, struct sndrv_seq_client_pool)
#define SNDRV_SEQ_IOCTL_REMOVE_EVENTS _IOW ('S', 0x4e, struct sndrv_seq_remove_events)
#define SNDRV_SEQ_IOCTL_QUERY_SUBS _IOWR('S', 0x4f, struct sndrv_seq_query_subs)
#define SNDRV_SEQ_IOCTL_GET_SUBSCRIPTION _IOWR('S', 0x50, struct sndrv_seq_port_subscribe)
#define SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT _IOWR('S', 0x51, struct sndrv_seq_client_info)
#define SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT _IOWR('S', 0x52, struct sndrv_seq_port_info)
#define SNDRV_DM_FM_IOCTL_INFO _IOR('H', 0x20, snd_dm_fm_info_t)
#define SNDRV_DM_FM_IOCTL_RESET _IO ('H', 0x21)
#define SNDRV_DM_FM_IOCTL_PLAY_NOTE _IOW('H', 0x22, snd_dm_fm_note_t)
#define SNDRV_DM_FM_IOCTL_SET_VOICE _IOW('H', 0x23, snd_dm_fm_voice_t)
#define SNDRV_DM_FM_IOCTL_SET_PARAMS _IOW('H', 0x24, snd_dm_fm_params_t)
#define SNDRV_DM_FM_IOCTL_SET_MODE _IOW('H', 0x25, int)
#define SNDRV_DM_FM_IOCTL_SET_CONNECTION _IOW('H', 0x26, int)
#define SNDRV_DM_FM_OSS_IOCTL_RESET 0x20
#define SNDRV_DM_FM_OSS_IOCTL_PLAY_NOTE 0x21
#define SNDRV_DM_FM_OSS_IOCTL_SET_VOICE 0x22
#define SNDRV_DM_FM_OSS_IOCTL_SET_PARAMS 0x23
#define SNDRV_DM_FM_OSS_IOCTL_SET_MODE 0x24
#define SNDRV_DM_FM_OSS_IOCTL_SET_OPL 0x25
#define SNDRV_HWDEP_IOCTL_PVERSION _IOR ('H', 0x00, int)
#define SNDRV_HWDEP_IOCTL_INFO _IOR ('H', 0x01, struct sndrv_hwdep_info)
#define SNDRV_HWDEP_IOCTL_DSP_STATUS _IOR('H', 0x02, struct sndrv_hwdep_dsp_status)
#define SNDRV_HWDEP_IOCTL_DSP_LOAD _IOW('H', 0x03, struct sndrv_hwdep_dsp_image)
#define SNDRV_PCM_IOCTL_PVERSION _IOR('A', 0x00, int)
#define SNDRV_PCM_IOCTL_INFO _IOR('A', 0x01, struct sndrv_pcm_info)
#define SNDRV_PCM_IOCTL_TSTAMP _IOW('A', 0x02, int)
#define SNDRV_PCM_IOCTL_HW_REFINE _IOWR('A', 0x10, struct sndrv_pcm_hw_params)
#define SNDRV_PCM_IOCTL_HW_PARAMS _IOWR('A', 0x11, struct sndrv_pcm_hw_params)
#define SNDRV_PCM_IOCTL_HW_FREE _IO('A', 0x12)
#define SNDRV_PCM_IOCTL_SW_PARAMS _IOWR('A', 0x13, struct sndrv_pcm_sw_params)
#define SNDRV_PCM_IOCTL_STATUS _IOR('A', 0x20, struct sndrv_pcm_status)
#define SNDRV_PCM_IOCTL_DELAY _IOR('A', 0x21, sndrv_pcm_sframes_t)
#define SNDRV_PCM_IOCTL_HWSYNC _IO('A', 0x22)
#define SNDRV_PCM_IOCTL_SYNC_PTR _IOWR('A', 0x23, struct sndrv_pcm_sync_ptr)
#define SNDRV_PCM_IOCTL_CHANNEL_INFO _IOR('A', 0x32, struct sndrv_pcm_channel_info)
#define SNDRV_PCM_IOCTL_PREPARE _IO('A', 0x40)
#define SNDRV_PCM_IOCTL_RESET _IO('A', 0x41)
#define SNDRV_PCM_IOCTL_START _IO('A', 0x42)
#define SNDRV_PCM_IOCTL_DROP _IO('A', 0x43)
#define SNDRV_PCM_IOCTL_DRAIN _IO('A', 0x44)
#define SNDRV_PCM_IOCTL_PAUSE _IOW('A', 0x45, int)
#define SNDRV_PCM_IOCTL_REWIND _IOW('A', 0x46, sndrv_pcm_uframes_t)
#define SNDRV_PCM_IOCTL_RESUME _IO('A', 0x47)
#define SNDRV_PCM_IOCTL_XRUN _IO('A', 0x48)
#define SNDRV_PCM_IOCTL_FORWARD _IOW('A', 0x49, sndrv_pcm_uframes_t)
#define SNDRV_PCM_IOCTL_WRITEI_FRAMES _IOW('A', 0x50, struct sndrv_xferi)
#define SNDRV_PCM_IOCTL_READI_FRAMES _IOR('A', 0x51, struct sndrv_xferi)
#define SNDRV_PCM_IOCTL_WRITEN_FRAMES _IOW('A', 0x52, struct sndrv_xfern)
#define SNDRV_PCM_IOCTL_READN_FRAMES _IOR('A', 0x53, struct sndrv_xfern)
#define SNDRV_PCM_IOCTL_LINK _IOW('A', 0x60, int)
#define SNDRV_PCM_IOCTL_UNLINK _IO('A', 0x61)
#define SNDRV_RAWMIDI_IOCTL_PVERSION _IOR('W', 0x00, int)
#define SNDRV_RAWMIDI_IOCTL_INFO _IOR('W', 0x01, struct sndrv_rawmidi_info)
#define SNDRV_RAWMIDI_IOCTL_PARAMS _IOWR('W', 0x10, struct sndrv_rawmidi_params)
#define SNDRV_RAWMIDI_IOCTL_STATUS _IOWR('W', 0x20, struct sndrv_rawmidi_status)
#define SNDRV_RAWMIDI_IOCTL_DROP _IOW('W', 0x30, int)
#define SNDRV_RAWMIDI_IOCTL_DRAIN _IOW('W', 0x31, int)
#define SNDRV_TIMER_IOCTL_PVERSION _IOR('T', 0x00, int)
#define SNDRV_TIMER_IOCTL_NEXT_DEVICE _IOWR('T', 0x01, struct sndrv_timer_id)
#define SNDRV_TIMER_IOCTL_TREAD _IOW('T', 0x02, int)
#define SNDRV_TIMER_IOCTL_GINFO _IOWR('T', 0x03, struct sndrv_timer_ginfo)
#define SNDRV_TIMER_IOCTL_GPARAMS _IOW('T', 0x04, struct sndrv_timer_gparams)
#define SNDRV_TIMER_IOCTL_GSTATUS _IOWR('T', 0x05, struct sndrv_timer_gstatus)
#define SNDRV_TIMER_IOCTL_SELECT _IOW('T', 0x10, struct sndrv_timer_select)
#define SNDRV_TIMER_IOCTL_INFO _IOR('T', 0x11, struct sndrv_timer_info)
#define SNDRV_TIMER_IOCTL_PARAMS _IOW('T', 0x12, struct sndrv_timer_params)
#define SNDRV_TIMER_IOCTL_STATUS _IOR('T', 0x14, struct sndrv_timer_status)
#define SNDRV_TIMER_IOCTL_START _IO('T', 0xa0)
#define SNDRV_TIMER_IOCTL_STOP _IO('T', 0xa1)
#define SNDRV_TIMER_IOCTL_CONTINUE _IO('T', 0xa2)
#define SNDRV_TIMER_IOCTL_PAUSE _IO('T', 0xa3)
#define SNDRV_CTL_IOCTL_PVERSION _IOR('U', 0x00, int)
#define SNDRV_CTL_IOCTL_CARD_INFO _IOR('U', 0x01, struct sndrv_ctl_card_info)
#define SNDRV_CTL_IOCTL_ELEM_LIST _IOWR('U', 0x10, struct sndrv_ctl_elem_list)
#define SNDRV_CTL_IOCTL_ELEM_INFO _IOWR('U', 0x11, struct sndrv_ctl_elem_info)
#define SNDRV_CTL_IOCTL_ELEM_READ _IOWR('U', 0x12, struct sndrv_ctl_elem_value)
#define SNDRV_CTL_IOCTL_ELEM_WRITE _IOWR('U', 0x13, struct sndrv_ctl_elem_value)
#define SNDRV_CTL_IOCTL_ELEM_LOCK _IOW('U', 0x14, struct sndrv_ctl_elem_id)
#define SNDRV_CTL_IOCTL_ELEM_UNLOCK _IOW('U', 0x15, struct sndrv_ctl_elem_id)
#define SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS _IOWR('U', 0x16, int)
#define SNDRV_CTL_IOCTL_ELEM_ADD _IOWR('U', 0x17, struct sndrv_ctl_elem_info)
#define SNDRV_CTL_IOCTL_ELEM_REPLACE _IOWR('U', 0x18, struct sndrv_ctl_elem_info)
#define SNDRV_CTL_IOCTL_ELEM_REMOVE _IOWR('U', 0x19, struct sndrv_ctl_elem_id)
#define SNDRV_CTL_IOCTL_TLV_READ _IOWR('U', 0x1a, struct sndrv_ctl_tlv)
#define SNDRV_CTL_IOCTL_TLV_WRITE _IOWR('U', 0x1b, struct sndrv_ctl_tlv)
#define SNDRV_CTL_IOCTL_TLV_COMMAND _IOWR('U', 0x1c, struct sndrv_ctl_tlv)
#define SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE _IOWR('U', 0x20, int)
#define SNDRV_CTL_IOCTL_HWDEP_INFO _IOR('U', 0x21, struct sndrv_hwdep_info)
#define SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE _IOR('U', 0x30, int)
#define SNDRV_CTL_IOCTL_PCM_INFO _IOWR('U', 0x31, struct sndrv_pcm_info)
#define SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE _IOW('U', 0x32, int)
#define SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE _IOWR('U', 0x40, int)
#define SNDRV_CTL_IOCTL_RAWMIDI_INFO _IOWR('U', 0x41, struct sndrv_rawmidi_info)
#define SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE _IOW('U', 0x42, int)
#define SNDRV_CTL_IOCTL_POWER _IOWR('U', 0xd0, int)
#define SNDRV_CTL_IOCTL_POWER_STATE _IOR('U', 0xd1, int)
#define SNDRV_IOCTL_READV _IOW('K', 0x00, struct sndrv_xferv)
#define SNDRV_IOCTL_WRITEV _IOW('K', 0x01, struct sndrv_xferv)
#define SNDRV_EMU10K1_IOCTL_INFO _IOR ('H', 0x10, emu10k1_fx8010_info_t)
#define SNDRV_EMU10K1_IOCTL_CODE_POKE _IOW ('H', 0x11, emu10k1_fx8010_code_t)
#define SNDRV_EMU10K1_IOCTL_CODE_PEEK _IOWR('H', 0x12, emu10k1_fx8010_code_t)
#define SNDRV_EMU10K1_IOCTL_TRAM_SETUP _IOW ('H', 0x20, int)
#define SNDRV_EMU10K1_IOCTL_TRAM_POKE _IOW ('H', 0x21, emu10k1_fx8010_tram_t)
#define SNDRV_EMU10K1_IOCTL_TRAM_PEEK _IOWR('H', 0x22, emu10k1_fx8010_tram_t)
#define SNDRV_EMU10K1_IOCTL_PCM_POKE _IOW ('H', 0x30, emu10k1_fx8010_pcm_t)
#define SNDRV_EMU10K1_IOCTL_PCM_PEEK _IOWR('H', 0x31, emu10k1_fx8010_pcm_t)
#define SNDRV_EMU10K1_IOCTL_PVERSION _IOR ('H', 0x40, int)
#define SNDRV_EMU10K1_IOCTL_STOP _IO ('H', 0x80)
#define SNDRV_EMU10K1_IOCTL_CONTINUE _IO ('H', 0x81)
#define SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER _IO ('H', 0x82)
#define SNDRV_EMU10K1_IOCTL_SINGLE_STEP _IOW ('H', 0x83, int)
#define SNDRV_EMU10K1_IOCTL_DBG_READ _IOR ('H', 0x84, int)
#define SNDRV_HDSP_IOCTL_GET_PEAK_RMS _IOR('H', 0x40, hdsp_peak_rms_t)
#define SNDRV_HDSP_IOCTL_GET_CONFIG_INFO _IOR('H', 0x41, hdsp_config_info_t)
#define SNDRV_HDSP_IOCTL_UPLOAD_FIRMWARE _IOW('H', 0x42, hdsp_firmware_t)
#define SNDRV_HDSP_IOCTL_GET_VERSION _IOR('H', 0x43, hdsp_version_t)
#define SNDRV_HDSP_IOCTL_GET_MIXER _IOR('H', 0x44, hdsp_mixer_t)
#define SNDRV_HDSP_IOCTL_GET_9632_AEB _IOR('H', 0x45, hdsp_9632_aeb_t)
#define SNDRV_SB_CSP_IOCTL_INFO _IOR('H', 0x10, snd_sb_csp_info_t)
#define SNDRV_SB_CSP_IOCTL_LOAD_CODE _IOW('H', 0x11, snd_sb_csp_microcode_t)
#define SNDRV_SB_CSP_IOCTL_UNLOAD_CODE _IO('H', 0x12)
#define SNDRV_SB_CSP_IOCTL_START _IOW('H', 0x13, snd_sb_csp_start_t)
#define SNDRV_SB_CSP_IOCTL_STOP _IO('H', 0x14)
#define SNDRV_SB_CSP_IOCTL_PAUSE _IO('H', 0x15)
#define SNDRV_SB_CSP_IOCTL_RESTART _IO('H', 0x16)
#define SND_SSCAPE_LOAD_BOOTB _IOWR('P', 100, struct sscape_bootblock)
#define SND_SSCAPE_LOAD_MCODE _IOW ('P', 101, struct sscape_microcode)
#define TARGET_SNDRV_SEQ_IOCTL_PVERSION TARGET_IOR ('S', 0x00, int)
#define TARGET_SNDRV_SEQ_IOCTL_CLIENT_ID TARGET_IOR ('S', 0x01, int)
#define TARGET_SNDRV_SEQ_IOCTL_SYSTEM_INFO TARGET_IOWRU('S', 0x02)
#define TARGET_SNDRV_SEQ_IOCTL_RUNNING_MODE TARGET_IOWRU('S', 0x03)
#define TARGET_SNDRV_SEQ_IOCTL_GET_CLIENT_INFO TARGET_IOWRU('S', 0x10)
#define TARGET_SNDRV_SEQ_IOCTL_SET_CLIENT_INFO TARGET_IOWU ('S', 0x11)
#define TARGET_SNDRV_SEQ_IOCTL_CREATE_PORT TARGET_IOWRU('S', 0x20)
#define TARGET_SNDRV_SEQ_IOCTL_DELETE_PORT TARGET_IOWU ('S', 0x21)
#define TARGET_SNDRV_SEQ_IOCTL_GET_PORT_INFO TARGET_IOWRU('S', 0x22)
#define TARGET_SNDRV_SEQ_IOCTL_SET_PORT_INFO TARGET_IOWU ('S', 0x23)
#define TARGET_SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT TARGET_IOWU ('S', 0x30)
#define TARGET_SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT TARGET_IOWU ('S', 0x31)
#define TARGET_SNDRV_SEQ_IOCTL_CREATE_QUEUE TARGET_IOWRU('S', 0x32)
#define TARGET_SNDRV_SEQ_IOCTL_DELETE_QUEUE TARGET_IOWU ('S', 0x33)
#define TARGET_SNDRV_SEQ_IOCTL_GET_QUEUE_INFO TARGET_IOWRU('S', 0x34)
#define TARGET_SNDRV_SEQ_IOCTL_SET_QUEUE_INFO TARGET_IOWRU('S', 0x35)
#define TARGET_SNDRV_SEQ_IOCTL_GET_NAMED_QUEUE TARGET_IOWRU('S', 0x36)
#define TARGET_SNDRV_SEQ_IOCTL_GET_QUEUE_STATUS TARGET_IOWRU('S', 0x40)
#define TARGET_SNDRV_SEQ_IOCTL_GET_QUEUE_TEMPO TARGET_IOWRU('S', 0x41)
#define TARGET_SNDRV_SEQ_IOCTL_SET_QUEUE_TEMPO TARGET_IOWU ('S', 0x42)
#define TARGET_SNDRV_SEQ_IOCTL_GET_QUEUE_OWNER TARGET_IOWRU('S', 0x43)
#define TARGET_SNDRV_SEQ_IOCTL_SET_QUEUE_OWNER TARGET_IOWU ('S', 0x44)
#define TARGET_SNDRV_SEQ_IOCTL_GET_QUEUE_TIMER TARGET_IOWRU('S', 0x45)
#define TARGET_SNDRV_SEQ_IOCTL_SET_QUEUE_TIMER TARGET_IOWU ('S', 0x46)
#define TARGET_SNDRV_SEQ_IOCTL_GET_QUEUE_SYNC TARGET_IOWRU('S', 0x53)
#define TARGET_SNDRV_SEQ_IOCTL_SET_QUEUE_SYNC TARGET_IOWU ('S', 0x54)
#define TARGET_SNDRV_SEQ_IOCTL_GET_QUEUE_CLIENT TARGET_IOWRU('S', 0x49)
#define TARGET_SNDRV_SEQ_IOCTL_SET_QUEUE_CLIENT TARGET_IOWU ('S', 0x4a)
#define TARGET_SNDRV_SEQ_IOCTL_GET_CLIENT_POOL TARGET_IOWRU('S', 0x4b)
#define TARGET_SNDRV_SEQ_IOCTL_SET_CLIENT_POOL TARGET_IOWU ('S', 0x4c)
#define TARGET_SNDRV_SEQ_IOCTL_REMOVE_EVENTS TARGET_IOWU ('S', 0x4e)
#define TARGET_SNDRV_SEQ_IOCTL_QUERY_SUBS TARGET_IOWRU('S', 0x4f)
#define TARGET_SNDRV_SEQ_IOCTL_GET_SUBSCRIPTION TARGET_IOWRU('S', 0x50)
#define TARGET_SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT TARGET_IOWRU('S', 0x51)
#define TARGET_SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT TARGET_IOWRU('S', 0x52)
#define TARGET_SNDRV_DM_FM_IOCTL_INFO TARGET_IORU('H', 0x20)
#define TARGET_SNDRV_DM_FM_IOCTL_RESET TARGET_IO ('H', 0x21)
#define TARGET_SNDRV_DM_FM_IOCTL_PLAY_NOTE TARGET_IOWU('H', 0x22)
#define TARGET_SNDRV_DM_FM_IOCTL_SET_VOICE TARGET_IOWU('H', 0x23)
#define TARGET_SNDRV_DM_FM_IOCTL_SET_PARAMS TARGET_IOWU('H', 0x24)
#define TARGET_SNDRV_DM_FM_IOCTL_SET_MODE TARGET_IOW('H', 0x25, int)
#define TARGET_SNDRV_DM_FM_IOCTL_SET_CONNECTION TARGET_IOW('H', 0x26, int)
#define TARGET_SNDRV_DM_FM_OSS_IOCTL_RESET 0x20
#define TARGET_SNDRV_DM_FM_OSS_IOCTL_PLAY_NOTE 0x21
#define TARGET_SNDRV_DM_FM_OSS_IOCTL_SET_VOICE 0x22
#define TARGET_SNDRV_DM_FM_OSS_IOCTL_SET_PARAMS 0x23
#define TARGET_SNDRV_DM_FM_OSS_IOCTL_SET_MODE 0x24
#define TARGET_SNDRV_DM_FM_OSS_IOCTL_SET_OPL 0x25
#define TARGET_SNDRV_HWDEP_IOCTL_PVERSION TARGET_IOR ('H', 0x00, int)
#define TARGET_SNDRV_HWDEP_IOCTL_INFO TARGET_IORU ('H', 0x01)
#define TARGET_SNDRV_HWDEP_IOCTL_DSP_STATUS TARGET_IORU('H', 0x02)
#define TARGET_SNDRV_HWDEP_IOCTL_DSP_LOAD TARGET_IOWU('H', 0x03)
#define TARGET_SNDRV_PCM_IOCTL_PVERSION TARGET_IOR('A', 0x00, int)
#define TARGET_SNDRV_PCM_IOCTL_INFO TARGET_IORU('A', 0x01)
#define TARGET_SNDRV_PCM_IOCTL_TSTAMP TARGET_IOW('A', 0x02, int)
#define TARGET_SNDRV_PCM_IOCTL_HW_REFINE TARGET_IOWRU('A', 0x10)
#define TARGET_SNDRV_PCM_IOCTL_HW_PARAMS TARGET_IOWRU('A', 0x11)
#define TARGET_SNDRV_PCM_IOCTL_HW_FREE TARGET_IO('A', 0x12)
#define TARGET_SNDRV_PCM_IOCTL_SW_PARAMS TARGET_IOWRU('A', 0x13)
#define TARGET_SNDRV_PCM_IOCTL_STATUS TARGET_IORU('A', 0x20)
#define TARGET_SNDRV_PCM_IOCTL_DELAY TARGET_IORU('A', 0x21)
#define TARGET_SNDRV_PCM_IOCTL_HWSYNC TARGET_IO('A', 0x22)
#define TARGET_SNDRV_PCM_IOCTL_SYNC_PTR TARGET_IOWRU('A', 0x23)
#define TARGET_SNDRV_PCM_IOCTL_CHANNEL_INFO TARGET_IORU('A', 0x32)
#define TARGET_SNDRV_PCM_IOCTL_PREPARE TARGET_IO('A', 0x40)
#define TARGET_SNDRV_PCM_IOCTL_RESET TARGET_IO('A', 0x41)
#define TARGET_SNDRV_PCM_IOCTL_START TARGET_IO('A', 0x42)
#define TARGET_SNDRV_PCM_IOCTL_DROP TARGET_IO('A', 0x43)
#define TARGET_SNDRV_PCM_IOCTL_DRAIN TARGET_IO('A', 0x44)
#define TARGET_SNDRV_PCM_IOCTL_PAUSE TARGET_IOW('A', 0x45, int)
#define TARGET_SNDRV_PCM_IOCTL_REWIND TARGET_IOWU('A', 0x46)
#define TARGET_SNDRV_PCM_IOCTL_RESUME TARGET_IO('A', 0x47)
#define TARGET_SNDRV_PCM_IOCTL_XRUN TARGET_IO('A', 0x48)
#define TARGET_SNDRV_PCM_IOCTL_FORWARD TARGET_IOWU('A', 0x49)
#define TARGET_SNDRV_PCM_IOCTL_WRITEI_FRAMES TARGET_IOWU('A', 0x50)
#define TARGET_SNDRV_PCM_IOCTL_READI_FRAMES TARGET_IORU('A', 0x51)
#define TARGET_SNDRV_PCM_IOCTL_WRITEN_FRAMES TARGET_IOWU('A', 0x52)
#define TARGET_SNDRV_PCM_IOCTL_READN_FRAMES TARGET_IORU('A', 0x53)
#define TARGET_SNDRV_PCM_IOCTL_LINK TARGET_IOW('A', 0x60, int)
#define TARGET_SNDRV_PCM_IOCTL_UNLINK TARGET_IO('A', 0x61)
#define TARGET_SNDRV_RAWMIDI_IOCTL_PVERSION TARGET_IOR('W', 0x00, int)
#define TARGET_SNDRV_RAWMIDI_IOCTL_INFO TARGET_IORU('W', 0x01)
#define TARGET_SNDRV_RAWMIDI_IOCTL_PARAMS TARGET_IOWRU('W', 0x10)
#define TARGET_SNDRV_RAWMIDI_IOCTL_STATUS TARGET_IOWRU('W', 0x20)
#define TARGET_SNDRV_RAWMIDI_IOCTL_DROP TARGET_IOW('W', 0x30, int)
#define TARGET_SNDRV_RAWMIDI_IOCTL_DRAIN TARGET_IOW('W', 0x31, int)
#define TARGET_SNDRV_TIMER_IOCTL_PVERSION TARGET_IOR('T', 0x00, int)
#define TARGET_SNDRV_TIMER_IOCTL_NEXT_DEVICE TARGET_IOWRU('T', 0x01)
#define TARGET_SNDRV_TIMER_IOCTL_TREAD TARGET_IOW('T', 0x02, int)
#define TARGET_SNDRV_TIMER_IOCTL_GINFO TARGET_IOWRU('T', 0x03)
#define TARGET_SNDRV_TIMER_IOCTL_GPARAMS TARGET_IOWU('T', 0x04)
#define TARGET_SNDRV_TIMER_IOCTL_GSTATUS TARGET_IOWRU('T', 0x05)
#define TARGET_SNDRV_TIMER_IOCTL_SELECT TARGET_IOWU('T', 0x10)
#define TARGET_SNDRV_TIMER_IOCTL_INFO TARGET_IORU('T', 0x11)
#define TARGET_SNDRV_TIMER_IOCTL_PARAMS TARGET_IOWU('T', 0x12)
#define TARGET_SNDRV_TIMER_IOCTL_STATUS TARGET_IORU('T', 0x14)
#define TARGET_SNDRV_TIMER_IOCTL_START TARGET_IO('T', 0xa0)
#define TARGET_SNDRV_TIMER_IOCTL_STOP TARGET_IO('T', 0xa1)
#define TARGET_SNDRV_TIMER_IOCTL_CONTINUE TARGET_IO('T', 0xa2)
#define TARGET_SNDRV_TIMER_IOCTL_PAUSE TARGET_IO('T', 0xa3)
#define TARGET_SNDRV_CTL_IOCTL_PVERSION TARGET_IOR('U', 0x00, int)
#define TARGET_SNDRV_CTL_IOCTL_CARD_INFO TARGET_IORU('U', 0x01)
#define TARGET_SNDRV_CTL_IOCTL_ELEM_LIST TARGET_IOWRU('U', 0x10)
#define TARGET_SNDRV_CTL_IOCTL_ELEM_INFO TARGET_IOWRU('U', 0x11)
#define TARGET_SNDRV_CTL_IOCTL_ELEM_READ TARGET_IOWRU('U', 0x12)
#define TARGET_SNDRV_CTL_IOCTL_ELEM_WRITE TARGET_IOWRU('U', 0x13)
#define TARGET_SNDRV_CTL_IOCTL_ELEM_LOCK TARGET_IOWU('U', 0x14)
#define TARGET_SNDRV_CTL_IOCTL_ELEM_UNLOCK TARGET_IOWU('U', 0x15)
#define TARGET_SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS TARGET_IOWR('U', 0x16, int)
#define TARGET_SNDRV_CTL_IOCTL_ELEM_ADD TARGET_IOWRU('U', 0x17)
#define TARGET_SNDRV_CTL_IOCTL_ELEM_REPLACE TARGET_IOWRU('U', 0x18)
#define TARGET_SNDRV_CTL_IOCTL_ELEM_REMOVE TARGET_IOWRU('U', 0x19)
#define TARGET_SNDRV_CTL_IOCTL_TLV_READ TARGET_IOWRU('U', 0x1a)
#define TARGET_SNDRV_CTL_IOCTL_TLV_WRITE TARGET_IOWRU('U', 0x1b)
#define TARGET_SNDRV_CTL_IOCTL_TLV_COMMAND TARGET_IOWRU('U', 0x1c)
#define TARGET_SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE TARGET_IOWR('U', 0x20, int)
#define TARGET_SNDRV_CTL_IOCTL_HWDEP_INFO TARGET_IORU('U', 0x21)
#define TARGET_SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE TARGET_IOR('U', 0x30, int)
#define TARGET_SNDRV_CTL_IOCTL_PCM_INFO TARGET_IOWRU('U', 0x31)
#define TARGET_SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE TARGET_IOW('U', 0x32, int)
#define TARGET_SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE TARGET_IOWR('U', 0x40, int)
#define TARGET_SNDRV_CTL_IOCTL_RAWMIDI_INFO TARGET_IOWRU('U', 0x41)
#define TARGET_SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE TARGET_IOW('U', 0x42, int)
#define TARGET_SNDRV_CTL_IOCTL_POWER TARGET_IOWR('U', 0xd0, int)
#define TARGET_SNDRV_CTL_IOCTL_POWER_STATE TARGET_IOR('U', 0xd1, int)
#define TARGET_SNDRV_IOCTL_READV TARGET_IOWU('K', 0x00)
#define TARGET_SNDRV_IOCTL_WRITEV TARGET_IOWU('K', 0x01)
#define TARGET_SNDRV_EMU10K1_IOCTL_INFO TARGET_IORU ('H', 0x10)
#define TARGET_SNDRV_EMU10K1_IOCTL_CODE_POKE TARGET_IOWU ('H', 0x11)
#define TARGET_SNDRV_EMU10K1_IOCTL_CODE_PEEK TARGET_IOWRU('H', 0x12)
#define TARGET_SNDRV_EMU10K1_IOCTL_TRAM_SETUP TARGET_IOW ('H', 0x20, int)
#define TARGET_SNDRV_EMU10K1_IOCTL_TRAM_POKE TARGET_IOWU ('H', 0x21)
#define TARGET_SNDRV_EMU10K1_IOCTL_TRAM_PEEK TARGET_IOWRU('H', 0x22)
#define TARGET_SNDRV_EMU10K1_IOCTL_PCM_POKE TARGET_IOWU ('H', 0x30)
#define TARGET_SNDRV_EMU10K1_IOCTL_PCM_PEEK TARGET_IOWRU('H', 0x31)
#define TARGET_SNDRV_EMU10K1_IOCTL_PVERSION TARGET_IOR ('H', 0x40, int)
#define TARGET_SNDRV_EMU10K1_IOCTL_STOP TARGET_IO ('H', 0x80)
#define TARGET_SNDRV_EMU10K1_IOCTL_CONTINUE TARGET_IO ('H', 0x81)
#define TARGET_SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER TARGET_IO ('H', 0x82)
#define TARGET_SNDRV_EMU10K1_IOCTL_SINGLE_STEP TARGET_IOW ('H', 0x83, int)
#define TARGET_SNDRV_EMU10K1_IOCTL_DBG_READ TARGET_IOR ('H', 0x84, int)
#define TARGET_SNDRV_HDSP_IOCTL_GET_PEAK_RMS TARGET_IORU('H', 0x40)
#define TARGET_SNDRV_HDSP_IOCTL_GET_CONFIG_INFO TARGET_IORU('H', 0x41)
#define TARGET_SNDRV_HDSP_IOCTL_UPLOAD_FIRMWARE TARGET_IOWU('H', 0x42)
#define TARGET_SNDRV_HDSP_IOCTL_GET_VERSION TARGET_IORU('H', 0x43)
#define TARGET_SNDRV_HDSP_IOCTL_GET_MIXER TARGET_IORU('H', 0x44)
#define TARGET_SNDRV_HDSP_IOCTL_GET_9632_AEB TARGET_IORU('H', 0x45)
#define TARGET_SNDRV_SB_CSP_IOCTL_INFO TARGET_IORU('H', 0x10)
#define TARGET_SNDRV_SB_CSP_IOCTL_LOAD_CODE TARGET_IOWU('H', 0x11)
#define TARGET_SNDRV_SB_CSP_IOCTL_UNLOAD_CODE TARGET_IO('H', 0x12)
#define TARGET_SNDRV_SB_CSP_IOCTL_START TARGET_IOWU('H', 0x13)
#define TARGET_SNDRV_SB_CSP_IOCTL_STOP TARGET_IO('H', 0x14)
#define TARGET_SNDRV_SB_CSP_IOCTL_PAUSE TARGET_IO('H', 0x15)
#define TARGET_SNDRV_SB_CSP_IOCTL_RESTART TARGET_IO('H', 0x16)
#define TARGET_SND_SSCAPE_LOAD_BOOTB TARGET_IOWRU('P', 100)
#define TARGET_SND_SSCAPE_LOAD_MCODE TARGET_IOWU ('P', 101)
IOCTL( SNDRV_SEQ_IOCTL_PVERSION , IOC_R, MK_PTR(TYPE_INT) )
IOCTL( SNDRV_SEQ_IOCTL_CLIENT_ID , IOC_R, MK_PTR(TYPE_INT) )
IOCTL( SNDRV_SEQ_IOCTL_SYSTEM_INFO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_system_info)) )
IOCTL( SNDRV_SEQ_IOCTL_RUNNING_MODE , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_running_info)) )
IOCTL( SNDRV_SEQ_IOCTL_GET_CLIENT_INFO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_client_info)) )
IOCTL( SNDRV_SEQ_IOCTL_SET_CLIENT_INFO , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_client_info)) )
IOCTL( SNDRV_SEQ_IOCTL_CREATE_PORT , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_port_info)) )
IOCTL( SNDRV_SEQ_IOCTL_DELETE_PORT , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_port_info)) )
IOCTL( SNDRV_SEQ_IOCTL_GET_PORT_INFO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_port_info)) )
IOCTL( SNDRV_SEQ_IOCTL_SET_PORT_INFO , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_port_info)) )
IOCTL( SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_port_subscribe)) )
IOCTL( SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_port_subscribe)) )
IOCTL( SNDRV_SEQ_IOCTL_CREATE_QUEUE , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_info)) )
IOCTL( SNDRV_SEQ_IOCTL_DELETE_QUEUE , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_info)) )
IOCTL( SNDRV_SEQ_IOCTL_GET_QUEUE_INFO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_info)) )
IOCTL( SNDRV_SEQ_IOCTL_SET_QUEUE_INFO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_info)) )
IOCTL( SNDRV_SEQ_IOCTL_GET_NAMED_QUEUE , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_info)) )
IOCTL( SNDRV_SEQ_IOCTL_GET_QUEUE_STATUS , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_status)) )
IOCTL( SNDRV_SEQ_IOCTL_GET_QUEUE_TEMPO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_tempo)) )
IOCTL( SNDRV_SEQ_IOCTL_SET_QUEUE_TEMPO , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_tempo)) )
//IOCTL( SNDRV_SEQ_IOCTL_GET_QUEUE_OWNER , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_owner)) )
//IOCTL( SNDRV_SEQ_IOCTL_SET_QUEUE_OWNER , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_owner)) )
IOCTL( SNDRV_SEQ_IOCTL_GET_QUEUE_TIMER , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_timer)) )
IOCTL( SNDRV_SEQ_IOCTL_SET_QUEUE_TIMER , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_timer)) )
//IOCTL( SNDRV_SEQ_IOCTL_GET_QUEUE_SYNC , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_sync)) )
//IOCTL( SNDRV_SEQ_IOCTL_SET_QUEUE_SYNC , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_sync)) )
IOCTL( SNDRV_SEQ_IOCTL_GET_QUEUE_CLIENT , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_client)) )
IOCTL( SNDRV_SEQ_IOCTL_SET_QUEUE_CLIENT , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_queue_client)) )
IOCTL( SNDRV_SEQ_IOCTL_GET_CLIENT_POOL , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_client_pool)) )
IOCTL( SNDRV_SEQ_IOCTL_SET_CLIENT_POOL , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_client_pool)) )
IOCTL( SNDRV_SEQ_IOCTL_REMOVE_EVENTS , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_remove_events)) )
IOCTL( SNDRV_SEQ_IOCTL_QUERY_SUBS , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_query_subs)) )
IOCTL( SNDRV_SEQ_IOCTL_GET_SUBSCRIPTION , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_port_subscribe)) )
IOCTL( SNDRV_SEQ_IOCTL_QUERY_NEXT_CLIENT , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_client_info)) )
IOCTL( SNDRV_SEQ_IOCTL_QUERY_NEXT_PORT , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_seq_port_info)) )
IOCTL( SNDRV_DM_FM_IOCTL_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_snd_dm_fm_info)) )
IOCTL( SNDRV_DM_FM_IOCTL_RESET , 0, TYPE_NULL )
IOCTL( SNDRV_DM_FM_IOCTL_PLAY_NOTE , IOC_W, MK_PTR(MK_STRUCT(STRUCT_snd_dm_fm_note)) )
IOCTL( SNDRV_DM_FM_IOCTL_SET_VOICE , IOC_W, MK_PTR(MK_STRUCT(STRUCT_snd_dm_fm_voice)) )
IOCTL( SNDRV_DM_FM_IOCTL_SET_PARAMS , IOC_W, MK_PTR(MK_STRUCT(STRUCT_snd_dm_fm_params)) )
IOCTL( SNDRV_DM_FM_IOCTL_SET_MODE , IOC_W, MK_PTR(TYPE_INT) )
IOCTL( SNDRV_DM_FM_IOCTL_SET_CONNECTION , IOC_W, MK_PTR(TYPE_INT) )
IOCTL( SNDRV_HWDEP_IOCTL_PVERSION , IOC_R, MK_PTR(TYPE_INT) )
IOCTL( SNDRV_HWDEP_IOCTL_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_hwdep_info)) )
IOCTL( SNDRV_HWDEP_IOCTL_DSP_STATUS , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_hwdep_dsp_status)) )
IOCTL( SNDRV_HWDEP_IOCTL_DSP_LOAD , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_hwdep_dsp_image)) )
IOCTL( SNDRV_PCM_IOCTL_PVERSION , IOC_R, MK_PTR(TYPE_INT) )
IOCTL( SNDRV_PCM_IOCTL_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_info)) )
IOCTL( SNDRV_PCM_IOCTL_TSTAMP , IOC_W, MK_PTR(TYPE_INT) )
IOCTL( SNDRV_PCM_IOCTL_HW_REFINE , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_hw_params)) )
IOCTL( SNDRV_PCM_IOCTL_HW_PARAMS , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_hw_params)) )
IOCTL( SNDRV_PCM_IOCTL_HW_FREE , 0, TYPE_NULL )
IOCTL( SNDRV_PCM_IOCTL_SW_PARAMS , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_sw_params)) )
IOCTL( SNDRV_PCM_IOCTL_STATUS , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_status)) )
IOCTL( SNDRV_PCM_IOCTL_DELAY , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_sframes)) )
IOCTL( SNDRV_PCM_IOCTL_HWSYNC , 0, TYPE_NULL )
IOCTL( SNDRV_PCM_IOCTL_SYNC_PTR , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_sync_ptr)) )
IOCTL( SNDRV_PCM_IOCTL_CHANNEL_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_channel_info)) )
IOCTL( SNDRV_PCM_IOCTL_PREPARE , 0, TYPE_NULL )
IOCTL( SNDRV_PCM_IOCTL_RESET , 0, TYPE_NULL )
IOCTL( SNDRV_PCM_IOCTL_START , 0, TYPE_NULL )
IOCTL( SNDRV_PCM_IOCTL_DROP , 0, TYPE_NULL )
IOCTL( SNDRV_PCM_IOCTL_DRAIN , 0, TYPE_NULL )
IOCTL( SNDRV_PCM_IOCTL_PAUSE , IOC_W, MK_PTR(TYPE_INT) )
IOCTL( SNDRV_PCM_IOCTL_REWIND , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_uframes)) )
IOCTL( SNDRV_PCM_IOCTL_RESUME , 0, TYPE_NULL )
IOCTL( SNDRV_PCM_IOCTL_XRUN , 0, TYPE_NULL )
IOCTL( SNDRV_PCM_IOCTL_FORWARD , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_uframes)) )
IOCTL( SNDRV_PCM_IOCTL_WRITEI_FRAMES , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_xferi)) )
IOCTL( SNDRV_PCM_IOCTL_READI_FRAMES , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_xferi)) )
IOCTL( SNDRV_PCM_IOCTL_WRITEN_FRAMES , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_xfern)) )
IOCTL( SNDRV_PCM_IOCTL_READN_FRAMES , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_xfern)) )
IOCTL( SNDRV_PCM_IOCTL_LINK , IOC_W, MK_PTR(TYPE_INT) )
IOCTL( SNDRV_PCM_IOCTL_UNLINK , 0, TYPE_NULL )
IOCTL( SNDRV_RAWMIDI_IOCTL_PVERSION , IOC_R, MK_PTR(TYPE_INT) )
IOCTL( SNDRV_RAWMIDI_IOCTL_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_rawmidi_info)) )
IOCTL( SNDRV_RAWMIDI_IOCTL_PARAMS , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_rawmidi_params)) )
IOCTL( SNDRV_RAWMIDI_IOCTL_STATUS , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_rawmidi_status)) )
IOCTL( SNDRV_RAWMIDI_IOCTL_DROP , IOC_W, MK_PTR(TYPE_INT) )
IOCTL( SNDRV_RAWMIDI_IOCTL_DRAIN , IOC_W, MK_PTR(TYPE_INT) )
IOCTL( SNDRV_TIMER_IOCTL_PVERSION , IOC_R, MK_PTR(TYPE_INT) )
IOCTL( SNDRV_TIMER_IOCTL_NEXT_DEVICE , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_timer_id)) )
IOCTL( SNDRV_TIMER_IOCTL_TREAD , IOC_W, MK_PTR(TYPE_INT) )
IOCTL( SNDRV_TIMER_IOCTL_GINFO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_timer_ginfo)) )
IOCTL( SNDRV_TIMER_IOCTL_GPARAMS , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_timer_gparams)) )
IOCTL( SNDRV_TIMER_IOCTL_GSTATUS , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_timer_gstatus)) )
IOCTL( SNDRV_TIMER_IOCTL_SELECT , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_timer_select)) )
IOCTL( SNDRV_TIMER_IOCTL_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_timer_info)) )
IOCTL( SNDRV_TIMER_IOCTL_PARAMS , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_timer_params)) )
IOCTL( SNDRV_TIMER_IOCTL_STATUS , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_timer_status)) )
IOCTL( SNDRV_TIMER_IOCTL_START , 0, TYPE_NULL )
IOCTL( SNDRV_TIMER_IOCTL_STOP , 0, TYPE_NULL )
IOCTL( SNDRV_TIMER_IOCTL_CONTINUE , 0, TYPE_NULL )
IOCTL( SNDRV_TIMER_IOCTL_PAUSE , 0, TYPE_NULL )
IOCTL( SNDRV_CTL_IOCTL_PVERSION , IOC_R, MK_PTR(TYPE_INT) )
IOCTL( SNDRV_CTL_IOCTL_CARD_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_card_info)) )
IOCTL( SNDRV_CTL_IOCTL_ELEM_LIST , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_elem_list)) )
IOCTL( SNDRV_CTL_IOCTL_ELEM_INFO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_elem_info)) )
IOCTL( SNDRV_CTL_IOCTL_ELEM_READ , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_elem_value)) )
IOCTL( SNDRV_CTL_IOCTL_ELEM_WRITE , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_elem_value)) )
IOCTL( SNDRV_CTL_IOCTL_ELEM_LOCK , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_elem_id)) )
IOCTL( SNDRV_CTL_IOCTL_ELEM_UNLOCK , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_elem_id)) )
IOCTL( SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS , IOC_RW, MK_PTR(TYPE_INT) )
IOCTL( SNDRV_CTL_IOCTL_ELEM_ADD , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_elem_info)) )
IOCTL( SNDRV_CTL_IOCTL_ELEM_REPLACE , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_elem_info)) )
IOCTL( SNDRV_CTL_IOCTL_ELEM_REMOVE , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_elem_id)) )
IOCTL( SNDRV_CTL_IOCTL_TLV_READ , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_tlv)) )
IOCTL( SNDRV_CTL_IOCTL_TLV_WRITE , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_tlv)) )
IOCTL( SNDRV_CTL_IOCTL_TLV_COMMAND , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_ctl_tlv)) )
IOCTL( SNDRV_CTL_IOCTL_HWDEP_NEXT_DEVICE , IOC_RW, MK_PTR(TYPE_INT) )
IOCTL( SNDRV_CTL_IOCTL_HWDEP_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_sndrv_hwdep_info)) )
IOCTL( SNDRV_CTL_IOCTL_PCM_NEXT_DEVICE , IOC_R, MK_PTR(TYPE_INT) )
IOCTL( SNDRV_CTL_IOCTL_PCM_INFO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_pcm_info)) )
IOCTL( SNDRV_CTL_IOCTL_PCM_PREFER_SUBDEVICE , IOC_W, MK_PTR(TYPE_INT) )
IOCTL( SNDRV_CTL_IOCTL_RAWMIDI_NEXT_DEVICE , IOC_RW, MK_PTR(TYPE_INT) )
IOCTL( SNDRV_CTL_IOCTL_RAWMIDI_INFO , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sndrv_rawmidi_info)) )
IOCTL( SNDRV_CTL_IOCTL_RAWMIDI_PREFER_SUBDEVICE , IOC_W, MK_PTR(TYPE_INT) )
IOCTL( SNDRV_CTL_IOCTL_POWER , IOC_RW, MK_PTR(TYPE_INT) )
IOCTL( SNDRV_CTL_IOCTL_POWER_STATE , IOC_R, MK_PTR(TYPE_INT) )
IOCTL( SNDRV_IOCTL_READV , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_xferv)) )
IOCTL( SNDRV_IOCTL_WRITEV , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sndrv_xferv)) )
IOCTL( SNDRV_EMU10K1_IOCTL_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_emu10k1_fx8010_info)) )
IOCTL( SNDRV_EMU10K1_IOCTL_CODE_POKE , IOC_W, MK_PTR(MK_STRUCT(STRUCT_emu10k1_fx8010_code)) )
IOCTL( SNDRV_EMU10K1_IOCTL_CODE_PEEK , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_emu10k1_fx8010_code)) )
IOCTL( SNDRV_EMU10K1_IOCTL_TRAM_SETUP , IOC_W, MK_PTR(TYPE_INT) )
IOCTL( SNDRV_EMU10K1_IOCTL_TRAM_POKE , IOC_W, MK_PTR(MK_STRUCT(STRUCT_emu10k1_fx8010_tram)) )
IOCTL( SNDRV_EMU10K1_IOCTL_TRAM_PEEK , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_emu10k1_fx8010_tram)) )
IOCTL( SNDRV_EMU10K1_IOCTL_PCM_POKE , IOC_W, MK_PTR(MK_STRUCT(STRUCT_emu10k1_fx8010_pcm)) )
IOCTL( SNDRV_EMU10K1_IOCTL_PCM_PEEK , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_emu10k1_fx8010_pcm)) )
IOCTL( SNDRV_EMU10K1_IOCTL_PVERSION , IOC_R, MK_PTR(TYPE_INT) )
IOCTL( SNDRV_EMU10K1_IOCTL_STOP , 0, TYPE_NULL )
IOCTL( SNDRV_EMU10K1_IOCTL_CONTINUE , 0, TYPE_NULL )
IOCTL( SNDRV_EMU10K1_IOCTL_ZERO_TRAM_COUNTER , 0, TYPE_NULL )
IOCTL( SNDRV_EMU10K1_IOCTL_SINGLE_STEP , IOC_W, MK_PTR(TYPE_INT) )
IOCTL( SNDRV_EMU10K1_IOCTL_DBG_READ , IOC_R, MK_PTR(TYPE_INT) )
IOCTL( SNDRV_HDSP_IOCTL_GET_PEAK_RMS , IOC_R, MK_PTR(MK_STRUCT(STRUCT_hdsp_peak_rms)) )
IOCTL( SNDRV_HDSP_IOCTL_GET_CONFIG_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_hdsp_config_info)) )
IOCTL( SNDRV_HDSP_IOCTL_UPLOAD_FIRMWARE , IOC_W, MK_PTR(MK_STRUCT(STRUCT_hdsp_firmware)) )
IOCTL( SNDRV_HDSP_IOCTL_GET_VERSION , IOC_R, MK_PTR(MK_STRUCT(STRUCT_hdsp_version)) )
IOCTL( SNDRV_HDSP_IOCTL_GET_MIXER , IOC_R, MK_PTR(MK_STRUCT(STRUCT_hdsp_mixer)) )
IOCTL( SNDRV_HDSP_IOCTL_GET_9632_AEB , IOC_R, MK_PTR(MK_STRUCT(STRUCT_hdsp_9632_aeb)) )
IOCTL( SNDRV_SB_CSP_IOCTL_INFO , IOC_R, MK_PTR(MK_STRUCT(STRUCT_snd_sb_csp_info)) )
#if _IOC_SIZEBITS > 13
IOCTL( SNDRV_SB_CSP_IOCTL_LOAD_CODE , IOC_W, MK_PTR(MK_STRUCT(STRUCT_snd_sb_csp_microcode)) )
#endif
IOCTL( SNDRV_SB_CSP_IOCTL_UNLOAD_CODE , 0, TYPE_NULL )
IOCTL( SNDRV_SB_CSP_IOCTL_START , IOC_W, MK_PTR(MK_STRUCT(STRUCT_snd_sb_csp_start)) )
IOCTL( SNDRV_SB_CSP_IOCTL_STOP , 0, TYPE_NULL )
IOCTL( SNDRV_SB_CSP_IOCTL_PAUSE , 0, TYPE_NULL )
IOCTL( SNDRV_SB_CSP_IOCTL_RESTART , 0, TYPE_NULL )
IOCTL( SND_SSCAPE_LOAD_BOOTB , IOC_RW, MK_PTR(MK_STRUCT(STRUCT_sscape_bootblock)) )
IOCTL( SND_SSCAPE_LOAD_MCODE , IOC_W, MK_PTR(MK_STRUCT(STRUCT_sscape_microcode)) )

File diff suppressed because it is too large Load Diff

View File

@@ -91,5 +91,6 @@ struct loop_info64 {
#define LOOP_SET_STATUS64 0x4C04
#define LOOP_GET_STATUS64 0x4C05
#define LOOP_CHANGE_FD 0x4C06
#define LOOP_BOGUS_CMD 0x4C82
#endif

View File

@@ -23,6 +23,7 @@
#include "qemu.h"
#include "qemu-common.h"
#include "tcg.h"
#include "translate-all.h"
//#define DEBUG_MMAP
@@ -34,6 +35,7 @@ void mmap_lock(void)
{
if (mmap_lock_count++ == 0) {
pthread_mutex_lock(&mmap_mutex);
tcg_lock();
}
}
@@ -41,6 +43,7 @@ void mmap_unlock(void)
{
if (--mmap_lock_count == 0) {
pthread_mutex_unlock(&mmap_mutex);
tcg_unlock();
}
}
@@ -358,6 +361,9 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size)
}
}
#define SNDRV_PCM_MMAP_OFFSET_STATUS 0x80000000
#define SNDRV_PCM_MMAP_OFFSET_CONTROL 0x81000000
/* NOTE: all the constants are the HOST ones */
abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
int flags, int fd, abi_ulong offset)
@@ -392,6 +398,17 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
}
#endif
/* Alsa tries to communcate with the kernel via mmap. This usually
* is a good idea when user- and kernelspace are running on the
* same architecture but does not work out when not. To make alsa
* not to use mmap, we can just have it fail on the mmap calls that
* would initiate this.
*/
if(offset == SNDRV_PCM_MMAP_OFFSET_STATUS || offset == SNDRV_PCM_MMAP_OFFSET_CONTROL) {
errno = EINVAL;
return -1;
}
if (offset & ~TARGET_PAGE_MASK) {
errno = EINVAL;
goto fail;

View File

@@ -176,10 +176,10 @@ abi_long memcpy_to_target(abi_ulong dest, const void *src,
void target_set_brk(abi_ulong new_brk);
abi_long do_brk(abi_ulong new_brk);
void syscall_init(void);
abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
abi_long arg2, abi_long arg3, abi_long arg4,
abi_long arg5, abi_long arg6, abi_long arg7,
abi_long arg8);
abi_long do_syscall(void *cpu_env, int num, abi_ulong arg1,
abi_ulong arg2, abi_ulong arg3, abi_ulong arg4,
abi_ulong arg5, abi_ulong arg6, abi_ulong arg7,
abi_ulong arg8);
void gemu_log(const char *fmt, ...) GCC_FMT_ATTR(1, 2);
extern THREAD CPUState *thread_cpu;
void cpu_loop(CPUArchState *env);

View File

@@ -443,6 +443,10 @@ static void QEMU_NORETURN force_sig(int target_sig)
trace_user_force_sig(env, target_sig, host_sig);
gdb_signalled(env, target_sig);
if (target_sig == 6) {
goto no_core;
}
/* dump core if supported by target binary format */
if (core_dump_signal(target_sig) && (ts->bprm->core_dump != NULL)) {
stop_all_tasks();
@@ -460,6 +464,8 @@ static void QEMU_NORETURN force_sig(int target_sig)
target_sig, strsignal(host_sig), "core dumped" );
}
no_core:
/* The proper exit code for dying from an uncaught signal is
* -<signal>. The kernel doesn't allow exit() or _exit() to pass
* a negative value. To get the proper exit code we need to

View File

@@ -3494,6 +3494,11 @@ static abi_long do_ioctl_fs_ioc_fiemap(const IOCTLEntry *ie, uint8_t *buf_temp,
uint32_t outbufsz;
int free_fm = 0;
if (1) {
/* XXX agraf: fiemap breaks for me */
return -TARGET_EINVAL;
}
assert(arg_type[0] == TYPE_PTR);
assert(ie->access == IOC_RW);
arg_type++;
@@ -3999,6 +4004,13 @@ static abi_long do_ioctl_kdsigaccept(const IOCTLEntry *ie, uint8_t *buf_temp,
return get_errno(ioctl(fd, ie->host_cmd, sig));
}
static abi_long do_ioctl_fail(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,
abi_long cmd, abi_long arg)
{
/* Fail silently */
return -EINVAL;
}
static IOCTLEntry ioctl_entries[] = {
#define IOCTL(cmd, access, ...) \
{ TARGET_ ## cmd, cmd, #cmd, access, 0, { __VA_ARGS__ } },
@@ -4022,7 +4034,12 @@ static abi_long do_ioctl(int fd, int cmd, abi_long arg)
ie = ioctl_entries;
for(;;) {
if (ie->target_cmd == 0) {
gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
int i;
gemu_log("Unsupported ioctl: cmd=0x%04lx (%x)\n", (unsigned long)cmd, (unsigned int)(cmd & (TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) >> TARGET_IOC_SIZESHIFT);
for (i = 0; ioctl_entries[i].target_cmd; i++) {
if ((ioctl_entries[i].target_cmd & ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) == (cmd & ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)))
gemu_log("%p\t->\t%s (%x)\n", (void *)(unsigned long)ioctl_entries[i].host_cmd, ioctl_entries[i].name, (ioctl_entries[i].target_cmd & (TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) >> TARGET_IOC_SIZESHIFT);
}
return -TARGET_ENOSYS;
}
if (ie->target_cmd == cmd)
@@ -4050,6 +4067,11 @@ static abi_long do_ioctl(int fd, int cmd, abi_long arg)
arg_type++;
target_size = thunk_type_size(arg_type, 0);
switch(ie->access) {
/* FIXME: actually the direction given in the ioctl should be
* correct so we can assume the communication is uni-directional.
* The alsa developers did not like this concept though and
* declared ioctls IOC_R and IOC_W even though they were IOC_RW.*/
/*
case IOC_R:
ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
if (!is_error(ret)) {
@@ -4068,6 +4090,7 @@ static abi_long do_ioctl(int fd, int cmd, abi_long arg)
unlock_user(argptr, arg, 0);
ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
break;
*/
default:
case IOC_RW:
argptr = lock_user(VERIFY_READ, arg, target_size, 1);
@@ -4686,6 +4709,15 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
if (nptl_flags & CLONE_SETTLS)
cpu_set_tls (new_env, newtls);
/* agraf: Pin ourselves to a single CPU when running multi-threaded.
This turned out to improve stability for me. */
{
cpu_set_t mask;
CPU_ZERO(&mask);
CPU_SET(0, &mask);
sched_setaffinity(0, sizeof(mask), &mask);
}
/* Grab a mutex so that thread setup appears atomic. */
pthread_mutex_lock(&clone_lock);
@@ -5670,6 +5702,25 @@ static int open_self_stat(void *cpu_env, int fd)
return 0;
}
static int open_cpuinfo(void *cpu_env, int fd)
{
dprintf(fd,
"Processor : ARMv7 Processor rev 5 (v7l)\n"
"BogoMIPS : 799.53\n"
"Features : swp half thumb fastmult vfp edsp thumbee neon vfpv3\n"
"CPU implementer : 0x41\n"
"CPU architecture: 7\n"
"CPU variant : 0x2\n"
"CPU part : 0xc08\n"
"CPU revision : 5\n"
"\n"
"Hardware : Genesi Efika MX (Smarttop)\n"
"Revision : 51030\n"
"Serial : 0000000000000000\n");
return 0;
}
static int open_self_auxv(void *cpu_env, int fd)
{
CPUState *cpu = ENV_GET_CPU((CPUArchState *)cpu_env);
@@ -5784,6 +5835,7 @@ static int do_openat(void *cpu_env, int dirfd, const char *pathname, int flags,
#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
{ "/proc/net/route", open_net_route, is_proc },
#endif
{ "cpuinfo", open_cpuinfo, is_proc_myself },
{ NULL, NULL, NULL }
};
@@ -5850,10 +5902,10 @@ static target_timer_t get_timer_id(abi_long arg)
/* do_syscall() should always have a single exit point at the end so
that actions, such as logging of syscall results, can be performed.
All errnos that do_syscall() returns must be -TARGET_<errcode>. */
abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
abi_long arg2, abi_long arg3, abi_long arg4,
abi_long arg5, abi_long arg6, abi_long arg7,
abi_long arg8)
abi_long do_syscall(void *cpu_env, int num, abi_ulong arg1,
abi_ulong arg2, abi_ulong arg3, abi_ulong arg4,
abi_ulong arg5, abi_ulong arg6, abi_ulong arg7,
abi_ulong arg8)
{
CPUState *cpu = ENV_GET_CPU(cpu_env);
abi_long ret;
@@ -6181,9 +6233,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
case TARGET_NR_oldstat:
goto unimplemented;
#endif
case TARGET_NR_lseek:
ret = get_errno(lseek(arg1, arg2, arg3));
case TARGET_NR_lseek: {
off_t off = arg2;
if (arg3 != SEEK_SET) {
off = (abi_long)arg2;
}
ret = get_errno(lseek(arg1, off, arg3));
break;
}
#if defined(TARGET_NR_getxpid) && defined(TARGET_ALPHA)
/* Alpha specific */
case TARGET_NR_getxpid:
@@ -6985,6 +7042,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
case TARGET_NR_gettimeofday:
{
struct timeval tv;
if(copy_from_user_timeval(&tv, arg1))
goto efault;
ret = get_errno(gettimeofday(&tv, NULL));
if (!is_error(ret)) {
if (copy_to_user_timeval(arg1, &tv))

View File

@@ -956,6 +956,12 @@ struct target_pollfd {
#define TARGET_BLKGETSIZE64 TARGET_IOR(0x12,114,abi_ulong)
/* return device size in bytes
(u64 *arg) */
#define TARGET_BLKDISCARD TARGET_IO(0x12,119)
#define TARGET_BLKIOMIN TARGET_IO(0x12,120)
#define TARGET_BLKIOOPT TARGET_IO(0x12,121)
#define TARGET_BLKALIGNOFF TARGET_IO(0x12,122)
#define TARGET_BLKPBSZGET TARGET_IO(0x12,123)
#define TARGET_BLKDISCARDZEROES TARGET_IO(0x12,124)
#define TARGET_FIBMAP TARGET_IO(0x00,1) /* bmap access */
#define TARGET_FIGETBSZ TARGET_IO(0x00,2) /* get the block size used for bmap */
#define TARGET_FS_IOC_FIEMAP TARGET_IOWR('f',11,struct fiemap)
@@ -1087,6 +1093,7 @@ struct target_pollfd {
#define TARGET_LOOP_SET_STATUS64 0x4C04
#define TARGET_LOOP_GET_STATUS64 0x4C05
#define TARGET_LOOP_CHANGE_FD 0x4C06
#define TARGET_LOOP_BOGUS_CMD 0x4C82
/* fb ioctls */
#define TARGET_FBIOGET_VSCREENINFO 0x4600
@@ -2456,6 +2463,9 @@ struct target_f_owner_ex {
#define TARGET_MTIOCGET TARGET_IOR('m', 2, struct mtget)
#define TARGET_MTIOCPOS TARGET_IOR('m', 3, struct mtpos)
#define TARGET_FS_IOC_GETFLAGS TARGET_IORU('f', 1)
#define TARGET_FS_IOC_SETFLAGS TARGET_IOWU('f', 2)
struct target_sysinfo {
abi_long uptime; /* Seconds since boot */
abi_ulong loads[3]; /* 1, 5, and 15 minute load averages */
@@ -2545,6 +2555,8 @@ struct target_ucred {
uint32_t gid;
};
#include "ioctls_alsa_structs.h"
#endif
typedef int32_t target_timer_t;

View File

@@ -71,6 +71,9 @@ STRUCT(kbentry,
STRUCT(kbsentry,
TYPE_CHAR, MK_ARRAY(TYPE_CHAR, 512))
STRUCT(blkdiscard,
MK_ARRAY(TYPE_LONGLONG, 2))
STRUCT(audio_buf_info,
TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT)
@@ -83,6 +86,11 @@ STRUCT(buffmem_desc,
STRUCT(mixer_info,
MK_ARRAY(TYPE_CHAR, 16), MK_ARRAY(TYPE_CHAR, 32), TYPE_INT, MK_ARRAY(TYPE_INT, 10))
/* FIXME: including these on x86 / x86_64 breaks qemu-i386 */
#ifdef __powerpc__
#include "syscall_types_alsa.h"
#endif
/* loop device ioctls */
STRUCT(loop_info,
TYPE_INT, /* lo_number */

File diff suppressed because it is too large Load Diff

View File

@@ -15,8 +15,6 @@
#include "qemu/osdep.h"
#include <glib.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/un.h>
@@ -111,7 +109,12 @@ static int parse_acl_file(const char *filename, ACLList *acl_list)
*argend = 0;
if (strcmp(cmd, "deny") == 0) {
acl_rule = g_malloc(sizeof(*acl_rule));
acl_rule = calloc(1, sizeof(*acl_rule));
if (!acl_rule) {
fclose(f);
errno = ENOMEM;
return -1;
}
if (strcmp(arg, "all") == 0) {
acl_rule->type = ACL_DENY_ALL;
} else {
@@ -120,7 +123,12 @@ static int parse_acl_file(const char *filename, ACLList *acl_list)
}
QSIMPLEQ_INSERT_TAIL(acl_list, acl_rule, entry);
} else if (strcmp(cmd, "allow") == 0) {
acl_rule = g_malloc(sizeof(*acl_rule));
acl_rule = calloc(1, sizeof(*acl_rule));
if (!acl_rule) {
fclose(f);
errno = ENOMEM;
return -1;
}
if (strcmp(arg, "all") == 0) {
acl_rule->type = ACL_ALLOW_ALL;
} else {
@@ -414,6 +422,17 @@ int main(int argc, char **argv)
goto cleanup;
}
#ifndef CONFIG_LIBCAP
/* avoid sending the fd as root user if running suid to not fool
* peer credentials to daemons that dont expect that
*/
if (setuid(getuid()) < 0) {
fprintf(stderr, "Failed to drop privileges.\n");
ret = EXIT_FAILURE;
goto cleanup;
}
#endif
/* write fd to the domain socket */
if (send_fd(unixfd, fd) == -1) {
fprintf(stderr, "failed to write fd to unix socket: %s\n",
@@ -435,7 +454,7 @@ cleanup:
}
while ((acl_rule = QSIMPLEQ_FIRST(&acl_list)) != NULL) {
QSIMPLEQ_REMOVE_HEAD(&acl_list, entry);
g_free(acl_rule);
free(acl_rule);
}
return ret;

View File

@@ -512,6 +512,9 @@ typedef struct {
IOEventHandler *chr_event[MAX_MUX];
void *ext_opaque[MAX_MUX];
CharDriverState *drv;
#if defined(TARGET_S390X)
QEMUTimer *accept_timer;
#endif
int focus;
int mux_cnt;
int term_got_escape;
@@ -671,6 +674,15 @@ static void mux_chr_accept_input(CharDriverState *chr)
d->chr_read[m](d->ext_opaque[m],
&d->buffer[m][d->cons[m]++ & MUX_BUFFER_MASK], 1);
}
#if defined(TARGET_S390X)
/* We're still not able to sync producer and consumer, so let's wait a bit
and try again by then. */
if (d->prod[m] != d->cons[m]) {
qemu_mod_timer(d->accept_timer, qemu_get_clock_ns(vm_clock)
+ (int64_t)100000);
}
#endif
}
static int mux_chr_can_read(void *opaque)
@@ -812,6 +824,10 @@ static CharDriverState *qemu_chr_open_mux(const char *id,
chr->opaque = d;
d->drv = drv;
d->focus = -1;
#if defined(TARGET_S390X)
d->accept_timer = qemu_new_timer_ns(vm_clock,
(QEMUTimerCB*)mux_chr_accept_input, chr);
#endif
chr->chr_write = mux_chr_write;
chr->chr_update_read_handler = mux_chr_update_read_handler;
chr->chr_accept_input = mux_chr_accept_input;

View File

@@ -2027,6 +2027,13 @@ static int img_convert(int argc, char **argv)
}
}
if (qemu_opt_get_bool(opts, BLOCK_OPT_SCSI, false)
&& strcmp(drv->format_name, "vmdk")) {
error_report("SCSI devices not supported for this file format");
ret = -1;
goto out;
}
if (!skip_create) {
/* Create the new image */
ret = bdrv_create(drv, out_filename, opts, &local_err);

View File

@@ -1410,6 +1410,14 @@ everybody else. 'ignore' completely ignores the shared flag and
allows everybody connect unconditionally. Doesn't conform to the rfb
spec but is traditional QEMU behavior.
@item key-delay-ms
Set keyboard delay, for key down and key up events, in milliseconds.
Default is 1. Keyboards are low-bandwidth devices, so this slowdown
can help the device and guest to keep up and not lose events in case
events are arriving in bulk. Possible causes for the latter are flaky
network connections, or scripts for automated testing.
@end table
ETEXI
@@ -3102,6 +3110,16 @@ Store the QEMU process PID in @var{file}. It is useful if you launch QEMU
from a script.
ETEXI
DEF("nooutgoing", HAS_ARG, QEMU_OPTION_nooutgoing, \
"-nooutgoing <IP>\n" \
" incoming traffic only from IP, no outgoing\n", \
QEMU_ARCH_ALL)
STEXI
@item -nooutgoing
Forbid userspace networking to make outgoing connections. Only accept incoming
connections from ip address IP.
ETEXI
DEF("singlestep", 0, QEMU_OPTION_singlestep, \
"-singlestep always run in singlestep mode\n", QEMU_ARCH_ALL)
STEXI

View File

@@ -27,46 +27,49 @@ case "$cpu" in
armv[4-9]*)
cpu="arm"
;;
sparc*)
cpu="sparc"
;;
esac
# register the interpreter for each cpu except for the native one
if [ $cpu != "i386" ] ; then
echo ':i386:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-i386:' > /proc/sys/fs/binfmt_misc/register
echo ':i486:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x06\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-i386:' > /proc/sys/fs/binfmt_misc/register
echo ':i386:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-i386-binfmt:P' > /proc/sys/fs/binfmt_misc/register
echo ':i486:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x06\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-i386-binfmt:P' > /proc/sys/fs/binfmt_misc/register
fi
if [ $cpu != "alpha" ] ; then
echo ':alpha:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x26\x90:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-alpha:' > /proc/sys/fs/binfmt_misc/register
echo ':alpha:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x26\x90:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-alpha-binfmt:P' > /proc/sys/fs/binfmt_misc/register
fi
if [ $cpu != "arm" ] ; then
echo ':arm:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-arm:' > /proc/sys/fs/binfmt_misc/register
echo ':armeb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-armeb:' > /proc/sys/fs/binfmt_misc/register
echo ':arm:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-arm-binfmt:P' > /proc/sys/fs/binfmt_misc/register
echo ':armeb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-armeb-binfmt:P' > /proc/sys/fs/binfmt_misc/register
fi
if [ $cpu != "aarch64" ] ; then
echo ':aarch64:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-aarch64:' > /proc/sys/fs/binfmt_misc/register
echo ':aarch64:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-aarch64-binfmt:P' > /proc/sys/fs/binfmt_misc/register
fi
if [ $cpu != "sparc" ] ; then
echo ':sparc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-sparc:' > /proc/sys/fs/binfmt_misc/register
echo ':sparc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-sparc-binfmt:P' > /proc/sys/fs/binfmt_misc/register
fi
if [ $cpu != "ppc" ] ; then
echo ':ppc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-ppc:' > /proc/sys/fs/binfmt_misc/register
echo ':ppc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-ppc-binfmt:P' > /proc/sys/fs/binfmt_misc/register
fi
if [ $cpu != "m68k" ] ; then
echo 'Please check cpu value and header information for m68k!'
echo ':m68k:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x04:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-m68k:' > /proc/sys/fs/binfmt_misc/register
echo ':m68k:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x04:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-m68k-binfmt:P' > /proc/sys/fs/binfmt_misc/register
fi
if [ $cpu != "mips" ] ; then
# FIXME: We could use the other endianness on a MIPS host.
echo ':mips:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-mips:' > /proc/sys/fs/binfmt_misc/register
echo ':mipsel:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-mipsel:' > /proc/sys/fs/binfmt_misc/register
echo ':mipsn32:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-mipsn32:' > /proc/sys/fs/binfmt_misc/register
echo ':mipsn32el:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-mipsn32el:' > /proc/sys/fs/binfmt_misc/register
echo ':mips64:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-mips64:' > /proc/sys/fs/binfmt_misc/register
echo ':mips64el:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-mips64el:' > /proc/sys/fs/binfmt_misc/register
echo ':mips:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-mips-binfmt:P' > /proc/sys/fs/binfmt_misc/register
echo ':mipsel:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-mipsel-binfmt:P' > /proc/sys/fs/binfmt_misc/register
echo ':mipsn32:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-mipsn32-binfmt:P' > /proc/sys/fs/binfmt_misc/register
echo ':mipsn32el:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-mipsn32el-binfmt:P' > /proc/sys/fs/binfmt_misc/register
echo ':mips64:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-mips64-binfmt:P' > /proc/sys/fs/binfmt_misc/register
echo ':mips64el:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-mips64el-binfmt:P' > /proc/sys/fs/binfmt_misc/register
fi
if [ $cpu != "sh" ] ; then
echo ':sh4:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a\x00:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-sh4:' > /proc/sys/fs/binfmt_misc/register
echo ':sh4eb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-sh4eb:' > /proc/sys/fs/binfmt_misc/register
echo ':sh4:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a\x00:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-sh4-binfmt:P' > /proc/sys/fs/binfmt_misc/register
echo ':sh4eb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-sh4eb-binfmt:P' > /proc/sys/fs/binfmt_misc/register
fi
if [ $cpu != "s390x" ] ; then
echo ':s390x:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x16:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-s390x:' > /proc/sys/fs/binfmt_misc/register
echo ':s390x:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x16:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-s390x-binfmt:P' > /proc/sys/fs/binfmt_misc/register
fi

View File

@@ -608,6 +608,8 @@ sorecvfrom(struct socket *so)
} /* if ping packet */
}
extern int slirp_nooutgoing;
/*
* sendto() a socket
*/
@@ -625,6 +627,12 @@ sosendto(struct socket *so, struct mbuf *m)
DEBUG_CALL(" sendto()ing)");
sotranslate_out(so, &addr);
/* Only allow DNS requests */
if (slirp_nooutgoing && ntohs(((struct sockaddr_in *)&addr)->sin_port) != 53) {
errno = EHOSTUNREACH;
return -1;
}
/* Don't care what port we get */
ret = sendto(so->s, m->m_data, m->m_len, 0,
(struct sockaddr *)&addr, sockaddr_size(&addr));

View File

@@ -391,6 +391,8 @@ tcp_sockclosed(struct tcpcb *tp)
* nonblocking. Connect returns after the SYN is sent, and does
* not wait for ACK+SYN.
*/
extern int slirp_nooutgoing;
int tcp_fconnect(struct socket *so, unsigned short af)
{
int ret=0;
@@ -398,6 +400,11 @@ int tcp_fconnect(struct socket *so, unsigned short af)
DEBUG_CALL("tcp_fconnect");
DEBUG_ARG("so = %p", so);
if (slirp_nooutgoing) {
errno = EHOSTUNREACH;
return -1;
}
ret = so->s = qemu_socket(af, SOCK_STREAM, 0);
if (ret >= 0) {
int opt, s=so->s;
@@ -478,6 +485,11 @@ void tcp_connect(struct socket *inso)
tcp_close(sototcpcb(so)); /* This will sofree() as well */
return;
}
if (slirp_nooutgoing && ((struct sockaddr_in *)&addr)->sin_addr.s_addr != slirp_nooutgoing) {
tcp_close(sototcpcb(so)); /* This will sofree() as well */
closesocket(s);
return;
}
qemu_set_nonblock(s);
socket_set_fast_reuse(s);
opt = 1;

View File

@@ -34,6 +34,8 @@
#include "qemu/cutils.h"
#include "qemu/host-utils.h"
#include "qemu/timer.h"
#include "config-host.h"
#include "qemu/thread.h"
/* Note: the long term plan is to reduce the dependencies on the QEMU
CPU definitions. Currently they are used for qemu_ld/st
@@ -114,6 +116,29 @@ static bool tcg_out_tb_finalize(TCGContext *s);
static TCGRegSet tcg_target_available_regs[2];
static TCGRegSet tcg_target_call_clobber_regs;
#ifdef CONFIG_USER_ONLY
static __thread int tcg_lock_count;
#endif
void tcg_lock(void)
{
#ifdef CONFIG_USER_ONLY
TCGContext *s = &tcg_ctx;
if (tcg_lock_count++ == 0) {
qemu_mutex_lock(&s->lock);
}
#endif
}
void tcg_unlock(void)
{
#ifdef CONFIG_USER_ONLY
TCGContext *s = &tcg_ctx;
if (--tcg_lock_count == 0) {
qemu_mutex_unlock(&s->lock);
}
#endif
}
#if TCG_TARGET_INSN_UNIT_SIZE == 1
static __attribute__((unused)) inline void tcg_out8(TCGContext *s, uint8_t v)
{
@@ -326,7 +351,8 @@ void tcg_context_init(TCGContext *s)
memset(s, 0, sizeof(*s));
s->nb_globals = 0;
qemu_mutex_init(&s->lock);
/* Count total number of arguments and allocate the corresponding
space */
total_args = 0;
@@ -2353,6 +2379,7 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
qemu_log("\n");
}
#endif
tcg_lock();
#ifdef CONFIG_PROFILER
s->opt_time -= profile_getclock();
@@ -2457,6 +2484,7 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
the buffer completely. Thus we can test for overflow after
generating code without having to check during generation. */
if (unlikely((void *)s->code_ptr > s->code_gen_highwater)) {
tcg_unlock();
return -1;
}
}
@@ -2470,6 +2498,7 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
/* flush instruction cache */
flush_icache_range((uintptr_t)s->code_buf, (uintptr_t)s->code_ptr);
tcg_unlock();
return tcg_current_code_size(s);
}

View File

@@ -27,6 +27,7 @@
#include "qemu-common.h"
#include "qemu/bitops.h"
#include "qemu/thread.h"
#include "tcg-target.h"
#define CPU_TEMP_BUF_NLONGS 128
@@ -591,6 +592,8 @@ struct TCGContext {
uint16_t gen_insn_end_off[TCG_MAX_INSNS];
target_ulong gen_insn_data[TCG_MAX_INSNS][TARGET_INSN_START_WORDS];
QemuMutex lock;
};
extern TCGContext tcg_ctx;
@@ -798,6 +801,9 @@ void tcg_gen_callN(TCGContext *s, void *func,
void tcg_op_remove(TCGContext *s, TCGOp *op);
void tcg_optimize(TCGContext *s);
extern void tcg_lock(void);
extern void tcg_unlock(void);
/* only used for debugging purposes */
void tcg_dump_ops(TCGContext *s);

View File

@@ -27,7 +27,7 @@
#include "qapi/qmp/qjson.h"
#define MAX_IRQ 256
#define SOCKET_TIMEOUT 5
#define SOCKET_TIMEOUT 15
QTestState *global_qtest;

View File

@@ -297,7 +297,12 @@ static void thread_pool_init_one(ThreadPool *pool, AioContext *ctx)
qemu_mutex_init(&pool->lock);
qemu_cond_init(&pool->worker_stopped);
qemu_sem_init(&pool->sem, 0);
pool->max_threads = 64;
if (sizeof(pool) == 4) {
/* 32bit systems run out of virtual memory quickly */
pool->max_threads = 4;
} else {
pool->max_threads = 64;
}
pool->new_thread_bh = aio_bh_new(ctx, spawn_thread_bh_fn, pool);
QLIST_INIT(&pool->head);

21
thunk.c
View File

@@ -37,6 +37,7 @@ static inline const argtype *thunk_type_next(const argtype *type_ptr)
case TYPE_CHAR:
case TYPE_SHORT:
case TYPE_INT:
case TYPE_INTBITFIELD:
case TYPE_LONGLONG:
case TYPE_ULONGLONG:
case TYPE_LONG:
@@ -139,6 +140,26 @@ const argtype *thunk_convert(void *dst, const void *src,
case TYPE_INT:
*(uint32_t *)dst = tswap32(*(uint32_t *)src);
break;
case TYPE_INTBITFIELD:
#if defined(TARGET_I386) && defined(__powerpc__)
/* powerpc uses the MSB, whereas i386 uses the LSB
* to store the first bit in a field */
{
unsigned char byte = *(uint8_t *)src;
*(uint8_t *)dst = ((byte >> 7) & 1)
| ((byte >> 5) & 2)
| ((byte >> 3) & 4)
| ((byte >> 1) & 8)
| ((byte << 1) & 16)
| ((byte << 3) & 32)
| ((byte << 5) & 64)
| ((byte << 7) & 128);
/* FIXME: implement for bitfields > 1 byte and other archs */
}
#else
*(uint32_t *)dst = tswap32(*(uint32_t *)src);
#endif
break;
case TYPE_LONGLONG:
case TYPE_ULONGLONG:
*(uint64_t *)dst = tswap64(*(uint64_t *)src);

View File

@@ -761,17 +761,21 @@ static TranslationBlock *tb_alloc(target_ulong pc)
{
TranslationBlock *tb;
tcg_lock();
if (tcg_ctx.tb_ctx.nb_tbs >= tcg_ctx.code_gen_max_blocks) {
tcg_unlock();
return NULL;
}
tb = &tcg_ctx.tb_ctx.tbs[tcg_ctx.tb_ctx.nb_tbs++];
tb->pc = pc;
tb->cflags = 0;
tcg_unlock();
return tb;
}
void tb_free(TranslationBlock *tb)
{
tcg_lock();
/* In practice this is mostly used for single use temporary TB
Ignore the hard cases and just back up if this TB happens to
be the last one generated. */
@@ -780,6 +784,7 @@ void tb_free(TranslationBlock *tb)
tcg_ctx.code_gen_ptr = tb->tc_ptr;
tcg_ctx.tb_ctx.nb_tbs--;
}
tcg_unlock();
}
static inline void invalidate_page_bitmap(PageDesc *p)
@@ -833,6 +838,7 @@ void tb_flush(CPUState *cpu)
((unsigned long)(tcg_ctx.code_gen_ptr - tcg_ctx.code_gen_buffer)) /
tcg_ctx.tb_ctx.nb_tbs : 0);
#endif
tcg_lock();
if ((unsigned long)(tcg_ctx.code_gen_ptr - tcg_ctx.code_gen_buffer)
> tcg_ctx.code_gen_buffer_size) {
cpu_abort(cpu, "Internal error: code buffer overflow\n");
@@ -850,6 +856,7 @@ void tb_flush(CPUState *cpu)
/* XXX: flush processor icache at this point if cache flush is
expensive */
tcg_ctx.tb_ctx.tb_flush_count++;
tcg_unlock();
}
#ifdef DEBUG_TB_CHECK
@@ -1208,8 +1215,10 @@ void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
int current_flags = 0;
#endif /* TARGET_HAS_PRECISE_SMC */
tcg_lock();
p = page_find(start >> TARGET_PAGE_BITS);
if (!p) {
tcg_unlock();
return;
}
#if defined(TARGET_HAS_PRECISE_SMC)
@@ -1294,6 +1303,7 @@ void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
cpu_resume_from_signal(cpu, NULL);
}
#endif
tcg_unlock();
}
/* len must be <= 8 and start must be a multiple of len */
@@ -1511,13 +1521,16 @@ static TranslationBlock *tb_find_pc(uintptr_t tc_ptr)
{
int m_min, m_max, m;
uintptr_t v;
TranslationBlock *tb;
TranslationBlock *tb, *r;
tcg_lock();
if (tcg_ctx.tb_ctx.nb_tbs <= 0) {
tcg_unlock();
return NULL;
}
if (tc_ptr < (uintptr_t)tcg_ctx.code_gen_buffer ||
tc_ptr >= (uintptr_t)tcg_ctx.code_gen_ptr) {
tcg_unlock();
return NULL;
}
/* binary search (cf Knuth) */
@@ -1528,6 +1541,7 @@ static TranslationBlock *tb_find_pc(uintptr_t tc_ptr)
tb = &tcg_ctx.tb_ctx.tbs[m];
v = (uintptr_t)tb->tc_ptr;
if (v == tc_ptr) {
tcg_unlock();
return tb;
} else if (tc_ptr < v) {
m_max = m - 1;
@@ -1535,7 +1549,9 @@ static TranslationBlock *tb_find_pc(uintptr_t tc_ptr)
m_min = m + 1;
}
}
return &tcg_ctx.tb_ctx.tbs[m_max];
r = &tcg_ctx.tb_ctx.tbs[m_max];
tcg_unlock();
return r;
}
#if !defined(CONFIG_USER_ONLY)

View File

@@ -868,7 +868,7 @@ static void console_putchar(QemuConsole *s, int ch)
} else {
if (s->nb_esc_params < MAX_ESC_PARAMS)
s->nb_esc_params++;
if (ch == ';')
if (ch == ';' || ch == '?')
break;
trace_console_putchar_csi(s->esc_params[0], s->esc_params[1],
ch, s->nb_esc_params);

View File

@@ -328,7 +328,23 @@ static void gd_update_geometry_hints(VirtualConsole *vc)
#if defined(CONFIG_VTE)
} else if (vc->type == GD_VC_VTE) {
VteTerminal *term = VTE_TERMINAL(vc->vte.terminal);
GtkBorder *ib;
GtkBorder padding = { 0 };
#if VTE_CHECK_VERSION(0, 37, 0)
gtk_style_context_get_padding(
gtk_widget_get_style_context(vc->vte.terminal),
gtk_widget_get_state_flags(vc->vte.terminal),
&padding);
#else
{
GtkBorder *ib = NULL;
gtk_widget_style_get(vc->vte.terminal, "inner-border", &ib, NULL);
if (ib) {
padding = *ib;
gtk_border_free(ib);
}
}
#endif
geo.width_inc = vte_terminal_get_char_width(term);
geo.height_inc = vte_terminal_get_char_height(term);
@@ -339,13 +355,11 @@ static void gd_update_geometry_hints(VirtualConsole *vc)
geo.min_width = geo.width_inc * VC_TERM_X_MIN;
geo.min_height = geo.height_inc * VC_TERM_Y_MIN;
mask |= GDK_HINT_MIN_SIZE;
gtk_widget_style_get(vc->vte.terminal, "inner-border", &ib, NULL);
if (ib) {
geo.base_width += ib->left + ib->right;
geo.base_height += ib->top + ib->bottom;
geo.min_width += ib->left + ib->right;
geo.min_height += ib->top + ib->bottom;
}
geo.base_width += padding.left + padding.right;
geo.base_height += padding.top + padding.bottom;
geo.min_width += padding.left + padding.right;
geo.min_height += padding.top + padding.bottom;
geo_widget = vc->vte.terminal;
#endif
}

View File

@@ -58,6 +58,8 @@ static const struct timeval VNC_REFRESH_LOSSY = { 2, 0 };
static QTAILQ_HEAD(, VncDisplay) vnc_displays =
QTAILQ_HEAD_INITIALIZER(vnc_displays);
static int allowed_connections = 0;
static int vnc_cursor_define(VncState *vs);
static void vnc_release_modifiers(VncState *vs);
@@ -1185,6 +1187,7 @@ static void vnc_disconnect_start(VncState *vs)
void vnc_disconnect_finish(VncState *vs)
{
int i;
static int num_disconnects = 0;
vnc_jobs_join(vs); /* Wait encoding jobs */
@@ -1235,6 +1238,13 @@ void vnc_disconnect_finish(VncState *vs)
object_unref(OBJECT(vs->sioc));
vs->sioc = NULL;
g_free(vs);
num_disconnects++;
if (allowed_connections > 0 && allowed_connections <= num_disconnects) {
VNC_DEBUG("Maximum number of disconnects (%d) reached:"
" Session terminating\n", allowed_connections);
exit(0);
}
}
ssize_t vnc_client_io_error(VncState *vs, ssize_t ret, Error **errp)
@@ -1629,6 +1639,7 @@ static void reset_keys(VncState *vs)
for(i = 0; i < 256; i++) {
if (vs->modifiers_state[i]) {
qemu_input_event_send_key_number(vs->vd->dcl.con, i, false);
qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
vs->modifiers_state[i] = 0;
}
}
@@ -1638,9 +1649,9 @@ static void press_key(VncState *vs, int keysym)
{
int keycode = keysym2scancode(vs->vd->kbd_layout, keysym) & SCANCODE_KEYMASK;
qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, true);
qemu_input_event_send_key_delay(0);
qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
qemu_input_event_send_key_delay(0);
qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
}
static int current_led_state(VncState *vs)
@@ -1792,6 +1803,7 @@ static void do_key_event(VncState *vs, int down, int keycode, int sym)
if (qemu_console_is_graphic(NULL)) {
qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, down);
qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
} else {
bool numlock = vs->modifiers_state[0x45];
bool control = (vs->modifiers_state[0x1d] ||
@@ -1913,6 +1925,7 @@ static void vnc_release_modifiers(VncState *vs)
continue;
}
qemu_input_event_send_key_number(vs->vd->dcl.con, keycode, false);
qemu_input_event_send_key_delay(vs->vd->key_delay_ms);
}
}
@@ -3200,6 +3213,39 @@ char *vnc_display_local_addr(const char *id)
return ret;
}
static void read_file_password(const char *id, const char *filename)
{
FILE *pfile = NULL;
char *passwd = NULL;
int start = 0, length = 0, rc = 0;
if (strlen(filename) == 0) {
printf("No file supplied\n");
return;
}
pfile = fopen(filename, "r");
if (pfile == NULL) {
printf("Could not read from %s\n", filename);
return;
}
start = ftell(pfile);
fseek(pfile, 0L, SEEK_END);
length = ftell(pfile);
fseek(pfile, 0L, start);
passwd = g_malloc(length + 1);
rc = fread(passwd, 1, length, pfile);
fclose(pfile);
if (rc == length && rc > 0) {
vnc_display_password(id, passwd);
}
g_free(passwd);
}
static QemuOptsList qemu_vnc_opts = {
.name = "vnc",
.head = QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts.head),
@@ -3230,6 +3276,9 @@ static QemuOptsList qemu_vnc_opts = {
},{
.name = "connections",
.type = QEMU_OPT_NUMBER,
},{
.name = "allowed-connections",
.type = QEMU_OPT_NUMBER,
},{
.name = "to",
.type = QEMU_OPT_NUMBER,
@@ -3242,12 +3291,18 @@ static QemuOptsList qemu_vnc_opts = {
},{
.name = "password",
.type = QEMU_OPT_BOOL,
},{
.name = "password-file",
.type = QEMU_OPT_STRING,
},{
.name = "reverse",
.type = QEMU_OPT_BOOL,
},{
.name = "lock-key-sync",
.type = QEMU_OPT_BOOL,
},{
.name = "key-delay-ms",
.type = QEMU_OPT_NUMBER,
},{
.name = "sasl",
.type = QEMU_OPT_BOOL,
@@ -3476,6 +3531,7 @@ void vnc_display_open(const char *id, Error **errp)
const char *share, *device_id;
QemuConsole *con;
bool password = false;
const char *password_file;
bool reverse = false;
const char *vnc;
char *h;
@@ -3486,6 +3542,7 @@ void vnc_display_open(const char *id, Error **errp)
#endif
int acl = 0;
int lock_key_sync = 1;
int key_delay_ms;
if (!vs) {
error_setg(errp, "VNC display not active");
@@ -3601,9 +3658,14 @@ void vnc_display_open(const char *id, Error **errp)
goto fail;
}
}
password_file = qemu_opt_get(opts, "password-file");
if (password_file) {
read_file_password(id, password_file);
}
reverse = qemu_opt_get_bool(opts, "reverse", false);
lock_key_sync = qemu_opt_get_bool(opts, "lock-key-sync", true);
key_delay_ms = qemu_opt_get_number(opts, "key-delay-ms", 1);
sasl = qemu_opt_get_bool(opts, "sasl", false);
#ifndef CONFIG_VNC_SASL
if (sasl) {
@@ -3689,6 +3751,7 @@ void vnc_display_open(const char *id, Error **errp)
vs->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
}
vs->connections_limit = qemu_opt_get_number(opts, "connections", 32);
allowed_connections = qemu_opt_get_number(opts, "allowed-connections", 0);
#ifdef CONFIG_VNC_JPEG
vs->lossy = qemu_opt_get_bool(opts, "lossy", false);
@@ -3735,6 +3798,7 @@ void vnc_display_open(const char *id, Error **errp)
}
#endif
vs->lock_key_sync = lock_key_sync;
vs->key_delay_ms = key_delay_ms;
device_id = qemu_opt_get(opts, "display");
if (device_id) {

View File

@@ -155,6 +155,7 @@ struct VncDisplay
DisplayChangeListener dcl;
kbd_layout_t *kbd_layout;
int lock_key_sync;
int key_delay_ms;
QemuMutex mutex;
QEMUCursor *cursor;

View File

@@ -94,6 +94,10 @@ static inline int handle_cpu_signal(uintptr_t pc, unsigned long address,
printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
pc, address, is_write, *(unsigned long *)old_set);
#endif
/* Maybe we're still holding the TB fiddling lock? */
tb_lock_reset();
/* XXX: locking issue */
if (is_write && h2g_valid(address)
&& page_unprotect(h2g(address), pc, puc)) {

9
vl.c
View File

@@ -162,6 +162,7 @@ int smp_threads = 1;
int acpi_enabled = 1;
int no_hpet = 0;
int fd_bootchk = 1;
int slirp_nooutgoing = 0;
static int no_reboot;
int no_shutdown = 0;
int cursor_hide = 1;
@@ -3386,6 +3387,14 @@ int main(int argc, char **argv, char **envp)
case QEMU_OPTION_singlestep:
singlestep = 1;
break;
case QEMU_OPTION_nooutgoing:
slirp_nooutgoing = inet_addr(optarg);
if (slirp_nooutgoing == INADDR_NONE) {
printf("Invalid address: %s.\nOnly addresses of the format "
"xxx.xxx.xxx.xxx are supported.\n", optarg);
exit(1);
}
break;
case QEMU_OPTION_S:
autostart = 0;
break;

View File

@@ -1305,9 +1305,7 @@ void xen_hvm_init(PCMachineState *pcms, MemoryRegion **ram_memory)
error_report("xen backend core setup failed");
goto err;
}
xen_be_register("console", &xen_console_ops);
xen_be_register("vkbd", &xen_kbdmouse_ops);
xen_be_register("qdisk", &xen_blkdev_ops);
xen_be_register_common();
xen_read_physmap(state);
return;