qemu-binfmt-conf: use qemu-ARCH-binfmt #7

Closed
andreas-schwab wants to merge 37 commits from opensuse-2.7 into opensuse-2.7
37 changed files with 4996 additions and 23 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
@@ -115,6 +119,8 @@ QEMU_CFLAGS+=-I$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR) \
obj-y += linux-user/
obj-y += gdbstub.o thunk.o user-exec.o
obj-binfmt-y += linux-user/
endif #CONFIG_LINUX_USER
#########################################################
@@ -163,7 +169,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 :=
@@ -200,6 +210,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

@@ -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;
s->hd = bdrv_open(filename, NULL, NULL, flags | BDRV_O_PROTOCOL, errp);
if (!s->hd) {
ret = -EINVAL;
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->file, 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->file, 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->file, GZ_XLEN, &tmp_short, 2) != 2)
goto fail;
headerLength += le16_to_cpu(tmp_short) + 2;
/* DictZip magic */
if (bdrv_pread(s->hd->file, 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->file, 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->file, GZ_CHUNKSIZE, &chunk_len16, 2) != 2)
goto fail;
s->chunk_len = le16_to_cpu(chunk_len16);
/* chunk count */
if (bdrv_pread(s->hd->file, 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->file, 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->file, 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->file, 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->file, rnd_offs, s->chunks, chunks_len) != chunks_len)
goto fail;
/* orig filename */
if (header_flags & GZ_FNAME) {
if (bdrv_pread(s->hd->file, 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->file, 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->file, 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->file, 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);

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;
s->hd = bdrv_open(filename, NULL, NULL, flags | BDRV_O_PROTOCOL, errp);
if (!s->hd) {
ret = -EINVAL;
qemu_opts_del(opts);
return ret;
}
/* Search the file for an image */
do {
/* tar header */
if (bdrv_pread(s->hd->file, 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->file, 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->file, 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->file, (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->file, 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);

29
configure vendored
View File

@@ -1545,7 +1545,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"
@@ -4049,6 +4049,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

2
exec.c
View File

@@ -1230,11 +1230,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

@@ -111,6 +111,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

@@ -37,6 +37,7 @@ typedef enum argtype {
TYPE_ARRAY,
TYPE_STRUCT,
TYPE_OLDDEVT,
TYPE_INTBITFIELD,
} argtype;
#define MK_PTR(type) TYPE_PTR, type
@@ -89,6 +90,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:
@@ -151,6 +153,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

@@ -6,3 +6,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

@@ -119,6 +119,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, IOC_R, MK_PTR(TYPE_INT))
IOCTL(SIOCGIFNAME, IOC_RW, MK_PTR(TYPE_INT))
@@ -348,6 +350,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)))

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

@@ -22,6 +22,7 @@
#include "qemu.h"
#include "qemu-common.h"
#include "tcg.h"
#include "translate-all.h"
//#define DEBUG_MMAP
@@ -33,6 +34,7 @@ void mmap_lock(void)
{
if (mmap_lock_count++ == 0) {
pthread_mutex_lock(&mmap_mutex);
tcg_lock();
}
}
@@ -40,6 +42,7 @@ void mmap_unlock(void)
{
if (--mmap_lock_count == 0) {
pthread_mutex_unlock(&mmap_mutex);
tcg_unlock();
}
}
@@ -357,6 +360,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)
@@ -391,6 +397,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

@@ -193,10 +193,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

@@ -526,6 +526,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();
@@ -543,6 +547,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

@@ -4651,6 +4651,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++;
@@ -5179,7 +5184,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)
@@ -5207,6 +5217,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(safe_ioctl(fd, ie->host_cmd, buf_temp));
if (!is_error(ret)) {
@@ -5225,6 +5240,7 @@ static abi_long do_ioctl(int fd, int cmd, abi_long arg)
unlock_user(argptr, arg, 0);
ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp));
break;
*/
default:
case IOC_RW:
argptr = lock_user(VERIFY_READ, arg, target_size, 1);
@@ -5844,6 +5860,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);
@@ -6967,6 +6992,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);
@@ -7081,6 +7125,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 }
};
@@ -7149,10 +7194,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;
@@ -7510,9 +7555,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:
@@ -8379,6 +8429,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

@@ -2502,6 +2502,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 */
@@ -2591,6 +2594,8 @@ struct target_ucred {
uint32_t gid;
};
#include "ioctls_alsa_structs.h"
typedef int32_t target_timer_t;
#define TARGET_SIGEV_MAX_SIZE 64

View File

@@ -83,6 +83,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

@@ -110,7 +110,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 {
@@ -119,7 +124,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 {
@@ -413,6 +423,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",
@@ -434,7 +455,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

@@ -510,6 +510,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;
@@ -669,6 +672,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)
@@ -817,6 +829,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_close = mux_chr_close;
chr->chr_write = mux_chr_write;
chr->chr_update_read_handler = mux_chr_update_read_handler;

View File

@@ -3132,6 +3132,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

@@ -201,7 +201,7 @@ qemu_check_systemd() {
}
qemu_generate_register() {
echo ":qemu-$cpu:M::$magic:$mask:$qemu:$FLAGS"
echo ":qemu-$cpu:M::$magic:$mask:$qemu:P$FLAGS"
}
qemu_register_interpreter() {
@@ -242,9 +242,9 @@ qemu_set_binfmts() {
continue
fi
qemu="$QEMU_PATH/qemu-$cpu"
qemu="$QEMU_PATH/qemu-$cpu-binfmt"
if [ "$cpu" = "i486" ] ; then
qemu="$QEMU_PATH/qemu-i386"
qemu="$QEMU_PATH/qemu-i386-binfmt"
fi
if [ "$host_family" != "$family" ] ; then
@@ -259,7 +259,7 @@ BINFMT_SET=qemu_register_interpreter
SYSTEMDDIR="/etc/binfmt.d"
DEBIANDIR="/usr/share/binfmts"
QEMU_PATH=/usr/local/bin
QEMU_PATH=/usr/bin
FLAGS=""
options=$(getopt -o ds:Q:e:hc: -l debian,systemd:,qemu-path:,exportdir:,help,credential: -- "$@")

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

@@ -33,6 +33,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
@@ -120,6 +122,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)
{
@@ -332,6 +357,7 @@ 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 */
@@ -2551,6 +2577,7 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
qemu_log("\n");
}
#endif
tcg_lock();
#ifdef CONFIG_PROFILER
s->opt_time -= profile_getclock();
@@ -2673,6 +2700,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;
}
}
@@ -2686,6 +2714,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

@@ -29,6 +29,7 @@
#include "cpu.h"
#include "exec/tb-context.h"
#include "qemu/bitops.h"
#include "qemu/thread.h"
#include "tcg-target.h"
/* XXX: make safe guess about sizes */
@@ -697,6 +698,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;
@@ -904,6 +907,9 @@ TCGOp *tcg_op_insert_after(TCGContext *s, TCGOp *op, TCGOpcode opc, int narg);
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

@@ -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

@@ -767,17 +767,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. */
@@ -786,6 +790,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)
@@ -841,6 +846,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");
@@ -859,6 +865,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
@@ -1317,8 +1324,10 @@ void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
uint32_t 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)
@@ -1389,6 +1398,7 @@ void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
cpu_loop_exit_noexc(cpu);
}
#endif
tcg_unlock();
}
#ifdef CONFIG_SOFTMMU
@@ -1506,13 +1516,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) */
@@ -1523,6 +1536,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;
@@ -1530,7 +1544,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

@@ -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);
@@ -1195,6 +1197,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 */
@@ -1245,6 +1248,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)
@@ -3243,6 +3253,39 @@ static void vnc_display_print_local_addr(VncDisplay *vs)
qapi_free_SocketAddress(addr);
}
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),
@@ -3273,6 +3316,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,
@@ -3285,6 +3331,9 @@ static QemuOptsList qemu_vnc_opts = {
},{
.name = "password",
.type = QEMU_OPT_BOOL,
},{
.name = "password-file",
.type = QEMU_OPT_STRING,
},{
.name = "reverse",
.type = QEMU_OPT_BOOL,
@@ -3522,6 +3571,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;
@@ -3650,6 +3700,10 @@ 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);
@@ -3739,6 +3793,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);

View File

@@ -65,6 +65,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)) {
switch (page_unprotect(h2g(address), pc)) {

9
vl.c
View File

@@ -160,6 +160,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;
@@ -3362,6 +3363,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;