Compare commits
72 Commits
pull-ui-20
...
opensuse-2
Author | SHA1 | Date | |
---|---|---|---|
|
bd4f41a27f | ||
|
f369059a4f | ||
|
cb184e87cf | ||
|
f774e0e5e6 | ||
|
424bd9dd9c | ||
|
5ac15a00c1 | ||
|
2d9d551729 | ||
|
3f442b0623 | ||
|
27db53c8bd | ||
|
ebc039becf | ||
|
6a847bb812 | ||
|
d1d06f7db5 | ||
|
536ae1665b | ||
|
07cbf6021a | ||
|
56fb083af9 | ||
|
818182d604 | ||
|
5525a02cb6 | ||
|
a31edb2865 | ||
|
52f9cd6fd4 | ||
|
65cef1a069 | ||
|
3b4bf7e1b3 | ||
|
0cfea2b4d6 | ||
|
e01538b755 | ||
|
bf1cd7a4b8 | ||
|
6afc220927 | ||
|
70f17e51a9 | ||
|
8e642bbb73 | ||
|
7b6b039ba5 | ||
|
992fa3653d | ||
|
be38f2a0ff | ||
|
87164237f3 | ||
|
54d95bf6b1 | ||
|
de2bd411b2 | ||
|
f29449e6c1 | ||
|
6fef5a1f40 | ||
|
a5f88d11e6 | ||
|
235fbffb3f | ||
|
101b933ef8 | ||
|
920c90f434 | ||
667601cdfb | |||
a420f344ce | |||
|
6163925a8a | ||
36996f68dc | |||
|
b05bd87923 | ||
|
1e4469088f | ||
|
69fae9cfe2 | ||
|
9a6dabcb75 | ||
|
1825b6ee2b | ||
|
68cabc26aa | ||
|
2be621021e | ||
|
047016003b | ||
|
b6dbfd4547 | ||
|
a4e7e274fa | ||
|
dae0d107e0 | ||
|
2f2838f6f1 | ||
|
725c9b6ff4 | ||
|
4338d0069c | ||
|
e69941d829 | ||
|
772c86a0d0 | ||
|
8af212a8fa | ||
|
21c1118213 | ||
|
34a749afcf | ||
|
74afa36996 | ||
|
fd1e321c4e | ||
|
380059e6c4 | ||
|
34dcc1febe | ||
|
e073096e40 | ||
|
9ef9e8d6c4 | ||
|
8a4092a66e | ||
|
beff0040fc | ||
|
e9b62c0a3f | ||
|
cf0874f4e2 |
@@ -920,6 +920,7 @@ M: Paolo Bonzini <pbonzini@redhat.com>
|
||||
S: Supported
|
||||
F: include/hw/scsi/*
|
||||
F: hw/scsi/*
|
||||
F: tests/scsi-disk-test.c
|
||||
F: tests/virtio-scsi-test.c
|
||||
T: git git://github.com/bonzini/qemu.git scsi-next
|
||||
|
||||
@@ -1361,6 +1362,7 @@ F: qom/
|
||||
X: qom/cpu.c
|
||||
F: tests/check-qom-interface.c
|
||||
F: tests/check-qom-proplist.c
|
||||
F: tests/check-qom-props.c
|
||||
F: tests/qom-test.c
|
||||
|
||||
QMP
|
||||
|
@@ -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
|
||||
|
||||
@@ -116,6 +120,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
|
||||
|
||||
#########################################################
|
||||
@@ -164,7 +170,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 :=
|
||||
@@ -201,6 +211,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)$@")
|
||||
|
||||
|
@@ -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 += backup.o
|
||||
block-obj-$(CONFIG_REPLICATION) += replication.o
|
||||
|
586
block/dictzip.c
Normal file
586
block/dictzip.c
Normal 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
379
block/tar.c
Normal 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);
|
5
configure
vendored
5
configure
vendored
@@ -1567,7 +1567,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"
|
||||
@@ -1928,6 +1928,9 @@ if test "$seccomp" != "no" ; then
|
||||
ppc|ppc64)
|
||||
libseccomp_minver="2.3.0"
|
||||
;;
|
||||
s390|s390x)
|
||||
libseccomp_minver="2.2.0"
|
||||
;;
|
||||
*)
|
||||
libseccomp_minver=""
|
||||
;;
|
||||
|
2
exec.c
2
exec.c
@@ -1240,11 +1240,13 @@ static void *file_ram_alloc(RAMBlock *block,
|
||||
int fd = -1;
|
||||
int64_t file_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);
|
||||
|
@@ -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>
|
||||
|
@@ -311,7 +311,7 @@ static const VMStateDescription vmstate_cpuhp_state = {
|
||||
static const VMStateDescription vmstate_acpi = {
|
||||
.name = "piix4_pm",
|
||||
.version_id = 3,
|
||||
.minimum_version_id = 3,
|
||||
.minimum_version_id = 2, /* qemu-kvm */
|
||||
.minimum_version_id_old = 1,
|
||||
.load_state_old = acpi_load_old,
|
||||
.post_load = vmstate_acpi_post_load,
|
||||
|
@@ -623,6 +623,24 @@ static void create_gic(VirtBoardInfo *vbi, qemu_irq *pic, int type,
|
||||
} else if (type == 2) {
|
||||
create_v2m(vbi, pic);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_KVM
|
||||
if (kvm_enabled() && !kvm_irqchip_in_kernel()) {
|
||||
for (i = 0; i < smp_cpus; i++) {
|
||||
CPUState *cs = qemu_get_cpu(i);
|
||||
int ret;
|
||||
|
||||
ret = kvm_vcpu_enable_cap(cs, KVM_CAP_ARM_TIMER, 0,
|
||||
KVM_ARM_TIMER_VTIMER);
|
||||
|
||||
if (ret) {
|
||||
error_report("KVM with user space irqchip only works when the "
|
||||
"host kernel supports KVM_CAP_ARM_TIMER");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void create_uart(const VirtBoardInfo *vbi, qemu_irq *pic, int uart,
|
||||
|
@@ -1387,6 +1387,16 @@ static void ac97_realize(PCIDevice *dev, Error **errp)
|
||||
ac97_on_reset (&s->dev.qdev);
|
||||
}
|
||||
|
||||
static void ac97_exit(PCIDevice *dev)
|
||||
{
|
||||
AC97LinkState *s = DO_UPCAST(AC97LinkState, dev, dev);
|
||||
|
||||
AUD_close_in(&s->card, s->voice_pi);
|
||||
AUD_close_out(&s->card, s->voice_po);
|
||||
AUD_close_in(&s->card, s->voice_mc);
|
||||
AUD_remove_card(&s->card);
|
||||
}
|
||||
|
||||
static int ac97_init (PCIBus *bus)
|
||||
{
|
||||
pci_create_simple (bus, -1, "AC97");
|
||||
@@ -1404,6 +1414,7 @@ static void ac97_class_init (ObjectClass *klass, void *data)
|
||||
PCIDeviceClass *k = PCI_DEVICE_CLASS (klass);
|
||||
|
||||
k->realize = ac97_realize;
|
||||
k->exit = ac97_exit;
|
||||
k->vendor_id = PCI_VENDOR_ID_INTEL;
|
||||
k->device_id = PCI_DEVICE_ID_INTEL_82801AA_5;
|
||||
k->revision = 0x01;
|
||||
|
@@ -1041,6 +1041,19 @@ static void es1370_realize(PCIDevice *dev, Error **errp)
|
||||
es1370_reset (s);
|
||||
}
|
||||
|
||||
static void es1370_exit(PCIDevice *dev)
|
||||
{
|
||||
ES1370State *s = ES1370(dev);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 2; ++i) {
|
||||
AUD_close_out(&s->card, s->dac_voice[i]);
|
||||
}
|
||||
|
||||
AUD_close_in(&s->card, s->adc_voice);
|
||||
AUD_remove_card(&s->card);
|
||||
}
|
||||
|
||||
static int es1370_init (PCIBus *bus)
|
||||
{
|
||||
pci_create_simple (bus, -1, TYPE_ES1370);
|
||||
@@ -1053,6 +1066,7 @@ static void es1370_class_init (ObjectClass *klass, void *data)
|
||||
PCIDeviceClass *k = PCI_DEVICE_CLASS (klass);
|
||||
|
||||
k->realize = es1370_realize;
|
||||
k->exit = es1370_exit;
|
||||
k->vendor_id = PCI_VENDOR_ID_ENSONIQ;
|
||||
k->device_id = PCI_DEVICE_ID_ENSONIQ_ES1370;
|
||||
k->class_id = PCI_CLASS_MULTIMEDIA_AUDIO;
|
||||
|
@@ -111,6 +111,7 @@ struct XenBlkDev {
|
||||
int requests_inflight;
|
||||
int requests_finished;
|
||||
|
||||
gboolean cache_unsafe;
|
||||
/* Persistent grants extension */
|
||||
gboolean feature_discard;
|
||||
gboolean feature_persistent;
|
||||
@@ -960,6 +961,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);
|
||||
@@ -1031,6 +1042,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;
|
||||
@@ -1073,6 +1085,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);
|
||||
|
@@ -55,6 +55,7 @@
|
||||
#include "exec/address-spaces.h"
|
||||
#include "hw/boards.h"
|
||||
#include "qemu/cutils.h"
|
||||
#include "hw/xen/xen.h"
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
@@ -858,7 +859,10 @@ static void *rom_set_mr(Rom *rom, Object *owner, const char *name)
|
||||
void *data;
|
||||
|
||||
rom->mr = g_malloc(sizeof(*rom->mr));
|
||||
memory_region_init_resizeable_ram(rom->mr, owner, name,
|
||||
if (xen_enabled())
|
||||
memory_region_init_ram(rom->mr, owner, name, rom->datasize, &error_fatal);
|
||||
else
|
||||
memory_region_init_resizeable_ram(rom->mr, owner, name,
|
||||
rom->datasize, rom->romsize,
|
||||
fw_cfg_resized,
|
||||
&error_fatal);
|
||||
|
@@ -277,10 +277,9 @@ static bool blit_region_is_unsafe(struct CirrusVGAState *s,
|
||||
}
|
||||
if (pitch < 0) {
|
||||
int64_t min = addr
|
||||
+ ((int64_t)s->cirrus_blt_height-1) * pitch;
|
||||
int32_t max = addr
|
||||
+ s->cirrus_blt_width;
|
||||
if (min < 0 || max > s->vga.vram_size) {
|
||||
+ ((int64_t)s->cirrus_blt_height - 1) * pitch
|
||||
- s->cirrus_blt_width;
|
||||
if (min < -1 || addr >= s->vga.vram_size) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
@@ -294,7 +293,7 @@ static bool blit_region_is_unsafe(struct CirrusVGAState *s,
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool blit_is_unsafe(struct CirrusVGAState *s)
|
||||
static bool blit_is_unsafe(struct CirrusVGAState *s, bool dst_only)
|
||||
{
|
||||
/* should be the case, see cirrus_bitblt_start */
|
||||
assert(s->cirrus_blt_width > 0);
|
||||
@@ -305,11 +304,15 @@ static bool blit_is_unsafe(struct CirrusVGAState *s)
|
||||
}
|
||||
|
||||
if (blit_region_is_unsafe(s, s->cirrus_blt_dstpitch,
|
||||
s->cirrus_blt_dstaddr & s->cirrus_addr_mask)) {
|
||||
s->cirrus_blt_dstaddr)) {
|
||||
return true;
|
||||
}
|
||||
if (dst_only) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (blit_region_is_unsafe(s, s->cirrus_blt_srcpitch,
|
||||
s->cirrus_blt_srcaddr & s->cirrus_addr_mask)) {
|
||||
s->cirrus_blt_srcaddr)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -658,22 +661,52 @@ static void cirrus_invalidate_region(CirrusVGAState * s, int off_begin,
|
||||
int off_cur;
|
||||
int off_cur_end;
|
||||
|
||||
if (off_pitch < 0) {
|
||||
off_begin -= bytesperline - 1;
|
||||
}
|
||||
|
||||
for (y = 0; y < lines; y++) {
|
||||
off_cur = off_begin;
|
||||
off_cur_end = (off_cur + bytesperline) & s->cirrus_addr_mask;
|
||||
assert(off_cur_end >= off_cur);
|
||||
memory_region_set_dirty(&s->vga.vram, off_cur, off_cur_end - off_cur);
|
||||
off_begin += off_pitch;
|
||||
}
|
||||
}
|
||||
|
||||
static int cirrus_bitblt_common_patterncopy(CirrusVGAState * s,
|
||||
const uint8_t * src)
|
||||
static int cirrus_bitblt_common_patterncopy(CirrusVGAState *s, bool videosrc)
|
||||
{
|
||||
uint32_t patternsize;
|
||||
uint8_t *dst;
|
||||
uint8_t *src;
|
||||
|
||||
dst = s->vga.vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask);
|
||||
dst = s->vga.vram_ptr + s->cirrus_blt_dstaddr;
|
||||
|
||||
if (blit_is_unsafe(s))
|
||||
if (videosrc) {
|
||||
switch (s->vga.get_bpp(&s->vga)) {
|
||||
case 8:
|
||||
patternsize = 64;
|
||||
break;
|
||||
case 15:
|
||||
case 16:
|
||||
patternsize = 128;
|
||||
break;
|
||||
case 24:
|
||||
case 32:
|
||||
default:
|
||||
patternsize = 256;
|
||||
break;
|
||||
}
|
||||
s->cirrus_blt_srcaddr &= ~(patternsize - 1);
|
||||
if (s->cirrus_blt_srcaddr + patternsize > s->vga.vram_size) {
|
||||
return 0;
|
||||
}
|
||||
src = s->vga.vram_ptr + s->cirrus_blt_srcaddr;
|
||||
} else {
|
||||
src = s->cirrus_bltbuf;
|
||||
}
|
||||
|
||||
if (blit_is_unsafe(s, true))
|
||||
return 0;
|
||||
|
||||
(*s->cirrus_rop) (s, dst, src,
|
||||
@@ -691,11 +724,11 @@ static int cirrus_bitblt_solidfill(CirrusVGAState *s, int blt_rop)
|
||||
{
|
||||
cirrus_fill_t rop_func;
|
||||
|
||||
if (blit_is_unsafe(s)) {
|
||||
if (blit_is_unsafe(s, true)) {
|
||||
return 0;
|
||||
}
|
||||
rop_func = cirrus_fill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
|
||||
rop_func(s, s->vga.vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask),
|
||||
rop_func(s, s->vga.vram_ptr + s->cirrus_blt_dstaddr,
|
||||
s->cirrus_blt_dstpitch,
|
||||
s->cirrus_blt_width, s->cirrus_blt_height);
|
||||
cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
|
||||
@@ -713,9 +746,7 @@ static int cirrus_bitblt_solidfill(CirrusVGAState *s, int blt_rop)
|
||||
|
||||
static int cirrus_bitblt_videotovideo_patterncopy(CirrusVGAState * s)
|
||||
{
|
||||
return cirrus_bitblt_common_patterncopy(s,
|
||||
s->vga.vram_ptr + ((s->cirrus_blt_srcaddr & ~7) &
|
||||
s->cirrus_addr_mask));
|
||||
return cirrus_bitblt_common_patterncopy(s, true);
|
||||
}
|
||||
|
||||
static int cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
|
||||
@@ -769,10 +800,8 @@ static int cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
|
||||
if (notify)
|
||||
graphic_hw_update(s->vga.con);
|
||||
|
||||
(*s->cirrus_rop) (s, s->vga.vram_ptr +
|
||||
(s->cirrus_blt_dstaddr & s->cirrus_addr_mask),
|
||||
s->vga.vram_ptr +
|
||||
(s->cirrus_blt_srcaddr & s->cirrus_addr_mask),
|
||||
(*s->cirrus_rop) (s, s->vga.vram_ptr + s->cirrus_blt_dstaddr,
|
||||
s->vga.vram_ptr + s->cirrus_blt_srcaddr,
|
||||
s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch,
|
||||
s->cirrus_blt_width, s->cirrus_blt_height);
|
||||
|
||||
@@ -795,7 +824,7 @@ static int cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
|
||||
|
||||
static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s)
|
||||
{
|
||||
if (blit_is_unsafe(s))
|
||||
if (blit_is_unsafe(s, false))
|
||||
return 0;
|
||||
|
||||
return cirrus_do_copy(s, s->cirrus_blt_dstaddr - s->vga.start_addr,
|
||||
@@ -816,15 +845,14 @@ static void cirrus_bitblt_cputovideo_next(CirrusVGAState * s)
|
||||
|
||||
if (s->cirrus_srccounter > 0) {
|
||||
if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
|
||||
cirrus_bitblt_common_patterncopy(s, s->cirrus_bltbuf);
|
||||
cirrus_bitblt_common_patterncopy(s, false);
|
||||
the_end:
|
||||
s->cirrus_srccounter = 0;
|
||||
cirrus_bitblt_reset(s);
|
||||
} else {
|
||||
/* at least one scan line */
|
||||
do {
|
||||
(*s->cirrus_rop)(s, s->vga.vram_ptr +
|
||||
(s->cirrus_blt_dstaddr & s->cirrus_addr_mask),
|
||||
(*s->cirrus_rop)(s, s->vga.vram_ptr + s->cirrus_blt_dstaddr,
|
||||
s->cirrus_bltbuf, 0, 0, s->cirrus_blt_width, 1);
|
||||
cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, 0,
|
||||
s->cirrus_blt_width, 1);
|
||||
@@ -871,6 +899,10 @@ static int cirrus_bitblt_cputovideo(CirrusVGAState * s)
|
||||
{
|
||||
int w;
|
||||
|
||||
if (blit_is_unsafe(s, true)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
s->cirrus_blt_mode &= ~CIRRUS_BLTMODE_MEMSYSSRC;
|
||||
s->cirrus_srcptr = &s->cirrus_bltbuf[0];
|
||||
s->cirrus_srcptr_end = &s->cirrus_bltbuf[0];
|
||||
@@ -896,6 +928,10 @@ static int cirrus_bitblt_cputovideo(CirrusVGAState * s)
|
||||
}
|
||||
s->cirrus_srccounter = s->cirrus_blt_srcpitch * s->cirrus_blt_height;
|
||||
}
|
||||
|
||||
/* the blit_is_unsafe call above should catch this */
|
||||
assert(s->cirrus_blt_srcpitch <= CIRRUS_BLTBUFSIZE);
|
||||
|
||||
s->cirrus_srcptr = s->cirrus_bltbuf;
|
||||
s->cirrus_srcptr_end = s->cirrus_bltbuf + s->cirrus_blt_srcpitch;
|
||||
cirrus_update_memory_access(s);
|
||||
@@ -943,6 +979,9 @@ static void cirrus_bitblt_start(CirrusVGAState * s)
|
||||
s->cirrus_blt_modeext = s->vga.gr[0x33];
|
||||
blt_rop = s->vga.gr[0x32];
|
||||
|
||||
s->cirrus_blt_dstaddr &= s->cirrus_addr_mask;
|
||||
s->cirrus_blt_srcaddr &= s->cirrus_addr_mask;
|
||||
|
||||
#ifdef DEBUG_BITBLT
|
||||
printf("rop=0x%02x mode=0x%02x modeext=0x%02x w=%d h=%d dpitch=%d spitch=%d daddr=0x%08x saddr=0x%08x writemask=0x%02x\n",
|
||||
blt_rop,
|
||||
|
@@ -77,10 +77,18 @@ static void virgl_cmd_resource_unref(VirtIOGPU *g,
|
||||
struct virtio_gpu_ctrl_command *cmd)
|
||||
{
|
||||
struct virtio_gpu_resource_unref unref;
|
||||
struct iovec *res_iovs = NULL;
|
||||
int num_iovs = 0;
|
||||
|
||||
VIRTIO_GPU_FILL_CMD(unref);
|
||||
trace_virtio_gpu_cmd_res_unref(unref.resource_id);
|
||||
|
||||
virgl_renderer_resource_detach_iov(unref.resource_id,
|
||||
&res_iovs,
|
||||
&num_iovs);
|
||||
if (res_iovs != NULL && num_iovs != 0) {
|
||||
virtio_gpu_cleanup_mapping_iov(res_iovs, num_iovs);
|
||||
}
|
||||
virgl_renderer_resource_unref(unref.resource_id);
|
||||
}
|
||||
|
||||
@@ -291,8 +299,11 @@ static void virgl_resource_attach_backing(VirtIOGPU *g,
|
||||
return;
|
||||
}
|
||||
|
||||
virgl_renderer_resource_attach_iov(att_rb.resource_id,
|
||||
res_iovs, att_rb.nr_entries);
|
||||
ret = virgl_renderer_resource_attach_iov(att_rb.resource_id,
|
||||
res_iovs, att_rb.nr_entries);
|
||||
|
||||
if (ret != 0)
|
||||
virtio_gpu_cleanup_mapping_iov(res_iovs, att_rb.nr_entries);
|
||||
}
|
||||
|
||||
static void virgl_resource_detach_backing(VirtIOGPU *g,
|
||||
@@ -371,8 +382,12 @@ static void virgl_cmd_get_capset(VirtIOGPU *g,
|
||||
|
||||
virgl_renderer_get_cap_set(gc.capset_id, &max_ver,
|
||||
&max_size);
|
||||
resp = g_malloc(sizeof(*resp) + max_size);
|
||||
if (!max_size) {
|
||||
cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
|
||||
return;
|
||||
}
|
||||
|
||||
resp = g_malloc0(sizeof(*resp) + max_size);
|
||||
resp->hdr.type = VIRTIO_GPU_RESP_OK_CAPSET;
|
||||
virgl_renderer_fill_caps(gc.capset_id,
|
||||
gc.capset_version,
|
||||
|
@@ -28,6 +28,8 @@
|
||||
static struct virtio_gpu_simple_resource*
|
||||
virtio_gpu_find_resource(VirtIOGPU *g, uint32_t resource_id);
|
||||
|
||||
static void virtio_gpu_cleanup_mapping(struct virtio_gpu_simple_resource *res);
|
||||
|
||||
#ifdef CONFIG_VIRGL
|
||||
#include <virglrenderer.h>
|
||||
#define VIRGL(_g, _virgl, _simple, ...) \
|
||||
@@ -359,6 +361,7 @@ static void virtio_gpu_resource_destroy(VirtIOGPU *g,
|
||||
struct virtio_gpu_simple_resource *res)
|
||||
{
|
||||
pixman_image_unref(res->image);
|
||||
virtio_gpu_cleanup_mapping(res);
|
||||
QTAILQ_REMOVE(&g->reslist, res, next);
|
||||
g_free(res);
|
||||
}
|
||||
@@ -705,6 +708,11 @@ virtio_gpu_resource_attach_backing(VirtIOGPU *g,
|
||||
return;
|
||||
}
|
||||
|
||||
if (res->iov) {
|
||||
cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
|
||||
return;
|
||||
}
|
||||
|
||||
ret = virtio_gpu_create_mapping_iov(&ab, cmd, &res->addrs, &res->iov);
|
||||
if (ret != 0) {
|
||||
cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
|
||||
|
@@ -460,7 +460,7 @@ static void rc4030_write(void *opaque, hwaddr addr, uint64_t data,
|
||||
break;
|
||||
/* Interval timer reload */
|
||||
case 0x0228:
|
||||
s->itr = val;
|
||||
s->itr = val & 0x01FF;
|
||||
qemu_irq_lower(s->timer_irq);
|
||||
set_next_tick(s);
|
||||
break;
|
||||
|
@@ -770,7 +770,32 @@ DEFINE_I440FX_MACHINE(v1_0, "pc-1.0", pc_compat_1_2,
|
||||
|
||||
|
||||
#define PC_COMPAT_0_15 \
|
||||
PC_CPU_MODEL_IDS("0.15")
|
||||
PC_CPU_MODEL_IDS("0.15")\
|
||||
{\
|
||||
.driver = "VGA",\
|
||||
.property = "vgamem_mb",\
|
||||
.value = stringify(16),\
|
||||
},{\
|
||||
.driver = "vmware-svga",\
|
||||
.property = "vgamem_mb",\
|
||||
.value = stringify(16),\
|
||||
},{\
|
||||
.driver = "qxl-vga",\
|
||||
.property = "vgamem_mb",\
|
||||
.value = stringify(16),\
|
||||
},{\
|
||||
.driver = "qxl",\
|
||||
.property = "vgamem_mb",\
|
||||
.value = stringify(16),\
|
||||
},{\
|
||||
.driver = "isa-cirrus-vga",\
|
||||
.property = "vgamem_mb",\
|
||||
.value = stringify(16),\
|
||||
},{\
|
||||
.driver = "cirrus-vga",\
|
||||
.property = "vgamem_mb",\
|
||||
.value = stringify(16),\
|
||||
},
|
||||
|
||||
static void pc_i440fx_0_15_machine_options(MachineClass *m)
|
||||
{
|
||||
|
@@ -10,7 +10,6 @@ common-obj-$(CONFIG_REALVIEW) += realview_gic.o
|
||||
common-obj-$(CONFIG_SLAVIO) += slavio_intctl.o
|
||||
common-obj-$(CONFIG_IOAPIC) += ioapic_common.o
|
||||
common-obj-$(CONFIG_ARM_GIC) += arm_gic_common.o
|
||||
common-obj-$(CONFIG_ARM_GIC) += arm_gic.o
|
||||
common-obj-$(CONFIG_ARM_GIC) += arm_gicv2m.o
|
||||
common-obj-$(CONFIG_ARM_GIC) += arm_gicv3_common.o
|
||||
common-obj-$(CONFIG_ARM_GIC) += arm_gicv3.o
|
||||
@@ -21,6 +20,7 @@ common-obj-$(CONFIG_OPENPIC) += openpic.o
|
||||
common-obj-y += intc.o
|
||||
|
||||
obj-$(CONFIG_APIC) += apic.o apic_common.o
|
||||
obj-$(CONFIG_ARM_GIC) += arm_gic.o
|
||||
obj-$(CONFIG_ARM_GIC_KVM) += arm_gic_kvm.o
|
||||
obj-$(call land,$(CONFIG_ARM_GIC_KVM),$(TARGET_AARCH64)) += arm_gicv3_kvm.o
|
||||
obj-$(call land,$(CONFIG_ARM_GIC_KVM),$(TARGET_AARCH64)) += arm_gicv3_its_kvm.o
|
||||
|
@@ -25,6 +25,7 @@
|
||||
#include "qom/cpu.h"
|
||||
#include "qemu/log.h"
|
||||
#include "trace.h"
|
||||
#include "kvm_arm.h"
|
||||
|
||||
//#define DEBUG_GIC
|
||||
|
||||
@@ -557,6 +558,11 @@ static void gic_deactivate_irq(GICState *s, int cpu, int irq, MemTxAttrs attrs)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Tell KVM that we want to know about timer IRQs again */
|
||||
if (kvm_enabled()) {
|
||||
kvm_arm_eoi_notify(cpu);
|
||||
}
|
||||
|
||||
GIC_CLEAR_ACTIVE(irq, cm);
|
||||
}
|
||||
|
||||
@@ -566,6 +572,12 @@ void gic_complete_irq(GICState *s, int cpu, int irq, MemTxAttrs attrs)
|
||||
int group;
|
||||
|
||||
DPRINTF("EOI %d\n", irq);
|
||||
|
||||
/* Tell KVM that we want to know about timer IRQs again */
|
||||
if (kvm_enabled()) {
|
||||
kvm_arm_eoi_notify(cpu);
|
||||
}
|
||||
|
||||
if (irq >= s->num_irq) {
|
||||
/* This handles two cases:
|
||||
* 1. If software writes the ID of a spurious interrupt [ie 1023]
|
||||
@@ -915,6 +927,10 @@ static void gic_dist_writeb(void *opaque, hwaddr offset,
|
||||
trace_gic_enable_irq(irq + i);
|
||||
}
|
||||
GIC_SET_ENABLED(irq + i, cm);
|
||||
/* Tell KVM that we want to know about timer IRQs again */
|
||||
if (kvm_enabled()) {
|
||||
kvm_arm_eoi_notify(cpu);
|
||||
}
|
||||
/* If a raised level triggered IRQ enabled then mark
|
||||
is as pending. */
|
||||
if (GIC_TEST_LEVEL(irq + i, mask)
|
||||
|
@@ -220,6 +220,8 @@ static const VMStateDescription vmstate_imx_eth = {
|
||||
#define PHY_INT_PARFAULT (1 << 2)
|
||||
#define PHY_INT_AUTONEG_PAGE (1 << 1)
|
||||
|
||||
#define IMX_MAX_DESC 1024
|
||||
|
||||
static void imx_eth_update(IMXFECState *s);
|
||||
|
||||
/*
|
||||
@@ -402,12 +404,12 @@ static void imx_eth_update(IMXFECState *s)
|
||||
|
||||
static void imx_fec_do_tx(IMXFECState *s)
|
||||
{
|
||||
int frame_size = 0;
|
||||
int frame_size = 0, descnt = 0;
|
||||
uint8_t frame[ENET_MAX_FRAME_SIZE];
|
||||
uint8_t *ptr = frame;
|
||||
uint32_t addr = s->tx_descriptor;
|
||||
|
||||
while (1) {
|
||||
while (descnt++ < IMX_MAX_DESC) {
|
||||
IMXFECBufDesc bd;
|
||||
int len;
|
||||
|
||||
|
@@ -204,8 +204,8 @@ void s390_machine_reset(void)
|
||||
{
|
||||
S390CPU *ipl_cpu = S390_CPU(qemu_get_cpu(0));
|
||||
|
||||
qemu_devices_reset();
|
||||
s390_cmma_reset();
|
||||
qemu_devices_reset();
|
||||
s390_crypto_reset();
|
||||
|
||||
/* all cpus are stopped - configure and start the ipl cpu only */
|
||||
|
@@ -683,14 +683,14 @@ static int megasas_map_dcmd(MegasasState *s, MegasasCmd *cmd)
|
||||
trace_megasas_dcmd_invalid_sge(cmd->index,
|
||||
cmd->frame->header.sge_count);
|
||||
cmd->iov_size = 0;
|
||||
return -1;
|
||||
return -EINVAL;
|
||||
}
|
||||
iov_pa = megasas_sgl_get_addr(cmd, &cmd->frame->dcmd.sgl);
|
||||
iov_size = megasas_sgl_get_len(cmd, &cmd->frame->dcmd.sgl);
|
||||
pci_dma_sglist_init(&cmd->qsg, PCI_DEVICE(s), 1);
|
||||
qemu_sglist_add(&cmd->qsg, iov_pa, iov_size);
|
||||
cmd->iov_size = iov_size;
|
||||
return cmd->iov_size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void megasas_finish_dcmd(MegasasCmd *cmd, uint32_t iov_size)
|
||||
@@ -1559,19 +1559,20 @@ static const struct dcmd_cmd_tbl_t {
|
||||
|
||||
static int megasas_handle_dcmd(MegasasState *s, MegasasCmd *cmd)
|
||||
{
|
||||
int opcode, len;
|
||||
int opcode;
|
||||
int retval = 0;
|
||||
size_t len;
|
||||
const struct dcmd_cmd_tbl_t *cmdptr = dcmd_cmd_tbl;
|
||||
|
||||
opcode = le32_to_cpu(cmd->frame->dcmd.opcode);
|
||||
trace_megasas_handle_dcmd(cmd->index, opcode);
|
||||
len = megasas_map_dcmd(s, cmd);
|
||||
if (len < 0) {
|
||||
if (megasas_map_dcmd(s, cmd) < 0) {
|
||||
return MFI_STAT_MEMORY_NOT_AVAILABLE;
|
||||
}
|
||||
while (cmdptr->opcode != -1 && cmdptr->opcode != opcode) {
|
||||
cmdptr++;
|
||||
}
|
||||
len = cmd->iov_size;
|
||||
if (cmdptr->opcode == -1) {
|
||||
trace_megasas_dcmd_unhandled(cmd->index, opcode, len);
|
||||
retval = megasas_dcmd_dummy(s, cmd);
|
||||
|
@@ -536,7 +536,7 @@ static void sdhci_sdma_transfer_multi_blocks(SDHCIState *s)
|
||||
boundary_count -= block_size - begin;
|
||||
}
|
||||
dma_memory_read(&address_space_memory, s->sdmasysad,
|
||||
&s->fifo_buffer[begin], s->data_count);
|
||||
&s->fifo_buffer[begin], s->data_count - begin);
|
||||
s->sdmasysad += s->data_count - begin;
|
||||
if (s->data_count == block_size) {
|
||||
for (n = 0; n < block_size; n++) {
|
||||
|
@@ -258,6 +258,12 @@ static int pit_dispatch_post_load(void *opaque, int version_id)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool is_qemu_kvm(void *opaque, int version_id)
|
||||
{
|
||||
/* HACK: We ignore incoming migration from upstream qemu */
|
||||
return version_id < 3;
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_pit_common = {
|
||||
.name = "i8254",
|
||||
.version_id = 3,
|
||||
@@ -267,6 +273,7 @@ static const VMStateDescription vmstate_pit_common = {
|
||||
.pre_save = pit_dispatch_pre_save,
|
||||
.post_load = pit_dispatch_post_load,
|
||||
.fields = (VMStateField[]) {
|
||||
VMSTATE_UNUSED_TEST(is_qemu_kvm, 4),
|
||||
VMSTATE_UINT32_V(channels[0].irq_disabled, PITCommonState, 3),
|
||||
VMSTATE_STRUCT_ARRAY(channels, PITCommonState, 3, 2,
|
||||
vmstate_pit_channel, PITChannelState),
|
||||
|
@@ -967,7 +967,7 @@ static void ccid_on_apdu_from_guest(USBCCIDState *s, CCID_XferBlock *recv)
|
||||
DPRINTF(s, 1, "%s: seq %d, len %d\n", __func__,
|
||||
recv->hdr.bSeq, len);
|
||||
ccid_add_pending_answer(s, (CCID_Header *)recv);
|
||||
if (s->card) {
|
||||
if (s->card && len <= BULK_OUT_DATA_SIZE) {
|
||||
ccid_card_apdu_from_guest(s->card, recv->abData, len);
|
||||
} else {
|
||||
DPRINTF(s, D_WARN, "warning: discarded apdu\n");
|
||||
|
@@ -92,7 +92,7 @@ struct VirtQueue
|
||||
|
||||
uint16_t queue_index;
|
||||
|
||||
int inuse;
|
||||
unsigned int inuse;
|
||||
|
||||
uint16_t vector;
|
||||
VirtIOHandleOutput handle_output;
|
||||
@@ -1855,9 +1855,11 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
|
||||
/*
|
||||
* Some devices migrate VirtQueueElements that have been popped
|
||||
* from the avail ring but not yet returned to the used ring.
|
||||
* Since max ring size < UINT16_MAX it's safe to use modulo
|
||||
* UINT16_MAX + 1 subtraction.
|
||||
*/
|
||||
vdev->vq[i].inuse = vdev->vq[i].last_avail_idx -
|
||||
vdev->vq[i].used_idx;
|
||||
vdev->vq[i].inuse = (uint16_t)(vdev->vq[i].last_avail_idx -
|
||||
vdev->vq[i].used_idx);
|
||||
if (vdev->vq[i].inuse > vdev->vq[i].vring.num) {
|
||||
error_report("VQ %d size 0x%x < last_avail_idx 0x%x - "
|
||||
"used_idx 0x%x",
|
||||
|
@@ -428,6 +428,14 @@ static void i6300esb_realize(PCIDevice *dev, Error **errp)
|
||||
/* qemu_register_coalesced_mmio (addr, 0x10); ? */
|
||||
}
|
||||
|
||||
static void i6300esb_exit(PCIDevice *dev)
|
||||
{
|
||||
I6300State *d = WATCHDOG_I6300ESB_DEVICE(dev);
|
||||
|
||||
timer_del(d->timer);
|
||||
timer_free(d->timer);
|
||||
}
|
||||
|
||||
static WatchdogTimerModel model = {
|
||||
.wdt_name = "i6300esb",
|
||||
.wdt_description = "Intel 6300ESB",
|
||||
@@ -441,6 +449,7 @@ static void i6300esb_class_init(ObjectClass *klass, void *data)
|
||||
k->config_read = i6300esb_config_read;
|
||||
k->config_write = i6300esb_config_write;
|
||||
k->realize = i6300esb_realize;
|
||||
k->exit = i6300esb_exit;
|
||||
k->vendor_id = PCI_VENDOR_ID_INTEL;
|
||||
k->device_id = PCI_DEVICE_ID_INTEL_ESB_9;
|
||||
k->class_id = PCI_CLASS_SYSTEM_OTHER;
|
||||
|
@@ -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:
|
||||
|
@@ -205,6 +205,7 @@ struct kvm_hyperv_exit {
|
||||
#define KVM_EXIT_S390_STSI 25
|
||||
#define KVM_EXIT_IOAPIC_EOI 26
|
||||
#define KVM_EXIT_HYPERV 27
|
||||
#define KVM_EXIT_ARM_TIMER 28
|
||||
|
||||
/* For KVM_EXIT_INTERNAL_ERROR */
|
||||
/* Emulate instruction failed. */
|
||||
@@ -361,6 +362,10 @@ struct kvm_run {
|
||||
} eoi;
|
||||
/* KVM_EXIT_HYPERV */
|
||||
struct kvm_hyperv_exit hyperv;
|
||||
/* KVM_EXIT_ARM_TIMER */
|
||||
struct {
|
||||
__u8 timesource;
|
||||
} arm_timer;
|
||||
/* Fix the size of the union. */
|
||||
char padding[256];
|
||||
};
|
||||
@@ -870,6 +875,7 @@ struct kvm_ppc_smmu_info {
|
||||
#define KVM_CAP_S390_USER_INSTR0 130
|
||||
#define KVM_CAP_MSI_DEVID 131
|
||||
#define KVM_CAP_PPC_HTM 132
|
||||
#define KVM_CAP_ARM_TIMER 133
|
||||
|
||||
#ifdef KVM_CAP_IRQ_ROUTING
|
||||
|
||||
@@ -1327,4 +1333,12 @@ struct kvm_assigned_msix_entry {
|
||||
#define KVM_X2APIC_API_USE_32BIT_IDS (1ULL << 0)
|
||||
#define KVM_X2APIC_API_DISABLE_BROADCAST_QUIRK (1ULL << 1)
|
||||
|
||||
/* Available with KVM_CAP_ARM_TIMER */
|
||||
|
||||
/* Bits for run->request_interrupt_window */
|
||||
#define KVM_IRQWINDOW_VTIMER (1 << 0)
|
||||
|
||||
/* Bits for run->arm_timer.timesource */
|
||||
#define KVM_ARM_TIMER_VTIMER (1 << 0)
|
||||
|
||||
#endif /* __LINUX_KVM_H */
|
||||
|
@@ -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
68
linux-user/binfmt.c
Normal 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);
|
||||
}
|
@@ -351,6 +351,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
467
linux-user/ioctls_alsa.h
Normal 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)) )
|
1740
linux-user/ioctls_alsa_structs.h
Normal file
1740
linux-user/ioctls_alsa_structs.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -4045,6 +4045,8 @@ int main(int argc, char **argv, char **envp)
|
||||
# endif
|
||||
#elif defined TARGET_SH4
|
||||
cpu_model = TYPE_SH7785_CPU;
|
||||
#elif defined TARGET_S390X
|
||||
cpu_model = "qemu";
|
||||
#else
|
||||
cpu_model = "any";
|
||||
#endif
|
||||
|
@@ -360,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)
|
||||
@@ -394,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;
|
||||
|
@@ -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);
|
||||
|
@@ -560,6 +560,10 @@ static void QEMU_NORETURN dump_core_and_abort(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();
|
||||
@@ -577,6 +581,8 @@ static void QEMU_NORETURN dump_core_and_abort(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
|
||||
|
@@ -4938,6 +4938,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++;
|
||||
@@ -5471,7 +5476,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)
|
||||
@@ -5499,6 +5509,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)) {
|
||||
@@ -5517,6 +5532,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);
|
||||
@@ -7214,52 +7230,19 @@ int host_to_target_waitstatus(int status)
|
||||
|
||||
static int open_self_cmdline(void *cpu_env, int fd)
|
||||
{
|
||||
int fd_orig = -1;
|
||||
bool word_skipped = false;
|
||||
CPUState *cpu = ENV_GET_CPU((CPUArchState *)cpu_env);
|
||||
struct linux_binprm *bprm = ((TaskState *)cpu->opaque)->bprm;
|
||||
int i;
|
||||
|
||||
fd_orig = open("/proc/self/cmdline", O_RDONLY);
|
||||
if (fd_orig < 0) {
|
||||
return fd_orig;
|
||||
}
|
||||
for (i = 0; i < bprm->argc; i++) {
|
||||
size_t len = strlen(bprm->argv[i]) + 1;
|
||||
|
||||
while (true) {
|
||||
ssize_t nb_read;
|
||||
char buf[128];
|
||||
char *cp_buf = buf;
|
||||
|
||||
nb_read = read(fd_orig, buf, sizeof(buf));
|
||||
if (nb_read < 0) {
|
||||
int e = errno;
|
||||
fd_orig = close(fd_orig);
|
||||
errno = e;
|
||||
if (write(fd, bprm->argv[i], len) != len) {
|
||||
return -1;
|
||||
} else if (nb_read == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!word_skipped) {
|
||||
/* Skip the first string, which is the path to qemu-*-static
|
||||
instead of the actual command. */
|
||||
cp_buf = memchr(buf, 0, nb_read);
|
||||
if (cp_buf) {
|
||||
/* Null byte found, skip one string */
|
||||
cp_buf++;
|
||||
nb_read -= cp_buf - buf;
|
||||
word_skipped = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (word_skipped) {
|
||||
if (write(fd, cp_buf, nb_read) != nb_read) {
|
||||
int e = errno;
|
||||
close(fd_orig);
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return close(fd_orig);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int open_self_maps(void *cpu_env, int fd)
|
||||
@@ -7348,6 +7331,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);
|
||||
@@ -7462,6 +7464,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 }
|
||||
};
|
||||
|
||||
@@ -7530,10 +7533,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;
|
||||
@@ -7896,9 +7899,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:
|
||||
@@ -8770,6 +8778,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))
|
||||
@@ -10018,7 +10028,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
{
|
||||
struct timespec ts, *pts;
|
||||
|
||||
if (arg3 >= 0) {
|
||||
if ((abi_long)arg3 >= 0) {
|
||||
/* Convert ms to secs, ns */
|
||||
ts.tv_sec = arg3 / 1000;
|
||||
ts.tv_nsec = (arg3 % 1000) * 1000000LL;
|
||||
|
@@ -2640,6 +2640,8 @@ struct target_ucred {
|
||||
uint32_t gid;
|
||||
};
|
||||
|
||||
#include "ioctls_alsa_structs.h"
|
||||
|
||||
typedef int32_t target_timer_t;
|
||||
|
||||
#define TARGET_SIGEV_MAX_SIZE 64
|
||||
|
@@ -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 */
|
||||
|
1336
linux-user/syscall_types_alsa.h
Normal file
1336
linux-user/syscall_types_alsa.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -43,7 +43,8 @@ static void free_range(void *range, void *dummy)
|
||||
g_free(range);
|
||||
}
|
||||
|
||||
static int parse_str(StringInputVisitor *siv, const char *name, Error **errp)
|
||||
static int parse_str(StringInputVisitor *siv, const char *name, bool u64,
|
||||
Error **errp)
|
||||
{
|
||||
char *str = (char *) siv->string;
|
||||
long long start, end;
|
||||
@@ -56,7 +57,11 @@ static int parse_str(StringInputVisitor *siv, const char *name, Error **errp)
|
||||
|
||||
do {
|
||||
errno = 0;
|
||||
start = strtoll(str, &endptr, 0);
|
||||
if (u64) {
|
||||
start = strtoull(str, &endptr, 0);
|
||||
} else {
|
||||
start = strtoll(str, &endptr, 0);
|
||||
}
|
||||
if (errno == 0 && endptr > str) {
|
||||
if (*endptr == '\0') {
|
||||
cur = g_malloc0(sizeof(*cur));
|
||||
@@ -67,7 +72,11 @@ static int parse_str(StringInputVisitor *siv, const char *name, Error **errp)
|
||||
} else if (*endptr == '-') {
|
||||
str = endptr + 1;
|
||||
errno = 0;
|
||||
end = strtoll(str, &endptr, 0);
|
||||
if (u64) {
|
||||
end = strtoull(str, &endptr, 0);
|
||||
} else {
|
||||
end = strtoll(str, &endptr, 0);
|
||||
}
|
||||
if (errno == 0 && endptr > str && start <= end &&
|
||||
(start > INT64_MAX - 65536 ||
|
||||
end < start + 65536)) {
|
||||
@@ -123,7 +132,7 @@ start_list(Visitor *v, const char *name, GenericList **list, size_t size,
|
||||
assert(list);
|
||||
siv->list = list;
|
||||
|
||||
if (parse_str(siv, name, errp) < 0) {
|
||||
if (parse_str(siv, name, false, errp) < 0) {
|
||||
*list = NULL;
|
||||
return;
|
||||
}
|
||||
@@ -188,7 +197,7 @@ static void parse_type_int64(Visitor *v, const char *name, int64_t *obj,
|
||||
return;
|
||||
}
|
||||
|
||||
if (parse_str(siv, name, errp) < 0) {
|
||||
if (parse_str(siv, name, false, errp) < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -224,15 +233,43 @@ error:
|
||||
static void parse_type_uint64(Visitor *v, const char *name, uint64_t *obj,
|
||||
Error **errp)
|
||||
{
|
||||
/* FIXME: parse_type_int64 mishandles values over INT64_MAX */
|
||||
int64_t i;
|
||||
Error *err = NULL;
|
||||
parse_type_int64(v, name, &i, &err);
|
||||
if (err) {
|
||||
error_propagate(errp, err);
|
||||
} else {
|
||||
*obj = i;
|
||||
StringInputVisitor *siv = to_siv(v);
|
||||
|
||||
if (!siv->string) {
|
||||
error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
|
||||
"integer");
|
||||
return;
|
||||
}
|
||||
|
||||
parse_str(siv, name, true, errp);
|
||||
|
||||
if (!siv->ranges) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!siv->cur_range) {
|
||||
Range *r;
|
||||
|
||||
siv->cur_range = g_list_first(siv->ranges);
|
||||
if (!siv->cur_range) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
r = siv->cur_range->data;
|
||||
if (!r) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
siv->cur = range_lob(r);
|
||||
}
|
||||
|
||||
*obj = siv->cur;
|
||||
siv->cur++;
|
||||
return;
|
||||
|
||||
error:
|
||||
error_setg(errp, QERR_INVALID_PARAMETER_VALUE, name,
|
||||
"a uint64 value or range");
|
||||
}
|
||||
|
||||
static void parse_type_size(Visitor *v, const char *name, uint64_t *obj,
|
||||
|
@@ -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;
|
||||
|
16
qemu-char.c
16
qemu-char.c
@@ -531,6 +531,9 @@ static CharDriverState *qemu_chr_open_null(const char *id,
|
||||
struct MuxDriver {
|
||||
CharBackend *backends[MAX_MUX];
|
||||
CharBackend chr;
|
||||
#if defined(TARGET_S390X)
|
||||
QEMUTimer *accept_timer;
|
||||
#endif
|
||||
int focus;
|
||||
int mux_cnt;
|
||||
int term_got_escape;
|
||||
@@ -694,6 +697,15 @@ static void mux_chr_accept_input(CharDriverState *chr)
|
||||
be->chr_read(be->opaque,
|
||||
&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)
|
||||
@@ -864,6 +876,10 @@ static CharDriverState *qemu_chr_open_mux(const char *id,
|
||||
|
||||
chr->opaque = d;
|
||||
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_free = mux_chr_free;
|
||||
chr->chr_write = mux_chr_write;
|
||||
chr->chr_accept_input = mux_chr_accept_input;
|
||||
|
@@ -3162,6 +3162,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
|
||||
|
@@ -52,6 +52,12 @@ SEABIOS_EXTRAVERSION="-prebuilt.qemu-project.org"
|
||||
#
|
||||
EFIROM ?= $(shell which EfiRom 2>/dev/null)
|
||||
|
||||
# NB: Certain SUSE qemu subpackages use date information, but we want
|
||||
# reproducible builds, so we use a pre-determined timestamp, rather
|
||||
# than the current timestamp to acheive consistent results build to
|
||||
# build.
|
||||
PACKAGING_TIMESTAMP = $(shell date -r ../VERSION +%s)
|
||||
|
||||
default:
|
||||
@echo "nothing is build by default"
|
||||
@echo "available build targets:"
|
||||
@@ -106,7 +112,7 @@ build-lgplvgabios:
|
||||
|
||||
.PHONY: sgabios skiboot
|
||||
sgabios:
|
||||
$(MAKE) -C sgabios
|
||||
$(MAKE) -C sgabios PACKAGING_TIMESTAMP=$(PACKAGING_TIMESTAMP)
|
||||
cp sgabios/sgabios.bin ../pc-bios
|
||||
|
||||
|
||||
@@ -126,18 +132,22 @@ efi-rom-%: build-pxe-roms build-efi-roms
|
||||
|
||||
build-pxe-roms:
|
||||
$(MAKE) -C ipxe/src CONFIG=qemu \
|
||||
PACKAGING_TIMESTAMP=$(PACKAGING_TIMESTAMP) \
|
||||
CROSS_COMPILE=$(x86_64_cross_prefix) \
|
||||
$(patsubst %,bin/%.rom,$(pxerom_targets))
|
||||
|
||||
build-efi-roms: build-pxe-roms
|
||||
$(MAKE) -C ipxe/src CONFIG=qemu \
|
||||
PACKAGING_TIMESTAMP=$(PACKAGING_TIMESTAMP) \
|
||||
CROSS_COMPILE=$(x86_64_cross_prefix) \
|
||||
$(patsubst %,bin-i386-efi/%.efidrv,$(pxerom_targets)) \
|
||||
$(patsubst %,bin-x86_64-efi/%.efidrv,$(pxerom_targets))
|
||||
|
||||
|
||||
slof:
|
||||
$(MAKE) -C SLOF CROSS=$(powerpc64_cross_prefix) qemu
|
||||
$(MAKE) -C SLOF CROSS=$(powerpc64_cross_prefix) \
|
||||
PACKAGING_TIMESTAMP=$(PACKAGING_TIMESTAMP) \
|
||||
qemu
|
||||
cp SLOF/boot_rom.bin ../pc-bios/slof.bin
|
||||
|
||||
u-boot.e500:
|
||||
|
@@ -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: -- "$@")
|
||||
|
@@ -625,6 +625,8 @@ sorecvfrom(struct socket *so)
|
||||
} /* if ping packet */
|
||||
}
|
||||
|
||||
extern int slirp_nooutgoing;
|
||||
|
||||
/*
|
||||
* sendto() a socket
|
||||
*/
|
||||
@@ -642,6 +644,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));
|
||||
|
@@ -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;
|
||||
|
@@ -530,7 +530,6 @@ MemTxAttrs kvm_arch_post_run(CPUState *cs, struct kvm_run *run)
|
||||
return MEMTXATTRS_UNSPECIFIED;
|
||||
}
|
||||
|
||||
|
||||
int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
|
||||
{
|
||||
int ret = 0;
|
||||
@@ -541,6 +540,23 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
|
||||
ret = EXCP_DEBUG;
|
||||
} /* otherwise return to guest */
|
||||
break;
|
||||
case KVM_EXIT_ARM_TIMER:
|
||||
/* We only support the vtimer today */
|
||||
if (run->arm_timer.timesource != KVM_ARM_TIMER_VTIMER) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* We ask the kernel to not tell us about pending virtual timer irqs,
|
||||
* so that we can process the IRQ until we get an EOI for it. Once the
|
||||
* EOI hits, we unset and unmask the interrupt again and if it is still
|
||||
* pending, we set the line high again
|
||||
*/
|
||||
run->request_interrupt_window = KVM_IRQWINDOW_VTIMER;
|
||||
|
||||
/* Internally trigger virtual timer IRQ */
|
||||
qemu_set_irq(ARM_CPU(cs)->gt_timer_outputs[GTIMER_VIRT], 1);
|
||||
break;
|
||||
default:
|
||||
qemu_log_mask(LOG_UNIMP, "%s: un-handled exit reason %d\n",
|
||||
__func__, run->exit_reason);
|
||||
@@ -638,3 +654,14 @@ int kvm_arch_msi_data_to_gsi(uint32_t data)
|
||||
{
|
||||
return (data - 32) & 0xffff;
|
||||
}
|
||||
|
||||
void kvm_arm_eoi_notify(int cpu)
|
||||
{
|
||||
CPUState *cs;
|
||||
|
||||
cs = qemu_get_cpu(cpu);
|
||||
|
||||
/* Disable vtimer - if it's still pending we get notified again */
|
||||
cs->kvm_run->request_interrupt_window &= ~KVM_ARM_TIMER_VTIMER;
|
||||
qemu_set_irq(ARM_CPU(cs)->gt_timer_outputs[GTIMER_VIRT], 0);
|
||||
}
|
||||
|
@@ -288,4 +288,15 @@ static inline const char *its_class_name(void)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* kvm_arm_eoi_notify:
|
||||
*
|
||||
* @cpu: CPU index the EOI is for
|
||||
*
|
||||
* Notify KVM that we're done processing an interrupt. This is
|
||||
* used to unmask any pending timer interrupts and potentially
|
||||
* learn about the fact that the level is still high.
|
||||
*/
|
||||
void kvm_arm_eoi_notify(int cpu);
|
||||
|
||||
#endif
|
||||
|
@@ -1465,7 +1465,7 @@ uint64_t cpu_get_tsc(CPUX86State *env);
|
||||
/* XXX: This value should match the one returned by CPUID
|
||||
* and in exec.c */
|
||||
# if defined(TARGET_X86_64)
|
||||
# define TCG_PHYS_ADDR_BITS 40
|
||||
# define TCG_PHYS_ADDR_BITS 42
|
||||
# else
|
||||
# define TCG_PHYS_ADDR_BITS 36
|
||||
# endif
|
||||
|
@@ -738,6 +738,7 @@ void s390_realize_cpu_model(CPUState *cs, Error **errp)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
/* copy over properties that can vary */
|
||||
cpu->model->lowest_ibc = max_model->lowest_ibc;
|
||||
cpu->model->cpu_id = max_model->cpu_id;
|
||||
@@ -750,6 +751,7 @@ void s390_realize_cpu_model(CPUState *cs, Error **errp)
|
||||
}
|
||||
|
||||
apply_cpu_model(cpu->model, errp);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void get_feature(Object *obj, Visitor *v, const char *name,
|
||||
|
@@ -86,6 +86,8 @@ check-unit-y += tests/check-qom-interface$(EXESUF)
|
||||
gcov-files-check-qom-interface-y = qom/object.c
|
||||
check-unit-y += tests/check-qom-proplist$(EXESUF)
|
||||
gcov-files-check-qom-proplist-y = qom/object.c
|
||||
check-unit-y += tests/check-qom-props$(EXESUF)
|
||||
gcov-files-check-qom-props-y = qom/object.c
|
||||
check-unit-y += tests/test-qemu-opts$(EXESUF)
|
||||
gcov-files-test-qemu-opts-y = qom/test-qemu-opts.c
|
||||
check-unit-y += tests/test-write-threshold$(EXESUF)
|
||||
@@ -146,6 +148,8 @@ check-qtest-virtio-y += tests/virtio-rng-test$(EXESUF)
|
||||
gcov-files-virtio-y += hw/virtio/virtio-rng.c
|
||||
check-qtest-virtio-y += tests/virtio-scsi-test$(EXESUF)
|
||||
gcov-files-virtio-y += i386-softmmu/hw/scsi/virtio-scsi.c
|
||||
check-qtest-virtio-y += tests/scsi-disk-test$(EXESUF)
|
||||
gcov-files-virtio-y += i386-softmmu/hw/scsi/scsi-disk.c
|
||||
ifeq ($(CONFIG_VIRTIO)$(CONFIG_VIRTFS)$(CONFIG_PCI),yyy)
|
||||
check-qtest-virtio-y += tests/virtio-9p-test$(EXESUF)
|
||||
gcov-files-virtio-y += hw/9pfs/virtio-9p.c
|
||||
@@ -487,6 +491,7 @@ tests/check-qnull$(EXESUF): tests/check-qnull.o $(test-util-obj-y)
|
||||
tests/check-qjson$(EXESUF): tests/check-qjson.o $(test-util-obj-y)
|
||||
tests/check-qom-interface$(EXESUF): tests/check-qom-interface.o $(test-qom-obj-y)
|
||||
tests/check-qom-proplist$(EXESUF): tests/check-qom-proplist.o $(test-qom-obj-y)
|
||||
tests/check-qom-props$(EXESUF): tests/check-qom-props.o $(test-qom-obj-y)
|
||||
|
||||
tests/test-char$(EXESUF): tests/test-char.o qemu-char.o qemu-timer.o $(test-util-obj-y) $(qtest-obj-y) $(test-io-obj-y)
|
||||
tests/test-coroutine$(EXESUF): tests/test-coroutine.o $(test-block-obj-y)
|
||||
@@ -679,6 +684,7 @@ tests/usb-hcd-xhci-test$(EXESUF): tests/usb-hcd-xhci-test.o $(libqos-usb-obj-y)
|
||||
tests/pc-cpu-test$(EXESUF): tests/pc-cpu-test.o
|
||||
tests/postcopy-test$(EXESUF): tests/postcopy-test.o
|
||||
tests/vhost-user-test$(EXESUF): tests/vhost-user-test.o qemu-char.o qemu-timer.o $(qtest-obj-y) $(test-io-obj-y) $(libqos-virtio-obj-y) $(libqos-pc-obj-y)
|
||||
tests/scsi-disk-test$(EXESUF): tests/scsi-disk-test.o
|
||||
tests/qemu-iotests/socket_scm_helper$(EXESUF): tests/qemu-iotests/socket_scm_helper.o
|
||||
tests/test-qemu-opts$(EXESUF): tests/test-qemu-opts.o $(test-util-obj-y)
|
||||
tests/test-write-threshold$(EXESUF): tests/test-write-threshold.o $(test-block-obj-y)
|
||||
|
122
tests/check-qom-props.c
Normal file
122
tests/check-qom-props.c
Normal file
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Red Hat, Inc.
|
||||
* Copyright (c) 2015 SUSE Linux GmbH
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Daniel P. Berrange <berrange@redhat.com>
|
||||
* Andreas Färber <afaerber@suse.com>
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include "qapi/visitor.h"
|
||||
#include "qom/object.h"
|
||||
#include "qemu/module.h"
|
||||
|
||||
|
||||
#define TYPE_DUMMY "qemu-dummy"
|
||||
|
||||
typedef struct DummyObject DummyObject;
|
||||
typedef struct DummyObjectClass DummyObjectClass;
|
||||
|
||||
#define DUMMY_OBJECT(obj) \
|
||||
OBJECT_CHECK(DummyObject, (obj), TYPE_DUMMY)
|
||||
|
||||
struct DummyObject {
|
||||
Object parent_obj;
|
||||
|
||||
uint64_t u64val;
|
||||
};
|
||||
|
||||
struct DummyObjectClass {
|
||||
ObjectClass parent_class;
|
||||
};
|
||||
|
||||
static void dummy_set_uint64(Object *obj, Visitor *v,
|
||||
const char *name, void *opaque,
|
||||
Error **errp)
|
||||
{
|
||||
uint64_t *ptr = (uint64_t *)opaque;
|
||||
|
||||
visit_type_uint64(v, name, ptr, errp);
|
||||
}
|
||||
|
||||
static void dummy_get_uint64(Object *obj, Visitor *v,
|
||||
const char *name, void *opaque,
|
||||
Error **errp)
|
||||
{
|
||||
uint64_t value = *(uint64_t *)opaque;
|
||||
|
||||
visit_type_uint64(v, name, &value, errp);
|
||||
}
|
||||
|
||||
static void dummy_init(Object *obj)
|
||||
{
|
||||
DummyObject *dobj = DUMMY_OBJECT(obj);
|
||||
|
||||
object_property_add(obj, "u64val", "uint64",
|
||||
dummy_get_uint64,
|
||||
dummy_set_uint64,
|
||||
NULL, &dobj->u64val, NULL);
|
||||
}
|
||||
|
||||
|
||||
static const TypeInfo dummy_info = {
|
||||
.name = TYPE_DUMMY,
|
||||
.parent = TYPE_OBJECT,
|
||||
.instance_size = sizeof(DummyObject),
|
||||
.instance_init = dummy_init,
|
||||
.class_size = sizeof(DummyObjectClass),
|
||||
};
|
||||
|
||||
static void test_dummy_uint64(void)
|
||||
{
|
||||
Error *err = NULL;
|
||||
char *str;
|
||||
DummyObject *dobj = DUMMY_OBJECT(object_new(TYPE_DUMMY));
|
||||
|
||||
g_assert(dobj->u64val == 0);
|
||||
|
||||
str = g_strdup_printf("%" PRIu64, UINT64_MAX);
|
||||
object_property_parse(OBJECT(dobj), str, "u64val", &err);
|
||||
g_free(str);
|
||||
g_assert(!err);
|
||||
g_assert_cmpint(dobj->u64val, ==, UINT64_MAX);
|
||||
|
||||
dobj->u64val = 0;
|
||||
str = g_strdup_printf("0x%" PRIx64, UINT64_MAX);
|
||||
object_property_parse(OBJECT(dobj), str, "u64val", &err);
|
||||
g_free(str);
|
||||
g_assert(!err);
|
||||
g_assert_cmpint(dobj->u64val, ==, UINT64_MAX);
|
||||
|
||||
object_unref(OBJECT(dobj));
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
g_test_init(&argc, &argv, NULL);
|
||||
|
||||
module_call_init(MODULE_INIT_QOM);
|
||||
type_register_static(&dummy_info);
|
||||
|
||||
g_test_add_func("/qom/props/uint64", test_dummy_uint64);
|
||||
|
||||
return g_test_run();
|
||||
}
|
82
tests/scsi-disk-test.c
Normal file
82
tests/scsi-disk-test.c
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* QTest testcase for SCSI disks
|
||||
* See virtio-scsi-test for more integrated tests.
|
||||
*
|
||||
* Copyright (c) 2015 SUSE Linux GmbH
|
||||
*
|
||||
* This work is licensed under the terms of the GNU GPL, version 2 or later.
|
||||
* See the COPYING file in the top-level directory.
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include <glib.h>
|
||||
#include "libqtest.h"
|
||||
#include "qapi/qmp/qint.h"
|
||||
|
||||
static void test_scsi_disk_common(const char *type, const char *id)
|
||||
{
|
||||
char *cmdline, *path;
|
||||
QDict *response;
|
||||
QInt *value;
|
||||
|
||||
cmdline = g_strdup_printf(
|
||||
"-drive id=drv0,if=none,file=/dev/null,format=raw "
|
||||
"-device virtio-scsi-pci,id=scsi0 "
|
||||
"-device %s,id=%s,bus=scsi0.0,drive=drv0"
|
||||
",wwn=0x%" PRIx64 ",port_wwn=0x%" PRIx64,
|
||||
type, id, UINT64_MAX, UINT64_C(1) << 63);
|
||||
qtest_start(cmdline);
|
||||
g_free(cmdline);
|
||||
|
||||
path = g_strdup_printf("/machine/peripheral/%s", id);
|
||||
|
||||
response = qmp("{ 'execute': 'qom-get',"
|
||||
" 'arguments': { 'path': %s,"
|
||||
" 'property': 'wwn' } }",
|
||||
path);
|
||||
g_assert(response);
|
||||
g_assert(qdict_haskey(response, "return"));
|
||||
value = qobject_to_qint(qdict_get(response, "return"));
|
||||
g_assert_cmpint(qint_get_int(value), ==, UINT64_MAX);
|
||||
|
||||
response = qmp("{ 'execute': 'qom-get',"
|
||||
" 'arguments': { 'path': %s,"
|
||||
" 'property': 'port_wwn' } }",
|
||||
path);
|
||||
g_assert(response);
|
||||
g_assert(qdict_haskey(response, "return"));
|
||||
value = qobject_to_qint(qdict_get(response, "return"));
|
||||
g_assert_cmpint(qint_get_int(value), ==, UINT64_C(1) << 63);
|
||||
|
||||
g_free(path);
|
||||
qtest_end();
|
||||
}
|
||||
|
||||
static void test_scsi_disk(void)
|
||||
{
|
||||
test_scsi_disk_common("scsi-disk", "disk0");
|
||||
}
|
||||
|
||||
static void test_scsi_hd(void)
|
||||
{
|
||||
test_scsi_disk_common("scsi-hd", "hd0");
|
||||
}
|
||||
|
||||
static void test_scsi_cd(void)
|
||||
{
|
||||
test_scsi_disk_common("scsi-cd", "cd0");
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
g_test_init(&argc, &argv, NULL);
|
||||
qtest_add_func("/scsi-disk/props", test_scsi_disk);
|
||||
qtest_add_func("/scsi-hd/props", test_scsi_hd);
|
||||
qtest_add_func("/scsi-cd/props", test_scsi_cd);
|
||||
|
||||
ret = g_test_run();
|
||||
|
||||
return ret;
|
||||
}
|
@@ -924,7 +924,9 @@ int main(int argc, char **argv)
|
||||
g_test_add_data_func("/qga/info", &fix, test_qga_info);
|
||||
g_test_add_data_func("/qga/network-get-interfaces", &fix,
|
||||
test_qga_network_get_interfaces);
|
||||
g_test_add_data_func("/qga/get-vcpus", &fix, test_qga_get_vcpus);
|
||||
if (!access("/sys/devices/system/cpu/cpu0", F_OK)) {
|
||||
g_test_add_data_func("/qga/get-vcpus", &fix, test_qga_get_vcpus);
|
||||
}
|
||||
g_test_add_data_func("/qga/get-fsinfo", &fix, test_qga_get_fsinfo);
|
||||
g_test_add_data_func("/qga/get-memory-block-info", &fix,
|
||||
test_qga_get_memory_block_info);
|
||||
|
@@ -53,6 +53,14 @@ static void test_visitor_in_int(TestInputVisitorData *data,
|
||||
|
||||
v = visitor_input_test_init(data, "-42");
|
||||
|
||||
visit_type_int(v, NULL, &res, &err);
|
||||
g_assert(!err);
|
||||
g_assert_cmpint(res, ==, value);
|
||||
visitor_input_teardown(data, unused);
|
||||
|
||||
value = INT64_MAX;
|
||||
v = visitor_input_test_init(data, g_strdup_printf("%" PRId64, value));
|
||||
|
||||
visit_type_int(v, NULL, &res, &err);
|
||||
g_assert(!err);
|
||||
g_assert_cmpint(res, ==, value);
|
||||
@@ -65,6 +73,27 @@ static void test_visitor_in_int(TestInputVisitorData *data,
|
||||
error_free_or_abort(&err);
|
||||
}
|
||||
|
||||
static void test_visitor_in_uint64(TestInputVisitorData *data,
|
||||
const void *unused)
|
||||
{
|
||||
uint64_t res = 0, value = UINT64_MAX;
|
||||
Error *err = NULL;
|
||||
Visitor *v;
|
||||
|
||||
v = visitor_input_test_init(data, g_strdup_printf("%" PRIu64, value));
|
||||
|
||||
visit_type_uint64(v, NULL, &res, &err);
|
||||
g_assert(!err);
|
||||
g_assert_cmpint(res, ==, value);
|
||||
visitor_input_teardown(data, unused);
|
||||
|
||||
v = visitor_input_test_init(data, g_strdup_printf("0x%" PRIx64, value));
|
||||
|
||||
visit_type_uint64(v, NULL, &res, &err);
|
||||
g_assert(!err);
|
||||
g_assert_cmpint(res, ==, value);
|
||||
}
|
||||
|
||||
static void test_visitor_in_intList(TestInputVisitorData *data,
|
||||
const void *unused)
|
||||
{
|
||||
@@ -267,6 +296,8 @@ int main(int argc, char **argv)
|
||||
|
||||
input_visitor_test_add("/string-visitor/input/int",
|
||||
&in_visitor_data, test_visitor_in_int);
|
||||
input_visitor_test_add("/string-visitor/input/uint64",
|
||||
&in_visitor_data, test_visitor_in_uint64);
|
||||
input_visitor_test_add("/string-visitor/input/intList",
|
||||
&in_visitor_data, test_visitor_in_intList);
|
||||
input_visitor_test_add("/string-visitor/input/bool",
|
||||
|
@@ -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
21
thunk.c
@@ -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);
|
||||
|
@@ -869,7 +869,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);
|
||||
|
74
ui/vnc.c
74
ui/vnc.c
@@ -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);
|
||||
|
||||
@@ -1201,6 +1203,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 */
|
||||
|
||||
@@ -1251,6 +1254,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)
|
||||
@@ -1760,6 +1770,25 @@ static void do_key_event(VncState *vs, int down, int keycode, int sym)
|
||||
if (down)
|
||||
vs->modifiers_state[keycode] ^= 1;
|
||||
break;
|
||||
default:
|
||||
if (qemu_console_is_graphic(NULL)) {
|
||||
/* record key 'down' info. Some client like tigervnc
|
||||
* will send key down repeatedly if user pressing a
|
||||
* a key for long time. In this case, we should add
|
||||
* additional key up event before repeated key down,
|
||||
* so that it can display the key multiple times.
|
||||
*/
|
||||
if (down) {
|
||||
if (vs->modifiers_state[keycode]) {
|
||||
/* add a key up event */
|
||||
do_key_event(vs, 0, keycode, sym);
|
||||
}
|
||||
vs->modifiers_state[keycode] = 1;
|
||||
} else {
|
||||
vs->modifiers_state[keycode] = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Turn off the lock state sync logic if the client support the led
|
||||
@@ -3244,6 +3273,39 @@ static void vnc_display_print_local_addr(VncDisplay *vd)
|
||||
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),
|
||||
@@ -3274,6 +3336,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,
|
||||
@@ -3286,6 +3351,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,
|
||||
@@ -3486,6 +3554,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;
|
||||
@@ -3615,6 +3684,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);
|
||||
@@ -3704,6 +3777,7 @@ void vnc_display_open(const char *id, Error **errp)
|
||||
vd->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
|
||||
}
|
||||
vd->connections_limit = qemu_opt_get_number(opts, "connections", 32);
|
||||
allowed_connections = qemu_opt_get_number(opts, "allowed-connections", 0);
|
||||
|
||||
#ifdef CONFIG_VNC_JPEG
|
||||
vd->lossy = qemu_opt_get_bool(opts, "lossy", false);
|
||||
|
@@ -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)) {
|
||||
|
21
vl.c
21
vl.c
@@ -26,6 +26,7 @@
|
||||
#include "qemu/cutils.h"
|
||||
#include "qemu/help_option.h"
|
||||
#include "qemu/uuid.h"
|
||||
#include <sys/resource.h>
|
||||
|
||||
#ifdef CONFIG_SECCOMP
|
||||
#include "sysemu/seccomp.h"
|
||||
@@ -162,6 +163,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;
|
||||
@@ -3030,6 +3032,7 @@ int main(int argc, char **argv, char **envp)
|
||||
Error *main_loop_err = NULL;
|
||||
Error *err = NULL;
|
||||
bool list_data_dirs = false;
|
||||
struct rlimit rlimit_as;
|
||||
|
||||
module_call_init(MODULE_INIT_TRACE);
|
||||
|
||||
@@ -3037,6 +3040,16 @@ int main(int argc, char **argv, char **envp)
|
||||
qemu_init_cpu_loop();
|
||||
qemu_mutex_lock_iothread();
|
||||
|
||||
/*
|
||||
* Try to raise the soft address space limit.
|
||||
* Default on SLES 11 SP2 is 80% of physical+swap memory.
|
||||
*/
|
||||
getrlimit(RLIMIT_AS, &rlimit_as);
|
||||
if (rlimit_as.rlim_cur < rlimit_as.rlim_max) {
|
||||
rlimit_as.rlim_cur = rlimit_as.rlim_max;
|
||||
setrlimit(RLIMIT_AS, &rlimit_as);
|
||||
}
|
||||
|
||||
atexit(qemu_run_exit_notifiers);
|
||||
error_set_progname(argv[0]);
|
||||
qemu_init_exec_dir(argv[0]);
|
||||
@@ -3437,6 +3450,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;
|
||||
|
Reference in New Issue
Block a user