Compare commits
74 Commits
python-nex
...
opensuse-1
Author | SHA1 | Date | |
---|---|---|---|
|
712271e21a | ||
|
7a423c1afd | ||
|
2b59d86cc1 | ||
|
7a0fbb2149 | ||
|
19c04c8cf5 | ||
|
6ad8ca6765 | ||
|
9503d039b2 | ||
|
41641ce4e5 | ||
|
6897c46882 | ||
|
c144bbfb2e | ||
|
55b40bcdc4 | ||
|
399781985e | ||
|
21ec069779 | ||
|
5c50df3458 | ||
|
be603e808e | ||
|
ba212d0628 | ||
|
fb44bccb2b | ||
|
e2259d5793 | ||
|
da3c3b83e0 | ||
|
890e0b2cf5 | ||
|
849a5d15f2 | ||
|
2cf41ff75a | ||
|
aa3dc18512 | ||
|
8137fc352d | ||
|
bcef1d17e9 | ||
|
b34244cfd6 | ||
|
941a2202e1 | ||
|
6129f046f7 | ||
|
1b71cc7ca0 | ||
|
d25cda59f2 | ||
|
84e839136f | ||
|
1a53708166 | ||
|
cc67cf446c | ||
|
8014305898 | ||
|
a6b483c31c | ||
|
6d52ff37b5 | ||
|
13795190e7 | ||
|
1125720b47 | ||
|
e00f3ed887 | ||
|
3f30407eb5 | ||
|
033bf37384 | ||
|
07ae122b6a | ||
|
6197cf31be | ||
|
665ce82fd8 | ||
|
04024dea26 | ||
|
1bd4397e8d | ||
|
e76672424d | ||
|
df50a7e0cb | ||
|
90c96d33c4 | ||
|
4ee28799d4 | ||
|
563068a8b2 | ||
|
cdb483457c | ||
|
9d173df553 | ||
|
204dd38c2d | ||
|
86bab45948 | ||
|
006c747440 | ||
|
f042cca009 | ||
|
1205b8080f | ||
|
ff0c079c14 | ||
|
d745511fc9 | ||
|
5afd0ecaa6 | ||
|
c4cd5b0f6d | ||
|
7ca2496588 | ||
|
bfae9374f1 | ||
|
b68c48ff01 | ||
|
36fd8179b6 | ||
|
0bc5f4ad63 | ||
|
37e1428cc7 | ||
|
518799a3e7 | ||
|
16c5fe49de | ||
|
f1a2195ec3 | ||
|
3b4fc1f9d2 | ||
|
d67d95f24e | ||
|
0a7ad69a0f |
@@ -31,6 +31,10 @@ PROGS+=$(QEMU_PROGW)
|
||||
endif
|
||||
STPFILES=
|
||||
|
||||
ifdef CONFIG_LINUX_USER
|
||||
PROGS+=$(QEMU_PROG)-binfmt
|
||||
endif
|
||||
|
||||
ifndef CONFIG_HAIKU
|
||||
LIBS+=-lm
|
||||
endif
|
||||
@@ -87,6 +91,8 @@ QEMU_CFLAGS+=-I$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR) -I$(SRC_PATH)/linux-user
|
||||
obj-y += linux-user/
|
||||
obj-y += gdbstub.o thunk.o user-exec.o $(oslib-obj-y)
|
||||
|
||||
obj-binfmt-y += linux-user/
|
||||
|
||||
endif #CONFIG_LINUX_USER
|
||||
|
||||
#########################################################
|
||||
@@ -147,6 +153,9 @@ endif # CONFIG_SOFTMMU
|
||||
%/translate.o: QEMU_CFLAGS += $(TRANSLATE_OPT_CFLAGS)
|
||||
|
||||
nested-vars += obj-y
|
||||
ifdef CONFIG_LINUX_USER
|
||||
nested-vars += obj-binfmt-y
|
||||
endif
|
||||
|
||||
# This resolves all nested paths, so it must come last
|
||||
include $(SRC_PATH)/Makefile.objs
|
||||
@@ -174,6 +183,9 @@ $(QEMU_PROG): $(all-obj-y) ../libqemustub.a
|
||||
$(call LINK,$^)
|
||||
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)$@")
|
||||
|
||||
|
@@ -264,5 +264,6 @@ bool aio_poll(AioContext *ctx, bool blocking)
|
||||
}
|
||||
}
|
||||
|
||||
return progress;
|
||||
assert(progress || busy);
|
||||
return true;
|
||||
}
|
||||
|
@@ -214,5 +214,6 @@ bool aio_poll(AioContext *ctx, bool blocking)
|
||||
events[ret - WAIT_OBJECT_0] = events[--count];
|
||||
}
|
||||
|
||||
return progress;
|
||||
assert(progress || busy);
|
||||
return true;
|
||||
}
|
||||
|
18
arch_init.c
18
arch_init.c
@@ -535,9 +535,13 @@ static void sort_ram_list(void)
|
||||
|
||||
static void migration_end(void)
|
||||
{
|
||||
memory_global_dirty_log_stop();
|
||||
if (migration_bitmap) {
|
||||
memory_global_dirty_log_stop();
|
||||
g_free(migration_bitmap);
|
||||
migration_bitmap = NULL;
|
||||
}
|
||||
|
||||
if (migrate_use_xbzrle()) {
|
||||
if (XBZRLE.cache) {
|
||||
cache_fini(XBZRLE.cache);
|
||||
g_free(XBZRLE.cache);
|
||||
g_free(XBZRLE.encoded_buf);
|
||||
@@ -568,7 +572,7 @@ static int ram_save_setup(QEMUFile *f, void *opaque)
|
||||
int64_t ram_pages = last_ram_offset() >> TARGET_PAGE_BITS;
|
||||
|
||||
migration_bitmap = bitmap_new(ram_pages);
|
||||
bitmap_set(migration_bitmap, 1, ram_pages);
|
||||
bitmap_set(migration_bitmap, 0, ram_pages);
|
||||
migration_dirty_pages = ram_pages;
|
||||
|
||||
bytes_transferred = 0;
|
||||
@@ -689,13 +693,10 @@ static int ram_save_complete(QEMUFile *f, void *opaque)
|
||||
}
|
||||
bytes_transferred += bytes_sent;
|
||||
}
|
||||
memory_global_dirty_log_stop();
|
||||
migration_end();
|
||||
|
||||
qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
|
||||
|
||||
g_free(migration_bitmap);
|
||||
migration_bitmap = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -840,7 +841,8 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id)
|
||||
memset(host, ch, TARGET_PAGE_SIZE);
|
||||
#ifndef _WIN32
|
||||
if (ch == 0 &&
|
||||
(!kvm_enabled() || kvm_has_sync_mmu())) {
|
||||
(!kvm_enabled() || kvm_has_sync_mmu()) &&
|
||||
getpagesize() <= TARGET_PAGE_SIZE) {
|
||||
qemu_madvise(host, TARGET_PAGE_SIZE, QEMU_MADV_DONTNEED);
|
||||
}
|
||||
#endif
|
||||
|
5
block.c
5
block.c
@@ -4413,7 +4413,7 @@ int bdrv_img_create(const char *filename, const char *fmt,
|
||||
char *options, uint64_t img_size, int flags)
|
||||
{
|
||||
QEMUOptionParameter *param = NULL, *create_options = NULL;
|
||||
QEMUOptionParameter *backing_fmt, *backing_file, *size;
|
||||
QEMUOptionParameter *backing_fmt, *backing_file, *size, *scsi;
|
||||
BlockDriverState *bs = NULL;
|
||||
BlockDriver *drv, *proto_drv;
|
||||
BlockDriver *backing_drv = NULL;
|
||||
@@ -4528,6 +4528,9 @@ int bdrv_img_create(const char *filename, const char *fmt,
|
||||
|
||||
printf("Formatting '%s', fmt=%s ", filename, fmt);
|
||||
print_option_parameters(param);
|
||||
scsi = get_option_parameter(param, BLOCK_OPT_SCSI);
|
||||
if (scsi && scsi->value.n)
|
||||
printf(", SCSI");
|
||||
puts("");
|
||||
|
||||
ret = bdrv_create(drv, filename, param);
|
||||
|
@@ -18,3 +18,5 @@ endif
|
||||
common-obj-y += stream.o
|
||||
common-obj-y += commit.o
|
||||
common-obj-y += mirror.o
|
||||
common-obj-y += dictzip.o
|
||||
common-obj-y += tar.o
|
||||
|
566
block/dictzip.c
Normal file
566
block/dictzip.c
Normal file
@@ -0,0 +1,566 @@
|
||||
/*
|
||||
* 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-common.h"
|
||||
#include "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 {
|
||||
BlockDriverAIOCB 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 dictzip_probe(const uint8_t *buf, int buf_size, const char *filename)
|
||||
{
|
||||
if (buf_size < 2)
|
||||
return 0;
|
||||
|
||||
/* We match on every gzip file */
|
||||
if ((buf[0] == GZ_MAGIC1) && (buf[1] == GZ_MAGIC2))
|
||||
return 100;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 int dictzip_open(BlockDriverState *bs, const char *filename, int flags)
|
||||
{
|
||||
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;
|
||||
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;
|
||||
const char *fname = filename;
|
||||
|
||||
if (!strncmp(filename, "dzip://", 7))
|
||||
fname += 7;
|
||||
else if (!strncmp(filename, "dzip:", 5))
|
||||
fname += 5;
|
||||
|
||||
ret = bdrv_file_open(&s->hd, fname, flags);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* initialize zlib streams */
|
||||
for (i = 0; i < Z_STREAM_COUNT; i++) {
|
||||
if (start_zStream( &s->zStream[i] ) != Z_OK) {
|
||||
err = s->zStream[i].msg;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
/* gzip header */
|
||||
if (bdrv_pread(s->hd, GZ_ID, &magic, sizeof(magic)) != sizeof(magic))
|
||||
goto fail;
|
||||
|
||||
if (!((magic[0] == GZ_MAGIC1) && (magic[1] == GZ_MAGIC2))) {
|
||||
err = "No gzip file";
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* dzip header */
|
||||
if (bdrv_pread(s->hd, GZ_FLG, &header_flags, 1) != 1)
|
||||
goto fail;
|
||||
|
||||
if (!(header_flags & GZ_FEXTRA)) {
|
||||
err = "Not a dictzip file (wrong flags)";
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* extra length */
|
||||
if (bdrv_pread(s->hd, GZ_XLEN, &tmp_short, 2) != 2)
|
||||
goto fail;
|
||||
|
||||
headerLength += le16_to_cpu(tmp_short) + 2;
|
||||
|
||||
/* DictZip magic */
|
||||
if (bdrv_pread(s->hd, GZ_SI, &magic, 2) != 2)
|
||||
goto fail;
|
||||
|
||||
if (magic[0] != DZ_MAGIC1 || magic[1] != DZ_MAGIC2) {
|
||||
err = "Not a dictzip file (missing extra magic)";
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* DictZip version */
|
||||
if (bdrv_pread(s->hd, GZ_VERSION, &header_ver, 2) != 2)
|
||||
goto fail;
|
||||
|
||||
header_ver = le16_to_cpu(header_ver);
|
||||
|
||||
switch (header_ver) {
|
||||
case 1: /* Normal DictZip */
|
||||
/* number of chunks */
|
||||
if (bdrv_pread(s->hd, GZ_CHUNKSIZE, &chunk_len16, 2) != 2)
|
||||
goto fail;
|
||||
|
||||
s->chunk_len = le16_to_cpu(chunk_len16);
|
||||
|
||||
/* chunk count */
|
||||
if (bdrv_pread(s->hd, GZ_CHUNKCNT, &chunk_cnt16, 2) != 2)
|
||||
goto fail;
|
||||
|
||||
s->chunk_cnt = le16_to_cpu(chunk_cnt16);
|
||||
chunks_len = sizeof(short) * s->chunk_cnt;
|
||||
rnd_offs = GZ_RNDDATA;
|
||||
break;
|
||||
case 99: /* Special Alex pigz version */
|
||||
/* number of chunks */
|
||||
if (bdrv_pread(s->hd, GZ_99_CHUNKSIZE, &s->chunk_len, 4) != 4)
|
||||
goto fail;
|
||||
|
||||
dprintf("chunk len [%#x] = %d\n", GZ_99_CHUNKSIZE, s->chunk_len);
|
||||
s->chunk_len = le32_to_cpu(s->chunk_len);
|
||||
|
||||
/* chunk count */
|
||||
if (bdrv_pread(s->hd, GZ_99_CHUNKCNT, &s->chunk_cnt, 4) != 4)
|
||||
goto fail;
|
||||
|
||||
s->chunk_cnt = le32_to_cpu(s->chunk_cnt);
|
||||
|
||||
dprintf("chunk len | count = %d | %d\n", s->chunk_len, s->chunk_cnt);
|
||||
|
||||
/* file size */
|
||||
if (bdrv_pread(s->hd, GZ_99_FILESIZE, &s->file_len, 8) != 8)
|
||||
goto fail;
|
||||
|
||||
s->file_len = le64_to_cpu(s->file_len);
|
||||
chunks_len = sizeof(int) * s->chunk_cnt;
|
||||
rnd_offs = GZ_99_RNDDATA;
|
||||
break;
|
||||
default:
|
||||
err = "Invalid DictZip version";
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* random access data */
|
||||
s->chunks = g_malloc(chunks_len);
|
||||
if (header_ver == 99)
|
||||
s->chunks32 = (uint32_t *)s->chunks;
|
||||
|
||||
if (bdrv_pread(s->hd, rnd_offs, s->chunks, chunks_len) != chunks_len)
|
||||
goto fail;
|
||||
|
||||
/* orig filename */
|
||||
if (header_flags & GZ_FNAME) {
|
||||
if (bdrv_pread(s->hd, headerLength + 1, buf, sizeof(buf)) != sizeof(buf))
|
||||
goto fail;
|
||||
|
||||
buf[sizeof(buf) - 1] = '\0';
|
||||
headerLength += strlen(buf) + 1;
|
||||
|
||||
if (strlen(buf) == sizeof(buf))
|
||||
goto fail;
|
||||
|
||||
dprintf("filename: %s\n", buf);
|
||||
}
|
||||
|
||||
/* comment field */
|
||||
if (header_flags & GZ_COMMENT) {
|
||||
if (bdrv_pread(s->hd, headerLength, buf, sizeof(buf)) != sizeof(buf))
|
||||
goto fail;
|
||||
|
||||
buf[sizeof(buf) - 1] = '\0';
|
||||
headerLength += strlen(buf) + 1;
|
||||
|
||||
if (strlen(buf) == sizeof(buf))
|
||||
goto fail;
|
||||
|
||||
dprintf("comment: %s\n", buf);
|
||||
}
|
||||
|
||||
if (header_flags & GZ_FHCRC)
|
||||
headerLength += 2;
|
||||
|
||||
/* uncompressed file length*/
|
||||
if (!s->file_len) {
|
||||
uint32_t file_len;
|
||||
|
||||
if (bdrv_pread(s->hd, bdrv_getlength(s->hd) - 4, &file_len, 4) != 4)
|
||||
goto fail;
|
||||
|
||||
s->file_len = le32_to_cpu(file_len);
|
||||
}
|
||||
|
||||
/* compute offsets */
|
||||
s->offsets = g_malloc(sizeof( *s->offsets ) * s->chunk_cnt);
|
||||
|
||||
for (offset = headerLength + 1, i = 0; i < s->chunk_cnt; i++) {
|
||||
s->offsets[i] = offset;
|
||||
switch (header_ver) {
|
||||
case 1:
|
||||
offset += s->chunks[i];
|
||||
break;
|
||||
case 99:
|
||||
offset += s->chunks32[i];
|
||||
break;
|
||||
}
|
||||
|
||||
dprintf("chunk %#x - %#x = offset %#x -> %#x\n", i * s->chunk_len, (i+1) * s->chunk_len, s->offsets[i], offset);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
fprintf(stderr, "DictZip: Error opening file: %s\n", err);
|
||||
bdrv_delete(s->hd);
|
||||
if (s->chunks)
|
||||
g_free(s->chunks);
|
||||
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_release(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;
|
||||
|
||||
buf = g_malloc(acb->chunks_len);
|
||||
|
||||
/* 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_release(acb);
|
||||
}
|
||||
|
||||
static void dictzip_aio_cancel(BlockDriverAIOCB *blockacb)
|
||||
{
|
||||
}
|
||||
|
||||
static const AIOCBInfo dictzip_aiocb_info = {
|
||||
.aiocb_size = sizeof(DictZipAIOCB),
|
||||
.cancel = dictzip_aio_cancel,
|
||||
};
|
||||
|
||||
/* This is where we get a request from a caller to read something */
|
||||
static BlockDriverAIOCB *dictzip_aio_readv(BlockDriverState *bs,
|
||||
int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
|
||||
BlockDriverCompletionFunc *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 */
|
||||
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);
|
||||
|
||||
/* 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 += s->chunks32[i];
|
||||
else
|
||||
gz_len += 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 %d - %d => %d - %d\n", start, end, gz_start, gz_start + gz_len);
|
||||
|
||||
acb->s = s;
|
||||
acb->qiov = qiov;
|
||||
acb->qiov_gz = qiov_gz;
|
||||
acb->start = start;
|
||||
acb->len = len;
|
||||
acb->gzipped = buf + (gz_start % SECTOR_SIZE);
|
||||
acb->gz_len = gz_len;
|
||||
acb->gz_start = first_chunk * s->chunk_len;
|
||||
acb->offset = first_offset;
|
||||
acb->chunks_len = (last_chunk - first_chunk + 1) * s->chunk_len;
|
||||
|
||||
return bdrv_aio_readv(s->hd, gz_sector_num, qiov_gz, gz_nb_sectors,
|
||||
dictzip_read_cb, acb);
|
||||
}
|
||||
|
||||
static void dictzip_close(BlockDriverState *bs)
|
||||
{
|
||||
BDRVDictZipState *s = bs->opaque;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CACHE_COUNT; i++) {
|
||||
if (!s->cache[i].len)
|
||||
continue;
|
||||
|
||||
g_free(s->cache[i].buf);
|
||||
}
|
||||
|
||||
for (i = 0; i < Z_STREAM_COUNT; i++) {
|
||||
inflateEnd(&s->zStream[i]);
|
||||
}
|
||||
|
||||
if (s->chunks)
|
||||
g_free(s->chunks);
|
||||
|
||||
if (s->offsets)
|
||||
g_free(s->offsets);
|
||||
|
||||
dprintf("Close\n");
|
||||
}
|
||||
|
||||
static int64_t dictzip_getlength(BlockDriverState *bs)
|
||||
{
|
||||
BDRVDictZipState *s = bs->opaque;
|
||||
dprintf("getlength -> %ld\n", s->file_len);
|
||||
return s->file_len;
|
||||
}
|
||||
|
||||
static BlockDriver bdrv_dictzip = {
|
||||
.format_name = "dzip",
|
||||
.protocol_name = "dzip",
|
||||
|
||||
.instance_size = sizeof(BDRVDictZipState),
|
||||
.bdrv_file_open = dictzip_open,
|
||||
.bdrv_close = dictzip_close,
|
||||
.bdrv_getlength = dictzip_getlength,
|
||||
.bdrv_probe = dictzip_probe,
|
||||
|
||||
.bdrv_aio_readv = dictzip_aio_readv,
|
||||
};
|
||||
|
||||
static void dictzip_block_init(void)
|
||||
{
|
||||
bdrv_register(&bdrv_dictzip);
|
||||
}
|
||||
|
||||
block_init(dictzip_block_init);
|
@@ -456,15 +456,7 @@ static ssize_t handle_aiocb_ioctl(RawPosixAIOData *aiocb)
|
||||
return -errno;
|
||||
}
|
||||
|
||||
/*
|
||||
* This looks weird, but the aio code only considers a request
|
||||
* successful if it has written the full number of bytes.
|
||||
*
|
||||
* Now we overload aio_nbytes as aio_ioctl_cmd for the ioctl command,
|
||||
* so in fact we return the ioctl command here to make posix_aio_read()
|
||||
* happy..
|
||||
*/
|
||||
return aiocb->aio_nbytes;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t handle_aiocb_flush(RawPosixAIOData *aiocb)
|
||||
|
365
block/tar.c
Normal file
365
block/tar.c
Normal file
@@ -0,0 +1,365 @@
|
||||
/*
|
||||
* 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-common.h"
|
||||
#include "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 tar_probe(const uint8_t *buf, int buf_size, const char *filename)
|
||||
{
|
||||
if (buf_size < OFFS_MAGIC + 5)
|
||||
return 0;
|
||||
|
||||
/* we only support newer tar */
|
||||
if (!strncmp((char*)buf + OFFS_MAGIC, POSIX_TAR_MAGIC, 5))
|
||||
return 100;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 int tar_open(BlockDriverState *bs, const char *filename, int flags)
|
||||
{
|
||||
BDRVTarState *s = bs->opaque;
|
||||
char header[SECTOR_SIZE];
|
||||
char *real_file = header;
|
||||
char *magic;
|
||||
const char *fname = filename;
|
||||
size_t header_offs = 0;
|
||||
int ret;
|
||||
|
||||
if (!strncmp(filename, "tar://", 6))
|
||||
fname += 6;
|
||||
else if (!strncmp(filename, "tar:", 4))
|
||||
fname += 4;
|
||||
|
||||
ret = bdrv_file_open(&s->hd, fname, flags);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Search the file for an image */
|
||||
|
||||
do {
|
||||
/* tar header */
|
||||
if (bdrv_pread(s->hd, header_offs, header, SECTOR_SIZE) != SECTOR_SIZE)
|
||||
goto fail;
|
||||
|
||||
if ((header_offs > 1) && !header[0]) {
|
||||
fprintf(stderr, "Tar: No image file found in archive\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
magic = &header[OFFS_MAGIC];
|
||||
if (strncmp(magic, POSIX_TAR_MAGIC, 5)) {
|
||||
fprintf(stderr, "Tar: Invalid magic: %s\n", magic);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
dprintf("file type: %c\n", header[OFFS_TYPE]);
|
||||
|
||||
/* file length*/
|
||||
s->file_len = (tar2u64(&header[OFFS_LENGTH]) + (SECTOR_SIZE - 1)) &
|
||||
~(SECTOR_SIZE - 1);
|
||||
s->file_sec = (header_offs / SECTOR_SIZE) + 1;
|
||||
|
||||
header_offs += s->file_len + SECTOR_SIZE;
|
||||
|
||||
if (header[OFFS_TYPE] == 'L') {
|
||||
bdrv_pread(s->hd, header_offs - s->file_len, s->longfile,
|
||||
sizeof(s->longfile));
|
||||
s->longfile[sizeof(s->longfile)-1] = '\0';
|
||||
real_file = header;
|
||||
} else if (s->longfile[0]) {
|
||||
real_file = s->longfile;
|
||||
} else {
|
||||
real_file = header;
|
||||
}
|
||||
} while(!is_target_file(bs, real_file, header));
|
||||
|
||||
/* We found an image! */
|
||||
|
||||
if (header[OFFS_TYPE] == 'S') {
|
||||
uint8_t isextended;
|
||||
int i;
|
||||
|
||||
for (i = OFFS_S_SP; i < (OFFS_S_SP + (4 * 24)); i += 24)
|
||||
tar_sparse(s, tar2u64(&header[i]), tar2u64(&header[i+12]));
|
||||
|
||||
s->file_len = tar2u64(&header[OFFS_S_LENGTH]);
|
||||
isextended = header[OFFS_S_EXT];
|
||||
|
||||
while (isextended) {
|
||||
if (bdrv_pread(s->hd, s->file_sec * SECTOR_SIZE, header,
|
||||
SECTOR_SIZE) != SECTOR_SIZE)
|
||||
goto fail;
|
||||
|
||||
for (i = 0; i < (21 * 24); i += 24)
|
||||
tar_sparse(s, tar2u64(&header[i]), tar2u64(&header[i+12]));
|
||||
isextended = header[OFFS_SX_EXT];
|
||||
s->file_sec++;
|
||||
}
|
||||
tar_sparse(s, s->file_len, 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
fprintf(stderr, "Tar: Error opening file\n");
|
||||
bdrv_delete(s->hd);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
typedef struct TarAIOCB {
|
||||
BlockDriverAIOCB 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_release(acb);
|
||||
}
|
||||
|
||||
static void tar_aio_cancel(BlockDriverAIOCB *blockacb)
|
||||
{
|
||||
}
|
||||
|
||||
static AIOCBInfo tar_aiocb_info = {
|
||||
.aiocb_size = sizeof(TarAIOCB),
|
||||
.cancel = tar_aio_cancel,
|
||||
};
|
||||
|
||||
/* This is where we get a request from a caller to read something */
|
||||
static BlockDriverAIOCB *tar_aio_readv(BlockDriverState *bs,
|
||||
int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
|
||||
BlockDriverCompletionFunc *cb, void *opaque)
|
||||
{
|
||||
BDRVTarState *s = bs->opaque;
|
||||
SparseCache *sparse;
|
||||
int64_t sec_file = sector_num + s->file_sec;
|
||||
int64_t start = sector_num * SECTOR_SIZE;
|
||||
int64_t end = start + (nb_sectors * SECTOR_SIZE);
|
||||
int i;
|
||||
TarAIOCB *acb;
|
||||
|
||||
for (i = 0; i < s->sparse_num; i++) {
|
||||
sparse = &s->sparse[i];
|
||||
if (sparse->start > end) {
|
||||
/* We expect the cache to be start increasing */
|
||||
break;
|
||||
} else if ((sparse->start < start) && (sparse->end <= start)) {
|
||||
/* sparse before our offset */
|
||||
sec_file -= (sparse->end - sparse->start) / SECTOR_SIZE;
|
||||
} else if ((sparse->start <= start) && (sparse->end >= end)) {
|
||||
/* all our sectors are sparse */
|
||||
char *buf = g_malloc0(nb_sectors * SECTOR_SIZE);
|
||||
|
||||
acb = qemu_aio_get(&tar_aiocb_info, bs, cb, opaque);
|
||||
qemu_iovec_from_buf(qiov, 0, buf, nb_sectors * SECTOR_SIZE);
|
||||
g_free(buf);
|
||||
acb->bh = qemu_bh_new(tar_sparse_cb, acb);
|
||||
qemu_bh_schedule(acb->bh);
|
||||
|
||||
return &acb->common;
|
||||
} else if (((sparse->start >= start) && (sparse->start < end)) ||
|
||||
((sparse->end >= start) && (sparse->end < end))) {
|
||||
/* we're semi-sparse (worst case) */
|
||||
/* let's go synchronous and read all sectors individually */
|
||||
char *buf = g_malloc(nb_sectors * SECTOR_SIZE);
|
||||
uint64_t offs;
|
||||
|
||||
for (offs = 0; offs < (nb_sectors * SECTOR_SIZE);
|
||||
offs += SECTOR_SIZE) {
|
||||
bdrv_pread(bs, (sector_num * SECTOR_SIZE) + offs,
|
||||
buf + offs, SECTOR_SIZE);
|
||||
}
|
||||
|
||||
qemu_iovec_from_buf(qiov, 0, buf, nb_sectors * SECTOR_SIZE);
|
||||
acb = qemu_aio_get(&tar_aiocb_info, bs, cb, opaque);
|
||||
acb->bh = qemu_bh_new(tar_sparse_cb, acb);
|
||||
qemu_bh_schedule(acb->bh);
|
||||
|
||||
return &acb->common;
|
||||
}
|
||||
}
|
||||
|
||||
return bdrv_aio_readv(s->hd, sec_file, qiov, nb_sectors,
|
||||
cb, opaque);
|
||||
}
|
||||
|
||||
static void tar_close(BlockDriverState *bs)
|
||||
{
|
||||
dprintf("Close\n");
|
||||
}
|
||||
|
||||
static int64_t tar_getlength(BlockDriverState *bs)
|
||||
{
|
||||
BDRVTarState *s = bs->opaque;
|
||||
dprintf("getlength -> %ld\n", s->file_len);
|
||||
return s->file_len;
|
||||
}
|
||||
|
||||
static BlockDriver bdrv_tar = {
|
||||
.format_name = "tar",
|
||||
.protocol_name = "tar",
|
||||
|
||||
.instance_size = sizeof(BDRVTarState),
|
||||
.bdrv_file_open = tar_open,
|
||||
.bdrv_close = tar_close,
|
||||
.bdrv_getlength = tar_getlength,
|
||||
.bdrv_probe = tar_probe,
|
||||
|
||||
.bdrv_aio_readv = tar_aio_readv,
|
||||
};
|
||||
|
||||
static void tar_block_init(void)
|
||||
{
|
||||
bdrv_register(&bdrv_tar);
|
||||
}
|
||||
|
||||
block_init(tar_block_init);
|
12
block/vmdk.c
12
block/vmdk.c
@@ -1471,7 +1471,7 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options)
|
||||
"ddb.geometry.cylinders = \"%" PRId64 "\"\n"
|
||||
"ddb.geometry.heads = \"16\"\n"
|
||||
"ddb.geometry.sectors = \"63\"\n"
|
||||
"ddb.adapterType = \"ide\"\n";
|
||||
"ddb.adapterType = \"%s\"\n";
|
||||
|
||||
if (filename_decompose(filename, path, prefix, postfix, PATH_MAX)) {
|
||||
return -EINVAL;
|
||||
@@ -1486,6 +1486,8 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options)
|
||||
flags |= options->value.n ? BLOCK_FLAG_COMPAT6 : 0;
|
||||
} else if (!strcmp(options->name, BLOCK_OPT_SUBFMT)) {
|
||||
fmt = options->value.s;
|
||||
} else if (!strcmp(options->name, BLOCK_OPT_SCSI)) {
|
||||
flags |= options->value.n ? BLOCK_FLAG_SCSI: 0;
|
||||
}
|
||||
options++;
|
||||
}
|
||||
@@ -1576,7 +1578,8 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options)
|
||||
parent_desc_line,
|
||||
ext_desc_lines,
|
||||
(flags & BLOCK_FLAG_COMPAT6 ? 6 : 4),
|
||||
total_size / (int64_t)(63 * 16 * 512));
|
||||
total_size / (int64_t)(63 * 16 * 512),
|
||||
flags & BLOCK_FLAG_SCSI ? "lsilogic" : "ide");
|
||||
if (split || flat) {
|
||||
fd = qemu_open(filename,
|
||||
O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE,
|
||||
@@ -1677,6 +1680,11 @@ static QEMUOptionParameter vmdk_create_options[] = {
|
||||
"VMDK flat extent format, can be one of "
|
||||
"{monolithicSparse (default) | monolithicFlat | twoGbMaxExtentSparse | twoGbMaxExtentFlat | streamOptimized} "
|
||||
},
|
||||
{
|
||||
.name = BLOCK_OPT_SCSI,
|
||||
.type = OPT_FLAG,
|
||||
.help = "SCSI image"
|
||||
},
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
@@ -84,11 +84,11 @@ static void win32_aio_process_completion(QEMUWin32AIOState *s,
|
||||
int i;
|
||||
|
||||
for (i = 0; i < qiov->niov; ++i) {
|
||||
memcpy(p, qiov->iov[i].iov_base, qiov->iov[i].iov_len);
|
||||
memcpy(qiov->iov[i].iov_base, p, qiov->iov[i].iov_len);
|
||||
p += qiov->iov[i].iov_len;
|
||||
}
|
||||
g_free(waiocb->buf);
|
||||
}
|
||||
qemu_vfree(waiocb->buf);
|
||||
}
|
||||
|
||||
|
||||
|
@@ -36,6 +36,7 @@
|
||||
#define BLOCK_FLAG_ENCRYPT 1
|
||||
#define BLOCK_FLAG_COMPAT6 4
|
||||
#define BLOCK_FLAG_LAZY_REFCOUNTS 8
|
||||
#define BLOCK_FLAG_SCSI 16
|
||||
|
||||
#define BLOCK_IO_LIMIT_READ 0
|
||||
#define BLOCK_IO_LIMIT_WRITE 1
|
||||
@@ -47,6 +48,7 @@
|
||||
#define BLOCK_OPT_SIZE "size"
|
||||
#define BLOCK_OPT_ENCRYPT "encryption"
|
||||
#define BLOCK_OPT_COMPAT6 "compat6"
|
||||
#define BLOCK_OPT_SCSI "scsi"
|
||||
#define BLOCK_OPT_BACKING_FILE "backing_file"
|
||||
#define BLOCK_OPT_BACKING_FMT "backing_fmt"
|
||||
#define BLOCK_OPT_CLUSTER_SIZE "cluster_size"
|
||||
|
@@ -66,9 +66,9 @@ static ssize_t buffered_flush(QEMUFileBuffered *s)
|
||||
DPRINTF("flushing %zu byte(s) of data\n", s->buffer_size);
|
||||
|
||||
while (s->bytes_xfer < s->xfer_limit && offset < s->buffer_size) {
|
||||
|
||||
size_t to_send = MIN(s->buffer_size - offset, s->xfer_limit - s->bytes_xfer);
|
||||
ret = migrate_fd_put_buffer(s->migration_state, s->buffer + offset,
|
||||
s->buffer_size - offset);
|
||||
to_send);
|
||||
if (ret == -EAGAIN) {
|
||||
DPRINTF("backend not ready, freezing\n");
|
||||
ret = 0;
|
||||
|
2
configure
vendored
2
configure
vendored
@@ -952,6 +952,8 @@ microblaze-linux-user \
|
||||
microblazeel-linux-user \
|
||||
mips-linux-user \
|
||||
mipsel-linux-user \
|
||||
mipsn32-linux-user \
|
||||
mipsn32el-linux-user \
|
||||
or32-linux-user \
|
||||
ppc-linux-user \
|
||||
ppc64-linux-user \
|
||||
|
@@ -950,7 +950,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;
|
||||
#ifdef DEBUG_CONSOLE
|
||||
fprintf(stderr, "escape sequence CSI%d;%d%c, %d parameters\n",
|
||||
|
11
cpu-exec.c
11
cpu-exec.c
@@ -597,7 +597,16 @@ int cpu_exec(CPUArchState *env)
|
||||
tc_ptr = tb->tc_ptr;
|
||||
/* execute the generated code */
|
||||
next_tb = tcg_qemu_tb_exec(env, tc_ptr);
|
||||
if ((next_tb & 3) == 2) {
|
||||
if ((next_tb & 3) == 3) {
|
||||
/* hit stopflag check */
|
||||
tb = (TranslationBlock *)(long)(next_tb & ~3);
|
||||
/* Restore PC. */
|
||||
cpu_pc_from_tb(env, tb);
|
||||
next_tb = 0;
|
||||
env->exit_request = 0;
|
||||
env->exception_index = EXCP_INTERRUPT;
|
||||
cpu_loop_exit(env);
|
||||
} else if ((next_tb & 3) == 2) {
|
||||
/* Instruction counter expired. */
|
||||
int insns_left;
|
||||
tb = (TranslationBlock *)(next_tb & ~3);
|
||||
|
49
exec.c
49
exec.c
@@ -119,6 +119,8 @@ DEFINE_TLS(CPUArchState *,cpu_single_env);
|
||||
1 = Precise instruction counting.
|
||||
2 = Adaptive rate instruction counting. */
|
||||
int use_icount = 0;
|
||||
/* 1 to do cpu_exit by inline flag check rather than tb link breaking */
|
||||
int use_stopflag = 1;
|
||||
|
||||
typedef struct PageDesc {
|
||||
/* list of TBs intersecting this ram page */
|
||||
@@ -734,17 +736,22 @@ static TranslationBlock *tb_alloc(target_ulong pc)
|
||||
{
|
||||
TranslationBlock *tb;
|
||||
|
||||
tcg_lock();
|
||||
if (nb_tbs >= code_gen_max_blocks ||
|
||||
(code_gen_ptr - code_gen_buffer) >= code_gen_buffer_max_size)
|
||||
(code_gen_ptr - code_gen_buffer) >= code_gen_buffer_max_size) {
|
||||
tcg_unlock();
|
||||
return NULL;
|
||||
}
|
||||
tb = &tbs[nb_tbs++];
|
||||
tb->pc = pc;
|
||||
tb->cflags = 0;
|
||||
tcg_unlock();
|
||||
return tb;
|
||||
}
|
||||
|
||||
void tb_free(TranslationBlock *tb)
|
||||
{
|
||||
tcg_lock();
|
||||
/* In practice this is mostly used for single use temporary TB
|
||||
Ignore the hard cases and just back up if this TB happens to
|
||||
be the last one generated. */
|
||||
@@ -752,6 +759,7 @@ void tb_free(TranslationBlock *tb)
|
||||
code_gen_ptr = tb->tc_ptr;
|
||||
nb_tbs--;
|
||||
}
|
||||
tcg_unlock();
|
||||
}
|
||||
|
||||
static inline void invalidate_page_bitmap(PageDesc *p)
|
||||
@@ -805,6 +813,7 @@ void tb_flush(CPUArchState *env1)
|
||||
nb_tbs, nb_tbs > 0 ?
|
||||
((unsigned long)(code_gen_ptr - code_gen_buffer)) / nb_tbs : 0);
|
||||
#endif
|
||||
tcg_lock();
|
||||
if ((unsigned long)(code_gen_ptr - code_gen_buffer) > code_gen_buffer_size)
|
||||
cpu_abort(env1, "Internal error: code buffer overflow\n");
|
||||
|
||||
@@ -821,6 +830,7 @@ void tb_flush(CPUArchState *env1)
|
||||
/* XXX: flush processor icache at this point if cache flush is
|
||||
expensive */
|
||||
tb_flush_count++;
|
||||
tcg_unlock();
|
||||
}
|
||||
|
||||
#ifdef DEBUG_TB_CHECK
|
||||
@@ -1120,9 +1130,12 @@ void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
|
||||
int current_flags = 0;
|
||||
#endif /* TARGET_HAS_PRECISE_SMC */
|
||||
|
||||
tcg_lock();
|
||||
p = page_find(start >> TARGET_PAGE_BITS);
|
||||
if (!p)
|
||||
if (!p) {
|
||||
tcg_unlock();
|
||||
return;
|
||||
}
|
||||
if (!p->code_bitmap &&
|
||||
++p->code_write_count >= SMC_BITMAP_USE_THRESHOLD &&
|
||||
is_cpu_write_access) {
|
||||
@@ -1206,6 +1219,7 @@ void tb_invalidate_phys_page_range(tb_page_addr_t start, tb_page_addr_t end,
|
||||
cpu_resume_from_signal(env, NULL);
|
||||
}
|
||||
#endif
|
||||
tcg_unlock();
|
||||
}
|
||||
|
||||
/* len must be <= 8 and start must be a multiple of len */
|
||||
@@ -1412,12 +1426,16 @@ TranslationBlock *tb_find_pc(uintptr_t tc_ptr)
|
||||
{
|
||||
int m_min, m_max, m;
|
||||
uintptr_t v;
|
||||
TranslationBlock *tb;
|
||||
TranslationBlock *tb, *r;
|
||||
|
||||
if (nb_tbs <= 0)
|
||||
tcg_lock();
|
||||
if (nb_tbs <= 0) {
|
||||
tcg_unlock();
|
||||
return NULL;
|
||||
}
|
||||
if (tc_ptr < (uintptr_t)code_gen_buffer ||
|
||||
tc_ptr >= (uintptr_t)code_gen_ptr) {
|
||||
tcg_unlock();
|
||||
return NULL;
|
||||
}
|
||||
/* binary search (cf Knuth) */
|
||||
@@ -1427,15 +1445,18 @@ TranslationBlock *tb_find_pc(uintptr_t tc_ptr)
|
||||
m = (m_min + m_max) >> 1;
|
||||
tb = &tbs[m];
|
||||
v = (uintptr_t)tb->tc_ptr;
|
||||
if (v == tc_ptr)
|
||||
if (v == tc_ptr) {
|
||||
tcg_unlock();
|
||||
return tb;
|
||||
else if (tc_ptr < v) {
|
||||
} else if (tc_ptr < v) {
|
||||
m_max = m - 1;
|
||||
} else {
|
||||
m_min = m + 1;
|
||||
}
|
||||
}
|
||||
return &tbs[m_max];
|
||||
r = &tbs[m_max];
|
||||
tcg_unlock();
|
||||
return r;
|
||||
}
|
||||
|
||||
static void tb_reset_jump_recursive(TranslationBlock *tb);
|
||||
@@ -1734,7 +1755,13 @@ static void tcg_handle_interrupt(CPUArchState *env, int mask)
|
||||
cpu_abort(env, "Raised interrupt while not in I/O function");
|
||||
}
|
||||
} else {
|
||||
cpu_unlink_tb(env);
|
||||
// XXX just call cpu_exit ?
|
||||
if (use_stopflag) {
|
||||
// XXX is this OK?
|
||||
env->exit_request = 1;
|
||||
} else {
|
||||
cpu_unlink_tb(env);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1757,7 +1784,9 @@ void cpu_reset_interrupt(CPUArchState *env, int mask)
|
||||
void cpu_exit(CPUArchState *env)
|
||||
{
|
||||
env->exit_request = 1;
|
||||
cpu_unlink_tb(env);
|
||||
if (!use_stopflag) {
|
||||
cpu_unlink_tb(env);
|
||||
}
|
||||
}
|
||||
|
||||
void cpu_abort(CPUArchState *env, const char *fmt, ...)
|
||||
@@ -2387,10 +2416,12 @@ static void *file_ram_alloc(RAMBlock *block,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifndef TARGET_PPC
|
||||
if (kvm_enabled() && !kvm_has_sync_mmu()) {
|
||||
fprintf(stderr, "host lacks kvm mmu notifiers, -mem-path unsupported\n");
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (asprintf(&filename, "%s/qemu_back_mem.XXXXXX", path) == -1) {
|
||||
return NULL;
|
||||
|
16
gen-icount.h
16
gen-icount.h
@@ -2,13 +2,25 @@
|
||||
|
||||
/* Helpers for instruction counting code generation. */
|
||||
|
||||
extern int use_stopflag;
|
||||
|
||||
static TCGArg *icount_arg;
|
||||
static int icount_label;
|
||||
static int stopflag_label;
|
||||
|
||||
static inline void gen_icount_start(void)
|
||||
{
|
||||
TCGv_i32 count;
|
||||
|
||||
if (use_stopflag) {
|
||||
TCGv_i32 flag;
|
||||
stopflag_label = gen_new_label();
|
||||
flag = tcg_temp_local_new_i32();
|
||||
tcg_gen_ld_i32(flag, cpu_env, offsetof(CPUArchState, exit_request));
|
||||
tcg_gen_brcondi_i32(TCG_COND_NE, flag, 0, stopflag_label);
|
||||
tcg_temp_free_i32(flag);
|
||||
}
|
||||
|
||||
if (!use_icount)
|
||||
return;
|
||||
|
||||
@@ -26,6 +38,10 @@ static inline void gen_icount_start(void)
|
||||
|
||||
static void gen_icount_end(TranslationBlock *tb, int num_insns)
|
||||
{
|
||||
if (use_stopflag) {
|
||||
gen_set_label(stopflag_label);
|
||||
tcg_gen_exit_tb((long)tb + 3); // XXX
|
||||
}
|
||||
if (use_icount) {
|
||||
*icount_arg = num_insns;
|
||||
gen_set_label(icount_label);
|
||||
|
@@ -61,6 +61,8 @@ static int debugflags = DBGBIT(TXERR) | DBGBIT(GENERAL);
|
||||
|
||||
/* this is the size past which hardware will drop packets when setting LPE=0 */
|
||||
#define MAXIMUM_ETHERNET_VLAN_SIZE 1522
|
||||
/* this is the size past which hardware will drop packets when setting LPE=1 */
|
||||
#define MAXIMUM_ETHERNET_LPE_SIZE 16384
|
||||
|
||||
/*
|
||||
* HW models:
|
||||
@@ -809,8 +811,9 @@ e1000_receive(NetClientState *nc, const uint8_t *buf, size_t size)
|
||||
}
|
||||
|
||||
/* Discard oversized packets if !LPE and !SBP. */
|
||||
if (size > MAXIMUM_ETHERNET_VLAN_SIZE
|
||||
&& !(s->mac_reg[RCTL] & E1000_RCTL_LPE)
|
||||
if ((size > MAXIMUM_ETHERNET_LPE_SIZE ||
|
||||
(size > MAXIMUM_ETHERNET_VLAN_SIZE
|
||||
&& !(s->mac_reg[RCTL] & E1000_RCTL_LPE)))
|
||||
&& !(s->mac_reg[RCTL] & E1000_RCTL_SBP)) {
|
||||
return size;
|
||||
}
|
||||
|
@@ -1025,6 +1025,19 @@ static bool assigned_dev_msix_masked(MSIXTableEntry *entry)
|
||||
return (entry->ctrl & cpu_to_le32(0x1)) != 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* When MSI-X is first enabled the vector table typically has all the
|
||||
* vectors masked, so we can't use that as the obvious test to figure out
|
||||
* how many vectors to initially enable. Instead we look at the data field
|
||||
* because this is what worked for pci-assign for a long time. This makes
|
||||
* sure the physical MSI-X state tracks the guest's view, which is important
|
||||
* for some VF/PF and PF/fw communication channels.
|
||||
*/
|
||||
static bool assigned_dev_msix_skipped(MSIXTableEntry *entry)
|
||||
{
|
||||
return !entry->data;
|
||||
}
|
||||
|
||||
static int assigned_dev_update_msix_mmio(PCIDevice *pci_dev)
|
||||
{
|
||||
AssignedDevice *adev = DO_UPCAST(AssignedDevice, dev, pci_dev);
|
||||
@@ -1035,7 +1048,7 @@ static int assigned_dev_update_msix_mmio(PCIDevice *pci_dev)
|
||||
|
||||
/* Get the usable entry number for allocating */
|
||||
for (i = 0; i < adev->msix_max; i++, entry++) {
|
||||
if (assigned_dev_msix_masked(entry)) {
|
||||
if (assigned_dev_msix_skipped(entry)) {
|
||||
continue;
|
||||
}
|
||||
entries_nr++;
|
||||
@@ -1064,7 +1077,7 @@ static int assigned_dev_update_msix_mmio(PCIDevice *pci_dev)
|
||||
for (i = 0; i < adev->msix_max; i++, entry++) {
|
||||
adev->msi_virq[i] = -1;
|
||||
|
||||
if (assigned_dev_msix_masked(entry)) {
|
||||
if (assigned_dev_msix_skipped(entry)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@@ -113,11 +113,12 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl)
|
||||
qxl->guest_primary.bits_pp);
|
||||
if (qxl->guest_primary.qxl_stride > 0) {
|
||||
qemu_free_displaysurface(vga->ds);
|
||||
qemu_create_displaysurface_from(qxl->guest_primary.surface.width,
|
||||
qxl->guest_primary.surface.height,
|
||||
qxl->guest_primary.bits_pp,
|
||||
qxl->guest_primary.abs_stride,
|
||||
qxl->guest_primary.data);
|
||||
vga->ds->surface = qemu_create_displaysurface_from
|
||||
(qxl->guest_primary.surface.width,
|
||||
qxl->guest_primary.surface.height,
|
||||
qxl->guest_primary.bits_pp,
|
||||
qxl->guest_primary.abs_stride,
|
||||
qxl->guest_primary.data);
|
||||
} else {
|
||||
qemu_resize_displaysurface(vga->ds,
|
||||
qxl->guest_primary.surface.width,
|
||||
|
20
hw/qxl.c
20
hw/qxl.c
@@ -37,33 +37,25 @@
|
||||
*/
|
||||
#undef SPICE_RING_PROD_ITEM
|
||||
#define SPICE_RING_PROD_ITEM(qxl, r, ret) { \
|
||||
typeof(r) start = r; \
|
||||
typeof(r) end = r + 1; \
|
||||
uint32_t prod = (r)->prod & SPICE_RING_INDEX_MASK(r); \
|
||||
typeof(&(r)->items[prod]) m_item = &(r)->items[prod]; \
|
||||
if (!((uint8_t*)m_item >= (uint8_t*)(start) && (uint8_t*)(m_item + 1) <= (uint8_t*)(end))) { \
|
||||
if (prod >= ARRAY_SIZE((r)->items)) { \
|
||||
qxl_set_guest_bug(qxl, "SPICE_RING_PROD_ITEM indices mismatch " \
|
||||
"! %p <= %p < %p", (uint8_t *)start, \
|
||||
(uint8_t *)m_item, (uint8_t *)end); \
|
||||
"%u >= %zu", prod, ARRAY_SIZE((r)->items)); \
|
||||
ret = NULL; \
|
||||
} else { \
|
||||
ret = &m_item->el; \
|
||||
ret = &(r)->items[prod].el; \
|
||||
} \
|
||||
}
|
||||
|
||||
#undef SPICE_RING_CONS_ITEM
|
||||
#define SPICE_RING_CONS_ITEM(qxl, r, ret) { \
|
||||
typeof(r) start = r; \
|
||||
typeof(r) end = r + 1; \
|
||||
uint32_t cons = (r)->cons & SPICE_RING_INDEX_MASK(r); \
|
||||
typeof(&(r)->items[cons]) m_item = &(r)->items[cons]; \
|
||||
if (!((uint8_t*)m_item >= (uint8_t*)(start) && (uint8_t*)(m_item + 1) <= (uint8_t*)(end))) { \
|
||||
if (cons >= ARRAY_SIZE((r)->items)) { \
|
||||
qxl_set_guest_bug(qxl, "SPICE_RING_CONS_ITEM indices mismatch " \
|
||||
"! %p <= %p < %p", (uint8_t *)start, \
|
||||
(uint8_t *)m_item, (uint8_t *)end); \
|
||||
"%u >= %zu", cons, ARRAY_SIZE((r)->items)); \
|
||||
ret = NULL; \
|
||||
} else { \
|
||||
ret = &m_item->el; \
|
||||
ret = &(r)->items[cons].el; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
@@ -11,6 +11,8 @@ static char *scsibus_get_dev_path(DeviceState *dev);
|
||||
static char *scsibus_get_fw_dev_path(DeviceState *dev);
|
||||
static int scsi_req_parse(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf);
|
||||
static void scsi_req_dequeue(SCSIRequest *req);
|
||||
static uint8_t *scsi_target_alloc_buf(SCSIRequest *req, size_t len);
|
||||
static void scsi_target_free_buf(SCSIRequest *req);
|
||||
|
||||
static Property scsi_props[] = {
|
||||
DEFINE_PROP_UINT32("channel", SCSIDevice, channel, 0),
|
||||
@@ -304,7 +306,8 @@ typedef struct SCSITargetReq SCSITargetReq;
|
||||
struct SCSITargetReq {
|
||||
SCSIRequest req;
|
||||
int len;
|
||||
uint8_t buf[2056];
|
||||
uint8_t *buf;
|
||||
int buf_len;
|
||||
};
|
||||
|
||||
static void store_lun(uint8_t *outbuf, int lun)
|
||||
@@ -348,14 +351,12 @@ static bool scsi_target_emulate_report_luns(SCSITargetReq *r)
|
||||
if (!found_lun0) {
|
||||
n += 8;
|
||||
}
|
||||
len = MIN(n + 8, r->req.cmd.xfer & ~7);
|
||||
if (len > sizeof(r->buf)) {
|
||||
/* TODO: > 256 LUNs? */
|
||||
return false;
|
||||
}
|
||||
|
||||
scsi_target_alloc_buf(&r->req, n + 8);
|
||||
|
||||
len = MIN(n + 8, r->req.cmd.xfer & ~7);
|
||||
memset(r->buf, 0, len);
|
||||
stl_be_p(&r->buf, n);
|
||||
stl_be_p(&r->buf[0], n);
|
||||
i = found_lun0 ? 8 : 16;
|
||||
QTAILQ_FOREACH(kid, &r->req.bus->qbus.children, sibling) {
|
||||
DeviceState *qdev = kid->child;
|
||||
@@ -374,6 +375,9 @@ static bool scsi_target_emulate_report_luns(SCSITargetReq *r)
|
||||
static bool scsi_target_emulate_inquiry(SCSITargetReq *r)
|
||||
{
|
||||
assert(r->req.dev->lun != r->req.lun);
|
||||
|
||||
scsi_target_alloc_buf(&r->req, SCSI_INQUIRY_LEN);
|
||||
|
||||
if (r->req.cmd.buf[1] & 0x2) {
|
||||
/* Command support data - optional, not implemented */
|
||||
return false;
|
||||
@@ -398,7 +402,7 @@ static bool scsi_target_emulate_inquiry(SCSITargetReq *r)
|
||||
return false;
|
||||
}
|
||||
/* done with EVPD */
|
||||
assert(r->len < sizeof(r->buf));
|
||||
assert(r->len < r->buf_len);
|
||||
r->len = MIN(r->req.cmd.xfer, r->len);
|
||||
return true;
|
||||
}
|
||||
@@ -409,7 +413,7 @@ static bool scsi_target_emulate_inquiry(SCSITargetReq *r)
|
||||
}
|
||||
|
||||
/* PAGE CODE == 0 */
|
||||
r->len = MIN(r->req.cmd.xfer, 36);
|
||||
r->len = MIN(r->req.cmd.xfer, SCSI_INQUIRY_LEN);
|
||||
memset(r->buf, 0, r->len);
|
||||
if (r->req.lun != 0) {
|
||||
r->buf[0] = TYPE_NO_LUN;
|
||||
@@ -442,8 +446,9 @@ static int32_t scsi_target_send_command(SCSIRequest *req, uint8_t *buf)
|
||||
}
|
||||
break;
|
||||
case REQUEST_SENSE:
|
||||
scsi_target_alloc_buf(&r->req, SCSI_SENSE_LEN);
|
||||
r->len = scsi_device_get_sense(r->req.dev, r->buf,
|
||||
MIN(req->cmd.xfer, sizeof r->buf),
|
||||
MIN(req->cmd.xfer, r->buf_len),
|
||||
(req->cmd.buf[1] & 1) == 0);
|
||||
if (r->req.dev->sense_is_ua) {
|
||||
scsi_device_unit_attention_reported(req->dev);
|
||||
@@ -488,11 +493,29 @@ static uint8_t *scsi_target_get_buf(SCSIRequest *req)
|
||||
return r->buf;
|
||||
}
|
||||
|
||||
static uint8_t *scsi_target_alloc_buf(SCSIRequest *req, size_t len)
|
||||
{
|
||||
SCSITargetReq *r = DO_UPCAST(SCSITargetReq, req, req);
|
||||
|
||||
r->buf = g_malloc(len);
|
||||
r->buf_len = len;
|
||||
|
||||
return r->buf;
|
||||
}
|
||||
|
||||
static void scsi_target_free_buf(SCSIRequest *req)
|
||||
{
|
||||
SCSITargetReq *r = DO_UPCAST(SCSITargetReq, req, req);
|
||||
|
||||
g_free(r->buf);
|
||||
}
|
||||
|
||||
static const struct SCSIReqOps reqops_target_command = {
|
||||
.size = sizeof(SCSITargetReq),
|
||||
.send_command = scsi_target_send_command,
|
||||
.read_data = scsi_target_read_data,
|
||||
.get_buf = scsi_target_get_buf,
|
||||
.free_req = scsi_target_free_buf,
|
||||
};
|
||||
|
||||
|
||||
@@ -1348,7 +1371,7 @@ int scsi_build_sense(uint8_t *in_buf, int in_len,
|
||||
buf[7] = 10;
|
||||
buf[12] = sense.asc;
|
||||
buf[13] = sense.ascq;
|
||||
return MIN(len, 18);
|
||||
return MIN(len, SCSI_SENSE_LEN);
|
||||
} else {
|
||||
/* Return descriptor format sense buffer */
|
||||
buf[0] = 0x72;
|
||||
|
@@ -9,6 +9,8 @@
|
||||
#define MAX_SCSI_DEVS 255
|
||||
|
||||
#define SCSI_CMD_BUF_SIZE 16
|
||||
#define SCSI_SENSE_LEN 18
|
||||
#define SCSI_INQUIRY_LEN 36
|
||||
|
||||
typedef struct SCSIBus SCSIBus;
|
||||
typedef struct SCSIBusInfo SCSIBusInfo;
|
||||
|
@@ -266,8 +266,6 @@ static void serial_xmit(void *opaque)
|
||||
s->tsr = fifo_get(s,XMIT_FIFO);
|
||||
if (!s->xmit_fifo.count)
|
||||
s->lsr |= UART_LSR_THRE;
|
||||
} else if ((s->lsr & UART_LSR_THRE)) {
|
||||
return;
|
||||
} else {
|
||||
s->tsr = s->thr;
|
||||
s->lsr |= UART_LSR_THRE;
|
||||
@@ -279,7 +277,7 @@ static void serial_xmit(void *opaque)
|
||||
/* in loopback mode, say that we just received a char */
|
||||
serial_receive1(s, &s->tsr, 1);
|
||||
} else if (qemu_chr_fe_write(s->chr, &s->tsr, 1) != 1) {
|
||||
if ((s->tsr_retry >= 0) && (s->tsr_retry <= MAX_XMIT_RETRY)) {
|
||||
if ((s->tsr_retry > 0) && (s->tsr_retry <= MAX_XMIT_RETRY)) {
|
||||
s->tsr_retry++;
|
||||
qemu_mod_timer(s->transmit_timer, new_xmit_ts + s->char_transmit_time);
|
||||
return;
|
||||
|
@@ -275,7 +275,7 @@ static void vfio_enable_intx_kvm(VFIODevice *vdev)
|
||||
int ret, argsz;
|
||||
int32_t *pfd;
|
||||
|
||||
if (!kvm_irqchip_in_kernel() ||
|
||||
if (!kvm_irqfds_enabled() ||
|
||||
vdev->intx.route.mode != PCI_INTX_ENABLED ||
|
||||
!kvm_check_extension(kvm_state, KVM_CAP_IRQFD_RESAMPLE)) {
|
||||
return;
|
||||
@@ -438,7 +438,8 @@ static int vfio_enable_intx(VFIODevice *vdev)
|
||||
* Only conditional to avoid generating error messages on platforms
|
||||
* where we won't actually use the result anyway.
|
||||
*/
|
||||
if (kvm_check_extension(kvm_state, KVM_CAP_IRQFD_RESAMPLE)) {
|
||||
if (kvm_irqfds_enabled() &&
|
||||
kvm_check_extension(kvm_state, KVM_CAP_IRQFD_RESAMPLE)) {
|
||||
vdev->intx.route = pci_device_route_intx_to_irq(&vdev->pdev,
|
||||
vdev->intx.pin);
|
||||
}
|
||||
@@ -561,8 +562,8 @@ static int vfio_enable_vectors(VFIODevice *vdev, bool msix)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int vfio_msix_vector_use(PCIDevice *pdev,
|
||||
unsigned int nr, MSIMessage msg)
|
||||
static int vfio_msix_vector_do_use(PCIDevice *pdev, unsigned int nr,
|
||||
MSIMessage *msg, IOHandler *handler)
|
||||
{
|
||||
VFIODevice *vdev = DO_UPCAST(VFIODevice, pdev, pdev);
|
||||
VFIOMSIVector *vector;
|
||||
@@ -586,7 +587,7 @@ static int vfio_msix_vector_use(PCIDevice *pdev,
|
||||
* Attempt to enable route through KVM irqchip,
|
||||
* default to userspace handling if unavailable.
|
||||
*/
|
||||
vector->virq = kvm_irqchip_add_msi_route(kvm_state, msg);
|
||||
vector->virq = msg ? kvm_irqchip_add_msi_route(kvm_state, *msg) : -1;
|
||||
if (vector->virq < 0 ||
|
||||
kvm_irqchip_add_irqfd_notifier(kvm_state, &vector->interrupt,
|
||||
vector->virq) < 0) {
|
||||
@@ -595,7 +596,7 @@ static int vfio_msix_vector_use(PCIDevice *pdev,
|
||||
vector->virq = -1;
|
||||
}
|
||||
qemu_set_fd_handler(event_notifier_get_fd(&vector->interrupt),
|
||||
vfio_msi_interrupt, NULL, vector);
|
||||
handler, NULL, vector);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -638,6 +639,12 @@ static int vfio_msix_vector_use(PCIDevice *pdev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vfio_msix_vector_use(PCIDevice *pdev,
|
||||
unsigned int nr, MSIMessage msg)
|
||||
{
|
||||
return vfio_msix_vector_do_use(pdev, nr, &msg, vfio_msi_interrupt);
|
||||
}
|
||||
|
||||
static void vfio_msix_vector_release(PCIDevice *pdev, unsigned int nr)
|
||||
{
|
||||
VFIODevice *vdev = DO_UPCAST(VFIODevice, pdev, pdev);
|
||||
@@ -696,6 +703,22 @@ static void vfio_enable_msix(VFIODevice *vdev)
|
||||
|
||||
vdev->interrupt = VFIO_INT_MSIX;
|
||||
|
||||
/*
|
||||
* Some communication channels between VF & PF or PF & fw rely on the
|
||||
* physical state of the device and expect that enabling MSI-X from the
|
||||
* guest enables the same on the host. When our guest is Linux, the
|
||||
* guest driver call to pci_enable_msix() sets the enabling bit in the
|
||||
* MSI-X capability, but leaves the vector table masked. We therefore
|
||||
* can't rely on a vector_use callback (from request_irq() in the guest)
|
||||
* to switch the physical device into MSI-X mode because that may come a
|
||||
* long time after pci_enable_msix(). This code enables vector 0 with
|
||||
* triggering to userspace, then immediately release the vector, leaving
|
||||
* the physical device with no vectors enabled, but MSI-X enabled, just
|
||||
* like the guest view.
|
||||
*/
|
||||
vfio_msix_vector_do_use(&vdev->pdev, 0, NULL, NULL);
|
||||
vfio_msix_vector_release(&vdev->pdev, 0);
|
||||
|
||||
if (msix_set_vector_notifiers(&vdev->pdev, vfio_msix_vector_use,
|
||||
vfio_msix_vector_release)) {
|
||||
error_report("vfio: msix_set_vector_notifiers failed\n");
|
||||
@@ -1814,13 +1837,13 @@ static int vfio_get_device(VFIOGroup *group, const char *name, VFIODevice *vdev)
|
||||
error_report("Warning, device %s does not support reset\n", name);
|
||||
}
|
||||
|
||||
if (dev_info.num_regions != VFIO_PCI_NUM_REGIONS) {
|
||||
if (dev_info.num_regions < VFIO_PCI_CONFIG_REGION_INDEX + 1) {
|
||||
error_report("vfio: unexpected number of io regions %u\n",
|
||||
dev_info.num_regions);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (dev_info.num_irqs != VFIO_PCI_NUM_IRQS) {
|
||||
if (dev_info.num_irqs < VFIO_PCI_MSIX_IRQ_INDEX + 1) {
|
||||
error_report("vfio: unexpected number of irqs %u\n", dev_info.num_irqs);
|
||||
goto error;
|
||||
}
|
||||
|
2
hw/vga.c
2
hw/vga.c
@@ -2413,7 +2413,7 @@ void ppm_save(const char *filename, struct DisplaySurface *ds, Error **errp)
|
||||
}
|
||||
linebuf = qemu_pixman_linebuf_create(PIXMAN_BE_r8g8b8, width);
|
||||
for (y = 0; y < height; y++) {
|
||||
qemu_pixman_linebuf_fill(linebuf, ds->image, width, y);
|
||||
qemu_pixman_linebuf_fill(linebuf, ds->image, width, 0, y);
|
||||
clearerr(f);
|
||||
ret = fwrite(pixman_image_get_data(linebuf), 1,
|
||||
pixman_image_get_stride(linebuf), f);
|
||||
|
@@ -113,6 +113,31 @@ struct XenBlkDev {
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
|
||||
static void ioreq_reset(struct ioreq *ioreq)
|
||||
{
|
||||
memset(&ioreq->req, 0, sizeof(ioreq->req));
|
||||
ioreq->status = 0;
|
||||
ioreq->start = 0;
|
||||
ioreq->presync = 0;
|
||||
ioreq->postsync = 0;
|
||||
ioreq->mapped = 0;
|
||||
|
||||
memset(ioreq->domids, 0, sizeof(ioreq->domids));
|
||||
memset(ioreq->refs, 0, sizeof(ioreq->refs));
|
||||
ioreq->prot = 0;
|
||||
memset(ioreq->page, 0, sizeof(ioreq->page));
|
||||
ioreq->pages = NULL;
|
||||
|
||||
ioreq->aio_inflight = 0;
|
||||
ioreq->aio_errors = 0;
|
||||
|
||||
ioreq->blkdev = NULL;
|
||||
memset(&ioreq->list, 0, sizeof(ioreq->list));
|
||||
memset(&ioreq->acct, 0, sizeof(ioreq->acct));
|
||||
|
||||
qemu_iovec_reset(&ioreq->v);
|
||||
}
|
||||
|
||||
static struct ioreq *ioreq_start(struct XenBlkDev *blkdev)
|
||||
{
|
||||
struct ioreq *ioreq = NULL;
|
||||
@@ -130,7 +155,6 @@ static struct ioreq *ioreq_start(struct XenBlkDev *blkdev)
|
||||
/* get one from freelist */
|
||||
ioreq = QLIST_FIRST(&blkdev->freelist);
|
||||
QLIST_REMOVE(ioreq, list);
|
||||
qemu_iovec_reset(&ioreq->v);
|
||||
}
|
||||
QLIST_INSERT_HEAD(&blkdev->inflight, ioreq, list);
|
||||
blkdev->requests_inflight++;
|
||||
@@ -154,7 +178,7 @@ static void ioreq_release(struct ioreq *ioreq, bool finish)
|
||||
struct XenBlkDev *blkdev = ioreq->blkdev;
|
||||
|
||||
QLIST_REMOVE(ioreq, list);
|
||||
memset(ioreq, 0, sizeof(*ioreq));
|
||||
ioreq_reset(ioreq);
|
||||
ioreq->blkdev = blkdev;
|
||||
QLIST_INSERT_HEAD(&blkdev->freelist, ioreq, list);
|
||||
if (finish) {
|
||||
|
@@ -671,7 +671,8 @@ static int xen_pt_initfn(PCIDevice *d)
|
||||
s->is_virtfn = s->real_device.is_virtfn;
|
||||
if (s->is_virtfn) {
|
||||
XEN_PT_LOG(d, "%04x:%02x:%02x.%d is a SR-IOV Virtual Function\n",
|
||||
s->real_device.domain, bus, slot, func);
|
||||
s->real_device.domain, s->real_device.bus,
|
||||
s->real_device.dev, s->real_device.func);
|
||||
}
|
||||
|
||||
/* Initialize virtualized PCI configuration (Extended 256 Bytes) */
|
||||
@@ -752,7 +753,7 @@ out:
|
||||
memory_listener_register(&s->memory_listener, &address_space_memory);
|
||||
memory_listener_register(&s->io_listener, &address_space_io);
|
||||
XEN_PT_LOG(d, "Real physical device %02x:%02x.%d registered successfuly!\n",
|
||||
bus, slot, func);
|
||||
s->hostaddr.bus, s->hostaddr.slot, s->hostaddr.function);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -321,7 +321,7 @@ static int xen_pt_msix_update_one(XenPCIPassthroughState *s, int entry_nr)
|
||||
|
||||
pirq = entry->pirq;
|
||||
|
||||
rc = msi_msix_setup(s, entry->data, entry->data, &pirq, true, entry_nr,
|
||||
rc = msi_msix_setup(s, entry->addr, entry->data, &pirq, true, entry_nr,
|
||||
entry->pirq == XEN_PT_UNASSIGNED_PIRQ);
|
||||
if (rc) {
|
||||
return rc;
|
||||
|
@@ -5,3 +5,5 @@ obj-$(TARGET_HAS_BFLT) += flatload.o
|
||||
obj-$(TARGET_I386) += vm86.o
|
||||
obj-$(TARGET_ARM) += arm/nwfpe/
|
||||
obj-$(TARGET_M68K) += m68k-sim.o
|
||||
|
||||
obj-binfmt-y = binfmt.o
|
||||
|
67
linux-user/binfmt.c
Normal file
67
linux-user/binfmt.c
Normal file
@@ -0,0 +1,67 @@
|
||||
#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;
|
||||
|
||||
guestarch = strrchr(argv[0], '-') ;
|
||||
if (!guestarch) {
|
||||
goto skip;
|
||||
}
|
||||
guestarch++;
|
||||
asprintf(&hostbin, "/emul/" ARCH_NAME "-for-%s/%s", guestarch, argv[1]);
|
||||
if (!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);
|
||||
}
|
@@ -70,6 +70,24 @@
|
||||
IOCTL(BLKGETSIZE, IOC_R, MK_PTR(TYPE_ULONG))
|
||||
#ifdef BLKGETSIZE64
|
||||
IOCTL(BLKGETSIZE64, IOC_R, MK_PTR(TYPE_ULONGLONG))
|
||||
#endif
|
||||
#ifdef BLKDISCARD
|
||||
IOCTL(BLKDISCARD, IOC_W, MK_PTR(MK_STRUCT(STRUCT_blkdiscard)))
|
||||
#endif
|
||||
#ifdef BLKIOMIN
|
||||
IOCTL(BLKIOMIN, IOC_R, MK_PTR(TYPE_INT))
|
||||
#endif
|
||||
#ifdef BLKIOOPT
|
||||
IOCTL(BLKIOOPT, IOC_R, MK_PTR(TYPE_INT))
|
||||
#endif
|
||||
#ifdef BLKALIGNOFF
|
||||
IOCTL(BLKALIGNOFF, IOC_R, MK_PTR(TYPE_INT))
|
||||
#endif
|
||||
#ifdef BLKPBSZGET
|
||||
IOCTL(BLKPBSZGET, IOC_R, MK_PTR(TYPE_INT))
|
||||
#endif
|
||||
#ifdef BLKDISCARDZEROES
|
||||
IOCTL(BLKDISCARDZEROES, IOC_R, MK_PTR(TYPE_INT))
|
||||
#endif
|
||||
IOCTL(BLKFLSBUF, 0, TYPE_NULL)
|
||||
IOCTL(BLKRASET, 0, TYPE_INT)
|
||||
@@ -86,6 +104,8 @@
|
||||
IOCTL_SPECIAL(FS_IOC_FIEMAP, IOC_W | IOC_R, do_ioctl_fs_ioc_fiemap,
|
||||
MK_PTR(MK_STRUCT(STRUCT_fiemap)))
|
||||
#endif
|
||||
IOCTL(FS_IOC_GETFLAGS, IOC_R, MK_PTR(TYPE_LONG))
|
||||
IOCTL(FS_IOC_SETFLAGS, IOC_W, MK_PTR(TYPE_LONG))
|
||||
|
||||
IOCTL(SIOCATMARK, 0, TYPE_NULL)
|
||||
IOCTL(SIOCADDRT, IOC_W, MK_PTR(MK_STRUCT(STRUCT_rtentry)))
|
||||
@@ -316,6 +336,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)))
|
||||
@@ -323,6 +348,7 @@
|
||||
IOCTL(LOOP_SET_STATUS64, IOC_W, MK_PTR(MK_STRUCT(STRUCT_loop_info64)))
|
||||
IOCTL(LOOP_GET_STATUS64, IOC_W, MK_PTR(MK_STRUCT(STRUCT_loop_info64)))
|
||||
IOCTL(LOOP_CHANGE_FD, 0, TYPE_INT)
|
||||
IOCTL_SPECIAL(LOOP_BOGUS_CMD, 0, do_ioctl_fail, TYPE_INT)
|
||||
|
||||
IOCTL(MTIOCTOP, IOC_W, MK_PTR(MK_STRUCT(STRUCT_mtop)))
|
||||
IOCTL(MTIOCGET, IOC_R, MK_PTR(MK_STRUCT(STRUCT_mtget)))
|
||||
|
467
linux-user/ioctls_alsa.h
Normal file
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
@@ -91,5 +91,6 @@ struct loop_info64 {
|
||||
#define LOOP_SET_STATUS64 0x4C04
|
||||
#define LOOP_GET_STATUS64 0x4C05
|
||||
#define LOOP_CHANGE_FD 0x4C06
|
||||
#define LOOP_BOGUS_CMD 0x4C82
|
||||
|
||||
#endif
|
||||
|
@@ -64,6 +64,7 @@ unsigned long reserved_va;
|
||||
#endif
|
||||
|
||||
static void usage(void);
|
||||
extern int use_stopflag;
|
||||
|
||||
static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX;
|
||||
const char *qemu_uname_release = CONFIG_UNAME_RELEASE;
|
||||
@@ -833,15 +834,22 @@ void cpu_loop(CPUARMState *env)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
env->regs[0] = do_syscall(env,
|
||||
n,
|
||||
env->regs[0],
|
||||
env->regs[1],
|
||||
env->regs[2],
|
||||
env->regs[3],
|
||||
env->regs[4],
|
||||
env->regs[5],
|
||||
0, 0);
|
||||
TaskState *ts = ((CPUArchState*)env)->opaque;
|
||||
target_ulong r;
|
||||
r = do_syscall(env, n, env->regs[0], env->regs[1],
|
||||
env->regs[2], env->regs[3], env->regs[4],
|
||||
env->regs[5], 0, 0);
|
||||
if ((r == -EINTR) && ts->signal_restart &&
|
||||
syscall_restartable(n)) {
|
||||
if (env->thumb) {
|
||||
env->regs[15] -= 2;
|
||||
} else {
|
||||
env->regs[15] -= 4;
|
||||
}
|
||||
} else {
|
||||
env->regs[0] = r;
|
||||
}
|
||||
ts->signal_restart = 0;
|
||||
}
|
||||
} else {
|
||||
goto error;
|
||||
@@ -3192,6 +3200,11 @@ static void handle_arg_reserved_va(const char *arg)
|
||||
}
|
||||
#endif
|
||||
|
||||
static void handle_arg_nostopflag(const char *arg)
|
||||
{
|
||||
use_stopflag = 0;
|
||||
}
|
||||
|
||||
static void handle_arg_singlestep(const char *arg)
|
||||
{
|
||||
singlestep = 1;
|
||||
@@ -3247,6 +3260,8 @@ static const struct qemu_argument arg_table[] = {
|
||||
"options", "activate log"},
|
||||
{"D", "QEMU_LOG_FILENAME", true, handle_arg_log_filename,
|
||||
"logfile", "override default logfile location"},
|
||||
{"no-stopflag", "QEMU_NOSTOPFLAG", false, handle_arg_nostopflag,
|
||||
"", "run in singlestep mode"},
|
||||
{"p", "QEMU_PAGESIZE", true, handle_arg_pagesize,
|
||||
"pagesize", "set the host page size to 'pagesize'"},
|
||||
{"singlestep", "QEMU_SINGLESTEP", false, handle_arg_singlestep,
|
||||
|
@@ -30,6 +30,7 @@
|
||||
|
||||
#include "qemu.h"
|
||||
#include "qemu-common.h"
|
||||
#include "tcg.h"
|
||||
|
||||
//#define DEBUG_MMAP
|
||||
|
||||
@@ -41,6 +42,7 @@ void mmap_lock(void)
|
||||
{
|
||||
if (mmap_lock_count++ == 0) {
|
||||
pthread_mutex_lock(&mmap_mutex);
|
||||
tcg_lock();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,6 +50,7 @@ void mmap_unlock(void)
|
||||
{
|
||||
if (--mmap_lock_count == 0) {
|
||||
pthread_mutex_unlock(&mmap_mutex);
|
||||
tcg_unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -377,6 +380,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)
|
||||
@@ -411,6 +417,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;
|
||||
|
@@ -137,6 +137,8 @@ typedef struct TaskState {
|
||||
struct sigqueue sigqueue_table[MAX_SIGQUEUE_SIZE]; /* siginfo queue */
|
||||
struct sigqueue *first_free; /* first free siginfo queue entry */
|
||||
int signal_pending; /* non zero if a signal may be pending */
|
||||
int signal_in_syscall; /* non zero if we are in do_syscall() */
|
||||
int signal_restart; /* non zero if we need to restart a syscall */
|
||||
} __attribute__((aligned(16))) TaskState;
|
||||
|
||||
extern char *exec_path;
|
||||
@@ -192,10 +194,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 CPUArchState *thread_env;
|
||||
void cpu_loop(CPUArchState *env);
|
||||
@@ -203,6 +205,7 @@ char *target_strerror(int err);
|
||||
int get_osversion(void);
|
||||
void fork_start(void);
|
||||
void fork_end(int child);
|
||||
int syscall_restartable(int syscall_nr);
|
||||
|
||||
/* Creates the initial guest address space in the host memory space using
|
||||
* the given host start address hint and size. The guest_start parameter
|
||||
|
@@ -25,6 +25,7 @@
|
||||
#include <assert.h>
|
||||
#include <sys/ucontext.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sched.h>
|
||||
|
||||
#include "qemu.h"
|
||||
#include "qemu-common.h"
|
||||
@@ -394,6 +395,10 @@ static void QEMU_NORETURN force_sig(int target_sig)
|
||||
host_sig = target_to_host_signal(target_sig);
|
||||
gdb_signalled(thread_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();
|
||||
@@ -411,6 +416,8 @@ static void QEMU_NORETURN force_sig(int target_sig)
|
||||
target_sig, strsignal(host_sig), "core dumped" );
|
||||
}
|
||||
|
||||
no_core:
|
||||
|
||||
/* The proper exit code for dying from an uncaught signal is
|
||||
* -<signal>. The kernel doesn't allow exit() or _exit() to pass
|
||||
* a negative value. To get the proper exit code we need to
|
||||
@@ -496,6 +503,11 @@ int queue_signal(CPUArchState *env, int sig, target_siginfo_t *info)
|
||||
k->pending = 1;
|
||||
/* signal that a new signal is pending */
|
||||
ts->signal_pending = 1;
|
||||
/* check if we have to restart the current syscall */
|
||||
if ((sigact_table[sig - 1].sa_flags & SA_RESTART) &&
|
||||
ts->signal_in_syscall) {
|
||||
ts->signal_restart = 1;
|
||||
}
|
||||
return 1; /* indicates that the signal was queued */
|
||||
}
|
||||
}
|
||||
@@ -636,8 +648,24 @@ int do_sigaction(int sig, const struct target_sigaction *act,
|
||||
if (host_sig != SIGSEGV && host_sig != SIGBUS) {
|
||||
sigfillset(&act1.sa_mask);
|
||||
act1.sa_flags = SA_SIGINFO;
|
||||
#ifdef TARGET_ARM
|
||||
/* Breaks boehm-gc, we have to do this manually */
|
||||
/*
|
||||
* Unfortunately our hacks only work as long as we don't do parallel
|
||||
* signal delivery and futexes, so let's do a dirty hack here to
|
||||
* pin our guest process to a single host CPU if we're using the
|
||||
* boehm-gc.
|
||||
*/
|
||||
if ((k->sa_flags & TARGET_SA_RESTART) && host_sig == SIGPWR) {
|
||||
cpu_set_t mask;
|
||||
CPU_ZERO(&mask);
|
||||
CPU_SET(0, &mask);
|
||||
sched_setaffinity(0, sizeof(mask), &mask);
|
||||
}
|
||||
#else
|
||||
if (k->sa_flags & TARGET_SA_RESTART)
|
||||
act1.sa_flags |= SA_RESTART;
|
||||
#endif
|
||||
/* NOTE: it is important to update the host kernel signal
|
||||
ignore state to avoid getting unexpected interrupted
|
||||
syscalls */
|
||||
|
@@ -3302,6 +3302,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++;
|
||||
@@ -3682,6 +3687,13 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static abi_long do_ioctl_fail(const IOCTLEntry *ie, uint8_t *buf_temp, int fd,
|
||||
abi_long cmd, abi_long arg)
|
||||
{
|
||||
/* Fail silently */
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static IOCTLEntry ioctl_entries[] = {
|
||||
#define IOCTL(cmd, access, ...) \
|
||||
{ TARGET_ ## cmd, cmd, #cmd, access, 0, { __VA_ARGS__ } },
|
||||
@@ -3705,7 +3717,12 @@ static abi_long do_ioctl(int fd, abi_long 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)
|
||||
@@ -3734,6 +3751,11 @@ static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
|
||||
arg_type++;
|
||||
target_size = thunk_type_size(arg_type, 0);
|
||||
switch(ie->access) {
|
||||
/* FIXME: actually the direction given in the ioctl should be
|
||||
* correct so we can assume the communication is uni-directional.
|
||||
* The alsa developers did not like this concept though and
|
||||
* declared ioctls IOC_R and IOC_W even though they were IOC_RW.*/
|
||||
/*
|
||||
case IOC_R:
|
||||
ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
|
||||
if (!is_error(ret)) {
|
||||
@@ -3752,6 +3774,7 @@ static abi_long do_ioctl(int fd, abi_long cmd, abi_long arg)
|
||||
unlock_user(argptr, arg, 0);
|
||||
ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp));
|
||||
break;
|
||||
*/
|
||||
default:
|
||||
case IOC_RW:
|
||||
argptr = lock_user(VERIFY_READ, arg, target_size, 1);
|
||||
@@ -4382,6 +4405,15 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
|
||||
if (nptl_flags & CLONE_SETTLS)
|
||||
cpu_set_tls (new_env, newtls);
|
||||
|
||||
/* agraf: Pin ourselves to a single CPU when running multi-threaded.
|
||||
This turned out to improve stability for me. */
|
||||
{
|
||||
cpu_set_t mask;
|
||||
CPU_ZERO(&mask);
|
||||
CPU_SET(0, &mask);
|
||||
sched_setaffinity(0, sizeof(mask), &mask);
|
||||
}
|
||||
|
||||
/* Grab a mutex so that thread setup appears atomic. */
|
||||
pthread_mutex_lock(&clone_lock);
|
||||
|
||||
@@ -5056,6 +5088,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)
|
||||
{
|
||||
TaskState *ts = ((CPUArchState *)cpu_env)->opaque;
|
||||
@@ -5096,6 +5147,7 @@ static int do_open(void *cpu_env, const char *pathname, int flags, mode_t mode)
|
||||
{ "/proc/self/maps", open_self_maps },
|
||||
{ "/proc/self/stat", open_self_stat },
|
||||
{ "/proc/self/auxv", open_self_auxv },
|
||||
{ "/proc/cpuinfo", open_cpuinfo },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
@@ -5134,18 +5186,105 @@ static int do_open(void *cpu_env, const char *pathname, int flags, mode_t mode)
|
||||
return get_errno(open(path(pathname), flags, mode));
|
||||
}
|
||||
|
||||
int syscall_restartable(int syscall_nr)
|
||||
{
|
||||
switch (syscall_nr) {
|
||||
#ifdef TARGET_NR_sigsuspend
|
||||
case TARGET_NR_sigsuspend:
|
||||
#endif
|
||||
#ifdef TARGET_NR_pause
|
||||
case TARGET_NR_pause:
|
||||
#endif
|
||||
#ifdef TARGET_NR_setsockopt
|
||||
case TARGET_NR_setsockopt:
|
||||
#endif
|
||||
#ifdef TARGET_NR_accept
|
||||
case TARGET_NR_accept:
|
||||
#endif
|
||||
#ifdef TARGET_NR_recv
|
||||
case TARGET_NR_recv:
|
||||
#endif
|
||||
#ifdef TARGET_NR_recvfrom
|
||||
case TARGET_NR_recvfrom:
|
||||
#endif
|
||||
#ifdef TARGET_NR_recvmsg
|
||||
case TARGET_NR_recvmsg:
|
||||
#endif
|
||||
#ifdef TARGET_NR_socketcall
|
||||
case TARGET_NR_socketcall:
|
||||
#endif
|
||||
#ifdef TARGET_NR_connect
|
||||
case TARGET_NR_connect:
|
||||
#endif
|
||||
#ifdef TARGET_NR_send
|
||||
case TARGET_NR_send:
|
||||
#endif
|
||||
#ifdef TARGET_NR_sendmsg
|
||||
case TARGET_NR_sendmsg:
|
||||
#endif
|
||||
#ifdef TARGET_NR_sendto
|
||||
case TARGET_NR_sendto:
|
||||
#endif
|
||||
#ifdef TARGET_NR_poll
|
||||
case TARGET_NR_poll:
|
||||
#endif
|
||||
#ifdef TARGET_NR_ppoll
|
||||
case TARGET_NR_ppoll:
|
||||
#endif
|
||||
#if defined(TARGET_NR_select)
|
||||
case TARGET_NR_select:
|
||||
#endif
|
||||
#ifdef TARGET_NR_pselect6
|
||||
case TARGET_NR_pselect6:
|
||||
#endif
|
||||
#ifdef TARGET_NR__newselect
|
||||
case TARGET_NR__newselect:
|
||||
#endif
|
||||
#ifdef TARGET_NR_msgrcv
|
||||
case TARGET_NR_msgrcv:
|
||||
#endif
|
||||
#ifdef TARGET_NR_msgsnd
|
||||
case TARGET_NR_msgsnd:
|
||||
#endif
|
||||
#ifdef TARGET_NR_semop
|
||||
case TARGET_NR_semop:
|
||||
#endif
|
||||
#ifdef TARGET_NR_ipc
|
||||
case TARGET_NR_ipc:
|
||||
#endif
|
||||
#ifdef TARGET_NR_clock_nanosleep
|
||||
case TARGET_NR_clock_nanosleep:
|
||||
#endif
|
||||
case TARGET_NR_rt_sigsuspend:
|
||||
case TARGET_NR_rt_sigtimedwait:
|
||||
case TARGET_NR_nanosleep:
|
||||
case TARGET_NR_close:
|
||||
/* can not be restarted */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* every other syscall can be restarted */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
abi_long ret;
|
||||
struct stat st;
|
||||
struct statfs stfs;
|
||||
void *p;
|
||||
TaskState *ts = ((CPUArchState*)cpu_env)->opaque;
|
||||
|
||||
if (!ts->signal_restart) {
|
||||
/* remember syscall info for restart */
|
||||
ts->signal_in_syscall = 1;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
gemu_log("syscall %d", num);
|
||||
@@ -5458,9 +5597,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_END) {
|
||||
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:
|
||||
@@ -6198,6 +6342,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))
|
||||
@@ -7496,7 +7642,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
unlock_user(p, arg1, ret);
|
||||
break;
|
||||
case TARGET_NR_capget:
|
||||
goto unimplemented;
|
||||
goto unimplemented_nowarn;
|
||||
case TARGET_NR_capset:
|
||||
goto unimplemented;
|
||||
case TARGET_NR_sigaltstack:
|
||||
@@ -8154,7 +8300,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
cmd = target_to_host_fcntl_cmd(arg2);
|
||||
if (cmd == -TARGET_EINVAL) {
|
||||
ret = cmd;
|
||||
break;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
switch(arg2) {
|
||||
@@ -8515,6 +8661,11 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(TARGET_NR_timer_create)
|
||||
case TARGET_NR_timer_create:
|
||||
goto unimplemented_nowarn;
|
||||
#endif
|
||||
|
||||
#if defined(TARGET_NR_tkill) && defined(__NR_tkill)
|
||||
case TARGET_NR_tkill:
|
||||
ret = get_errno(sys_tkill((int)arg1, target_to_host_signal(arg2)));
|
||||
@@ -8911,6 +9062,7 @@ fail:
|
||||
#endif
|
||||
if(do_strace)
|
||||
print_syscall_ret(num, ret);
|
||||
ts->signal_in_syscall = 0;
|
||||
return ret;
|
||||
efault:
|
||||
ret = -TARGET_EFAULT;
|
||||
|
@@ -885,6 +885,12 @@ struct target_pollfd {
|
||||
#define TARGET_BLKGETSIZE64 TARGET_IOR(0x12,114,abi_ulong)
|
||||
/* return device size in bytes
|
||||
(u64 *arg) */
|
||||
#define TARGET_BLKDISCARD TARGET_IO(0x12,119)
|
||||
#define TARGET_BLKIOMIN TARGET_IO(0x12,120)
|
||||
#define TARGET_BLKIOOPT TARGET_IO(0x12,121)
|
||||
#define TARGET_BLKALIGNOFF TARGET_IO(0x12,122)
|
||||
#define TARGET_BLKPBSZGET TARGET_IO(0x12,123)
|
||||
#define TARGET_BLKDISCARDZEROES TARGET_IO(0x12,124)
|
||||
#define TARGET_FIBMAP TARGET_IO(0x00,1) /* bmap access */
|
||||
#define TARGET_FIGETBSZ TARGET_IO(0x00,2) /* get the block size used for bmap */
|
||||
#define TARGET_FS_IOC_FIEMAP TARGET_IOWR('f',11,struct fiemap)
|
||||
@@ -1016,6 +1022,7 @@ struct target_pollfd {
|
||||
#define TARGET_LOOP_SET_STATUS64 0x4C04
|
||||
#define TARGET_LOOP_GET_STATUS64 0x4C05
|
||||
#define TARGET_LOOP_CHANGE_FD 0x4C06
|
||||
#define TARGET_LOOP_BOGUS_CMD 0x4C82
|
||||
|
||||
/* fb ioctls */
|
||||
#define TARGET_FBIOGET_VSCREENINFO 0x4600
|
||||
@@ -2343,6 +2350,9 @@ struct target_eabi_flock64 {
|
||||
#define TARGET_MTIOCGET TARGET_IOR('m', 2, struct mtget)
|
||||
#define TARGET_MTIOCPOS TARGET_IOR('m', 3, struct mtpos)
|
||||
|
||||
#define TARGET_FS_IOC_GETFLAGS TARGET_IORU('f', 1)
|
||||
#define TARGET_FS_IOC_SETFLAGS TARGET_IOWU('f', 2)
|
||||
|
||||
struct target_sysinfo {
|
||||
abi_long uptime; /* Seconds since boot */
|
||||
abi_ulong loads[3]; /* 1, 5, and 15 minute load averages */
|
||||
@@ -2425,3 +2435,5 @@ struct target_ucred {
|
||||
uint32_t uid;
|
||||
uint32_t gid;
|
||||
};
|
||||
|
||||
#include "ioctls_alsa_structs.h"
|
||||
|
@@ -71,6 +71,9 @@ STRUCT(kbentry,
|
||||
STRUCT(kbsentry,
|
||||
TYPE_CHAR, MK_ARRAY(TYPE_CHAR, 512))
|
||||
|
||||
STRUCT(blkdiscard,
|
||||
MK_ARRAY(TYPE_LONGLONG, 2))
|
||||
|
||||
STRUCT(audio_buf_info,
|
||||
TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT)
|
||||
|
||||
@@ -83,6 +86,11 @@ STRUCT(buffmem_desc,
|
||||
STRUCT(mixer_info,
|
||||
MK_ARRAY(TYPE_CHAR, 16), MK_ARRAY(TYPE_CHAR, 32), TYPE_INT, MK_ARRAY(TYPE_INT, 10))
|
||||
|
||||
/* FIXME: including these on x86 / x86_64 breaks qemu-i386 */
|
||||
#ifdef __powerpc__
|
||||
#include "syscall_types_alsa.h"
|
||||
#endif
|
||||
|
||||
/* loop device ioctls */
|
||||
STRUCT(loop_info,
|
||||
TYPE_INT, /* lo_number */
|
||||
|
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
22
net.c
22
net.c
@@ -138,6 +138,27 @@ void qemu_format_nic_info_str(NetClientState *nc, uint8_t macaddr[6])
|
||||
macaddr[3], macaddr[4], macaddr[5]);
|
||||
}
|
||||
|
||||
static void default_mac_check(void)
|
||||
{
|
||||
static const MACAddr def_mac = { .a = { 0x52,0x54,0x00,0x12,0x34,0x56 } };
|
||||
static int warned = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < MAX_NICS; i++)
|
||||
{
|
||||
if (!nd_table[i].used)
|
||||
continue;
|
||||
if (memcmp(nd_table[i].macaddr.a, def_mac.a, 5))
|
||||
continue;
|
||||
if (nd_table[i].macaddr.a[5] >= 0x56 &&
|
||||
nd_table[i].macaddr.a[5] < 0x56 + MAX_NICS && !warned) {
|
||||
warned = 1;
|
||||
fprintf(stderr, "Warning: default mac address being used, creating "
|
||||
"potential for address conflict\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void qemu_macaddr_default_if_unset(MACAddr *macaddr)
|
||||
{
|
||||
static int index = 0;
|
||||
@@ -1010,6 +1031,7 @@ int net_init_clients(void)
|
||||
if (qemu_opts_foreach(net, net_init_client, NULL, 1) == -1) {
|
||||
return -1;
|
||||
}
|
||||
default_mac_check();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Binary file not shown.
BIN
pc-bios/bios.bin
BIN
pc-bios/bios.bin
Binary file not shown.
BIN
pc-bios/q35-acpi-dsdt.aml
Normal file
BIN
pc-bios/q35-acpi-dsdt.aml
Normal file
Binary file not shown.
@@ -177,16 +177,14 @@ bool aio_pending(AioContext *ctx);
|
||||
* aio as a result of executing I/O completion or bh callbacks.
|
||||
*
|
||||
* If there is no pending AIO operation or completion (bottom half),
|
||||
* return false. If there are pending bottom halves, return true.
|
||||
* return false. If there are pending AIO operations of bottom halves,
|
||||
* return true.
|
||||
*
|
||||
* If there are no pending bottom halves, but there are pending AIO
|
||||
* operations, it may not be possible to make any progress without
|
||||
* blocking. If @blocking is true, this function will wait until one
|
||||
* or more AIO events have completed, to ensure something has moved
|
||||
* before returning.
|
||||
*
|
||||
* If @blocking is false, this function will also return false if the
|
||||
* function cannot make any progress without blocking.
|
||||
*/
|
||||
bool aio_poll(AioContext *ctx, bool blocking);
|
||||
|
||||
|
16
qemu-char.c
16
qemu-char.c
@@ -241,6 +241,9 @@ typedef struct {
|
||||
IOEventHandler *chr_event[MAX_MUX];
|
||||
void *ext_opaque[MAX_MUX];
|
||||
CharDriverState *drv;
|
||||
#if defined(TARGET_S390X)
|
||||
QEMUTimer *accept_timer;
|
||||
#endif
|
||||
int focus;
|
||||
int mux_cnt;
|
||||
int term_got_escape;
|
||||
@@ -397,6 +400,15 @@ static void mux_chr_accept_input(CharDriverState *chr)
|
||||
d->chr_read[m](d->ext_opaque[m],
|
||||
&d->buffer[m][d->cons[m]++ & MUX_BUFFER_MASK], 1);
|
||||
}
|
||||
|
||||
#if defined(TARGET_S390X)
|
||||
/* We're still not able to sync producer and consumer, so let's wait a bit
|
||||
and try again by then. */
|
||||
if (d->prod[m] != d->cons[m]) {
|
||||
qemu_mod_timer(d->accept_timer, qemu_get_clock_ns(vm_clock)
|
||||
+ (int64_t)100000);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static int mux_chr_can_read(void *opaque)
|
||||
@@ -479,6 +491,10 @@ static CharDriverState *qemu_chr_open_mux(CharDriverState *drv)
|
||||
chr->opaque = d;
|
||||
d->drv = drv;
|
||||
d->focus = -1;
|
||||
#if defined(TARGET_S390X)
|
||||
d->accept_timer = qemu_new_timer_ns(vm_clock,
|
||||
(QEMUTimerCB*)mux_chr_accept_input, chr);
|
||||
#endif
|
||||
chr->chr_write = mux_chr_write;
|
||||
chr->chr_update_read_handler = mux_chr_update_read_handler;
|
||||
chr->chr_accept_input = mux_chr_accept_input;
|
||||
|
@@ -421,7 +421,7 @@ static void become_daemon(const char *pidfile)
|
||||
}
|
||||
}
|
||||
|
||||
umask(0);
|
||||
umask(S_IRWXG | S_IRWXO);
|
||||
sid = setsid();
|
||||
if (sid < 0) {
|
||||
goto fail;
|
||||
|
@@ -671,7 +671,7 @@ static int img_convert(int argc, char **argv)
|
||||
const uint8_t *buf1;
|
||||
BlockDriverInfo bdi;
|
||||
QEMUOptionParameter *param = NULL, *create_options = NULL;
|
||||
QEMUOptionParameter *out_baseimg_param;
|
||||
QEMUOptionParameter *out_baseimg_param, *scsi;
|
||||
char *options = NULL;
|
||||
const char *snapshot_name = NULL;
|
||||
float local_progress = 0;
|
||||
@@ -864,6 +864,12 @@ static int img_convert(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
if ((scsi = get_option_parameter(param, BLOCK_OPT_SCSI)) && scsi->value.n && strcmp(drv->format_name, "vmdk")) {
|
||||
error_report("SCSI devices not supported for this file format");
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Create the new image */
|
||||
ret = bdrv_create(drv, out_filename, param);
|
||||
if (ret < 0) {
|
||||
|
10
qemu-lock.h
10
qemu-lock.h
@@ -24,6 +24,12 @@
|
||||
#include <pthread.h>
|
||||
#define spin_lock pthread_mutex_lock
|
||||
#define spin_unlock pthread_mutex_unlock
|
||||
static inline void spin_unlock_safe(pthread_mutex_t *lock)
|
||||
{
|
||||
/* unlocking an unlocked mutex results in undefined behavior */
|
||||
pthread_mutex_trylock(lock);
|
||||
pthread_mutex_unlock(lock);
|
||||
}
|
||||
#define spinlock_t pthread_mutex_t
|
||||
#define SPIN_LOCK_UNLOCKED PTHREAD_MUTEX_INITIALIZER
|
||||
|
||||
@@ -46,4 +52,8 @@ static inline void spin_unlock(spinlock_t *lock)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void spin_unlock_safe(spinlock_t *lock)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -1258,6 +1258,15 @@ STEXI
|
||||
Disable HPET support.
|
||||
ETEXI
|
||||
|
||||
DEF("no-stopflag", 0, QEMU_OPTION_no_stopflag,
|
||||
"-no-stopflag use old behaviour, not inline stopflag checks\n", QEMU_ARCH_ALL)
|
||||
STEXI
|
||||
@item -no-stopflag
|
||||
@findex -no-stopflag
|
||||
Implement cpu-exit by the old tb link breaking method rather than inline checks
|
||||
(this is slightly faster but racy!)
|
||||
ETEXI
|
||||
|
||||
DEF("acpitable", HAS_ARG, QEMU_OPTION_acpitable,
|
||||
"-acpitable [sig=str][,rev=n][,oem_id=str][,oem_table_id=str][,oem_rev=n][,asl_compiler_id=str][,asl_compiler_rev=n][,{data|file}=file1[:file2]...]\n"
|
||||
" ACPI table description\n", QEMU_ARCH_I386)
|
||||
@@ -2417,6 +2426,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,10 +52,10 @@ pixman_image_t *qemu_pixman_linebuf_create(pixman_format_code_t format,
|
||||
}
|
||||
|
||||
void qemu_pixman_linebuf_fill(pixman_image_t *linebuf, pixman_image_t *fb,
|
||||
int width, int y)
|
||||
int width, int x, int y)
|
||||
{
|
||||
pixman_image_composite(PIXMAN_OP_SRC, fb, NULL, linebuf,
|
||||
0, y, 0, 0, 0, 0, width, 1);
|
||||
x, y, 0, 0, 0, 0, width, 1);
|
||||
}
|
||||
|
||||
pixman_image_t *qemu_pixman_mirror_create(pixman_format_code_t format,
|
||||
|
@@ -31,7 +31,7 @@ pixman_format_code_t qemu_pixman_get_format(PixelFormat *pf);
|
||||
pixman_image_t *qemu_pixman_linebuf_create(pixman_format_code_t format,
|
||||
int width);
|
||||
void qemu_pixman_linebuf_fill(pixman_image_t *linebuf, pixman_image_t *fb,
|
||||
int width, int y);
|
||||
int width, int x, int y);
|
||||
pixman_image_t *qemu_pixman_mirror_create(pixman_format_code_t format,
|
||||
pixman_image_t *image);
|
||||
void qemu_pixman_image_unref(pixman_image_t *image);
|
||||
|
@@ -122,7 +122,7 @@ void qemu_sem_init(QemuSemaphore *sem, int init)
|
||||
{
|
||||
int rc;
|
||||
|
||||
#if defined(__OpenBSD__) || defined(__APPLE__) || defined(__NetBSD__)
|
||||
#if defined(__APPLE__) || defined(__NetBSD__)
|
||||
rc = pthread_mutex_init(&sem->lock, NULL);
|
||||
if (rc != 0) {
|
||||
error_exit(rc, __func__);
|
||||
@@ -147,7 +147,7 @@ void qemu_sem_destroy(QemuSemaphore *sem)
|
||||
{
|
||||
int rc;
|
||||
|
||||
#if defined(__OpenBSD__) || defined(__APPLE__) || defined(__NetBSD__)
|
||||
#if defined(__APPLE__) || defined(__NetBSD__)
|
||||
rc = pthread_cond_destroy(&sem->cond);
|
||||
if (rc < 0) {
|
||||
error_exit(rc, __func__);
|
||||
@@ -168,7 +168,7 @@ void qemu_sem_post(QemuSemaphore *sem)
|
||||
{
|
||||
int rc;
|
||||
|
||||
#if defined(__OpenBSD__) || defined(__APPLE__) || defined(__NetBSD__)
|
||||
#if defined(__APPLE__) || defined(__NetBSD__)
|
||||
pthread_mutex_lock(&sem->lock);
|
||||
if (sem->count == INT_MAX) {
|
||||
rc = EINVAL;
|
||||
@@ -206,13 +206,14 @@ int qemu_sem_timedwait(QemuSemaphore *sem, int ms)
|
||||
int rc;
|
||||
struct timespec ts;
|
||||
|
||||
#if defined(__OpenBSD__) || defined(__APPLE__) || defined(__NetBSD__)
|
||||
#if defined(__APPLE__) || defined(__NetBSD__)
|
||||
compute_abs_deadline(&ts, ms);
|
||||
pthread_mutex_lock(&sem->lock);
|
||||
--sem->count;
|
||||
while (sem->count < 0) {
|
||||
rc = pthread_cond_timedwait(&sem->cond, &sem->lock, &ts);
|
||||
if (rc == ETIMEDOUT) {
|
||||
++sem->count;
|
||||
break;
|
||||
}
|
||||
if (rc != 0) {
|
||||
@@ -248,7 +249,7 @@ int qemu_sem_timedwait(QemuSemaphore *sem, int ms)
|
||||
|
||||
void qemu_sem_wait(QemuSemaphore *sem)
|
||||
{
|
||||
#if defined(__OpenBSD__) || defined(__APPLE__) || defined(__NetBSD__)
|
||||
#if defined(__APPLE__) || defined(__NetBSD__)
|
||||
pthread_mutex_lock(&sem->lock);
|
||||
--sem->count;
|
||||
while (sem->count < 0) {
|
||||
|
@@ -12,7 +12,7 @@ struct QemuCond {
|
||||
};
|
||||
|
||||
struct QemuSemaphore {
|
||||
#if defined(__OpenBSD__) || defined(__APPLE__) || defined(__NetBSD__)
|
||||
#if defined(__APPLE__) || defined(__NetBSD__)
|
||||
pthread_mutex_t lock;
|
||||
pthread_cond_t cond;
|
||||
int count;
|
||||
|
@@ -15,6 +15,9 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/wait.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include "qga/guest-agent-core.h"
|
||||
#include "qga-qmp-commands.h"
|
||||
#include "qerror.h"
|
||||
@@ -125,9 +128,135 @@ static GuestFileHandle *guest_file_handle_find(int64_t id)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
typedef const char * const ccpc;
|
||||
|
||||
#ifndef O_BINARY
|
||||
#define O_BINARY 0
|
||||
#endif
|
||||
|
||||
/* http://pubs.opengroup.org/onlinepubs/9699919799/functions/fopen.html */
|
||||
static const struct {
|
||||
ccpc *forms;
|
||||
int oflag_base;
|
||||
} guest_file_open_modes[] = {
|
||||
{ (ccpc[]){ "r", NULL }, O_RDONLY },
|
||||
{ (ccpc[]){ "rb", NULL }, O_RDONLY | O_BINARY },
|
||||
{ (ccpc[]){ "w", NULL }, O_WRONLY | O_CREAT | O_TRUNC },
|
||||
{ (ccpc[]){ "wb", NULL }, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY },
|
||||
{ (ccpc[]){ "a", NULL }, O_WRONLY | O_CREAT | O_APPEND },
|
||||
{ (ccpc[]){ "ab", NULL }, O_WRONLY | O_CREAT | O_APPEND | O_BINARY },
|
||||
{ (ccpc[]){ "r+", NULL }, O_RDWR },
|
||||
{ (ccpc[]){ "rb+", "r+b", NULL }, O_RDWR | O_BINARY },
|
||||
{ (ccpc[]){ "w+", NULL }, O_RDWR | O_CREAT | O_TRUNC },
|
||||
{ (ccpc[]){ "wb+", "w+b", NULL }, O_RDWR | O_CREAT | O_TRUNC | O_BINARY },
|
||||
{ (ccpc[]){ "a+", NULL }, O_RDWR | O_CREAT | O_APPEND },
|
||||
{ (ccpc[]){ "ab+", "a+b", NULL }, O_RDWR | O_CREAT | O_APPEND | O_BINARY }
|
||||
};
|
||||
|
||||
static int
|
||||
find_open_flag(const char *mode_str, Error **err)
|
||||
{
|
||||
unsigned mode;
|
||||
|
||||
for (mode = 0; mode < ARRAY_SIZE(guest_file_open_modes); ++mode) {
|
||||
ccpc *form;
|
||||
|
||||
form = guest_file_open_modes[mode].forms;
|
||||
while (*form != NULL && strcmp(*form, mode_str) != 0) {
|
||||
++form;
|
||||
}
|
||||
if (*form != NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mode == ARRAY_SIZE(guest_file_open_modes)) {
|
||||
error_setg(err, "invalid file open mode '%s'", mode_str);
|
||||
return -1;
|
||||
}
|
||||
return guest_file_open_modes[mode].oflag_base | O_NOCTTY | O_NONBLOCK;
|
||||
}
|
||||
|
||||
#define DEFAULT_NEW_FILE_MODE (S_IRUSR | S_IWUSR | \
|
||||
S_IRGRP | S_IWGRP | \
|
||||
S_IROTH | S_IWOTH)
|
||||
|
||||
static FILE *
|
||||
safe_open_or_create(const char *path, const char *mode, Error **err)
|
||||
{
|
||||
Error *local_err = NULL;
|
||||
int oflag;
|
||||
|
||||
oflag = find_open_flag(mode, &local_err);
|
||||
if (local_err == NULL) {
|
||||
int fd;
|
||||
|
||||
/* If the caller wants / allows creation of a new file, we implement it
|
||||
* with a two step process: open() + (open() / fchmod()).
|
||||
*
|
||||
* First we insist on creating the file exclusively as a new file. If
|
||||
* that succeeds, we're free to set any file-mode bits on it. (The
|
||||
* motivation is that we want to set those file-mode bits independently
|
||||
* of the current umask.)
|
||||
*
|
||||
* If the exclusive creation fails because the file already exists
|
||||
* (EEXIST is not possible for any other reason), we just attempt to
|
||||
* open the file, but in this case we won't be allowed to change the
|
||||
* file-mode bits on the preexistent file.
|
||||
*
|
||||
* The pathname should never disappear between the two open()s in
|
||||
* practice. If it happens, then someone very likely tried to race us.
|
||||
* In this case just go ahead and report the ENOENT from the second
|
||||
* open() to the caller.
|
||||
*
|
||||
* If the caller wants to open a preexistent file, then the first
|
||||
* open() is decisive and its third argument is ignored, and the second
|
||||
* open() and the fchmod() are never called.
|
||||
*/
|
||||
fd = open(path, oflag | ((oflag & O_CREAT) ? O_EXCL : 0), 0);
|
||||
if (fd == -1 && errno == EEXIST) {
|
||||
oflag &= ~(unsigned)O_CREAT;
|
||||
fd = open(path, oflag);
|
||||
}
|
||||
|
||||
if (fd == -1) {
|
||||
error_setg_errno(&local_err, errno, "failed to open file '%s' "
|
||||
"(mode: '%s')", path, mode);
|
||||
} else {
|
||||
qemu_set_cloexec(fd);
|
||||
|
||||
if ((oflag & O_CREAT) && fchmod(fd, DEFAULT_NEW_FILE_MODE) == -1) {
|
||||
error_setg_errno(&local_err, errno, "failed to set permission "
|
||||
"0%03o on new file '%s' (mode: '%s')",
|
||||
(unsigned)DEFAULT_NEW_FILE_MODE, path, mode);
|
||||
} else {
|
||||
FILE *f;
|
||||
|
||||
f = fdopen(fd, mode);
|
||||
if (f == NULL) {
|
||||
error_setg_errno(&local_err, errno, "failed to associate "
|
||||
"stdio stream with file descriptor %d, "
|
||||
"file '%s' (mode: '%s')", fd, path, mode);
|
||||
} else {
|
||||
return f;
|
||||
}
|
||||
}
|
||||
|
||||
close(fd);
|
||||
if (oflag & O_CREAT) {
|
||||
unlink(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
error_propagate(err, local_err);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int64_t qmp_guest_file_open(const char *path, bool has_mode, const char *mode, Error **err)
|
||||
{
|
||||
FILE *fh;
|
||||
Error *local_err = NULL;
|
||||
int fd;
|
||||
int64_t ret = -1;
|
||||
|
||||
@@ -135,9 +264,9 @@ int64_t qmp_guest_file_open(const char *path, bool has_mode, const char *mode, E
|
||||
mode = "r";
|
||||
}
|
||||
slog("guest-file-open called, filepath: %s, mode: %s", path, mode);
|
||||
fh = fopen(path, mode);
|
||||
if (!fh) {
|
||||
error_set(err, QERR_OPEN_FILE_FAILED, path);
|
||||
fh = safe_open_or_create(path, mode, &local_err);
|
||||
if (local_err != NULL) {
|
||||
error_propagate(err, local_err);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
Submodule roms/seabios updated: b1c35f2b28...a810e4e72a
@@ -27,43 +27,46 @@ case "$cpu" in
|
||||
armv[4-9]*)
|
||||
cpu="arm"
|
||||
;;
|
||||
sparc*)
|
||||
cpu="sparc"
|
||||
;;
|
||||
esac
|
||||
|
||||
# register the interpreter for each cpu except for the native one
|
||||
if [ $cpu != "i386" ] ; then
|
||||
echo ':i386:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-i386:' > /proc/sys/fs/binfmt_misc/register
|
||||
echo ':i486:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x06\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-i386:' > /proc/sys/fs/binfmt_misc/register
|
||||
echo ':i386:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-i386-binfmt:P' > /proc/sys/fs/binfmt_misc/register
|
||||
echo ':i486:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x06\x00:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-i386-binfmt:P' > /proc/sys/fs/binfmt_misc/register
|
||||
fi
|
||||
if [ $cpu != "alpha" ] ; then
|
||||
echo ':alpha:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x26\x90:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-alpha:' > /proc/sys/fs/binfmt_misc/register
|
||||
echo ':alpha:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x26\x90:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-alpha-binfmt:P' > /proc/sys/fs/binfmt_misc/register
|
||||
fi
|
||||
if [ $cpu != "arm" ] ; then
|
||||
echo ':arm:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-arm:' > /proc/sys/fs/binfmt_misc/register
|
||||
echo ':armeb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-armeb:' > /proc/sys/fs/binfmt_misc/register
|
||||
echo ':arm:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-arm-binfmt:P' > /proc/sys/fs/binfmt_misc/register
|
||||
echo ':armeb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-armeb-binfmt:P' > /proc/sys/fs/binfmt_misc/register
|
||||
fi
|
||||
if [ $cpu != "sparc" ] ; then
|
||||
echo ':sparc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-sparc:' > /proc/sys/fs/binfmt_misc/register
|
||||
echo ':sparc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-sparc-binfmt:P' > /proc/sys/fs/binfmt_misc/register
|
||||
fi
|
||||
if [ $cpu != "ppc" ] ; then
|
||||
echo ':ppc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-ppc:' > /proc/sys/fs/binfmt_misc/register
|
||||
echo ':ppc:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x14:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-ppc-binfmt:P' > /proc/sys/fs/binfmt_misc/register
|
||||
fi
|
||||
if [ $cpu != "m68k" ] ; then
|
||||
echo 'Please check cpu value and header information for m68k!'
|
||||
echo ':m68k:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x04:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-m68k:' > /proc/sys/fs/binfmt_misc/register
|
||||
echo ':m68k:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x04:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-m68k-binfmt:P' > /proc/sys/fs/binfmt_misc/register
|
||||
fi
|
||||
if [ $cpu != "mips" ] ; then
|
||||
# FIXME: We could use the other endianness on a MIPS host.
|
||||
echo ':mips:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-mips:' > /proc/sys/fs/binfmt_misc/register
|
||||
echo ':mipsel:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-mipsel:' > /proc/sys/fs/binfmt_misc/register
|
||||
echo ':mipsn32:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-mipsn32:' > /proc/sys/fs/binfmt_misc/register
|
||||
echo ':mipsn32el:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-mipsn32el:' > /proc/sys/fs/binfmt_misc/register
|
||||
echo ':mips64:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-mips64:' > /proc/sys/fs/binfmt_misc/register
|
||||
echo ':mips64el:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-mips64el:' > /proc/sys/fs/binfmt_misc/register
|
||||
echo ':mips:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-mips-binfmt:P' > /proc/sys/fs/binfmt_misc/register
|
||||
echo ':mipsel:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-mipsel-binfmt:P' > /proc/sys/fs/binfmt_misc/register
|
||||
echo ':mipsn32:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-mipsn32-binfmt:P' > /proc/sys/fs/binfmt_misc/register
|
||||
echo ':mipsn32el:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-mipsn32el-binfmt:P' > /proc/sys/fs/binfmt_misc/register
|
||||
echo ':mips64:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-mips64-binfmt:P' > /proc/sys/fs/binfmt_misc/register
|
||||
echo ':mips64el:M::\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x08\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-mips64el-binfmt:P' > /proc/sys/fs/binfmt_misc/register
|
||||
fi
|
||||
if [ $cpu != "sh" ] ; then
|
||||
echo ':sh4:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a\x00:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/local/bin/qemu-sh4:' > /proc/sys/fs/binfmt_misc/register
|
||||
echo ':sh4eb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-sh4eb:' > /proc/sys/fs/binfmt_misc/register
|
||||
echo ':sh4:M::\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a\x00:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-sh4-binfmt:P' > /proc/sys/fs/binfmt_misc/register
|
||||
echo ':sh4eb:M::\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x2a:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-sh4eb-binfmt:P' > /proc/sys/fs/binfmt_misc/register
|
||||
fi
|
||||
if [ $cpu != "s390x" ] ; then
|
||||
echo ':s390x:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x16:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/local/bin/qemu-s390x:' > /proc/sys/fs/binfmt_misc/register
|
||||
echo ':s390x:M::\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x16:\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff:/usr/bin/qemu-s390x-binfmt:P' > /proc/sys/fs/binfmt_misc/register
|
||||
fi
|
||||
|
@@ -531,6 +531,8 @@ sorecvfrom(struct socket *so)
|
||||
} /* if ping packet */
|
||||
}
|
||||
|
||||
extern int slirp_nooutgoing;
|
||||
|
||||
/*
|
||||
* sendto() a socket
|
||||
*/
|
||||
@@ -561,6 +563,12 @@ sosendto(struct socket *so, struct mbuf *m)
|
||||
|
||||
DEBUG_MISC((dfd, " sendto()ing, addr.sin_port=%d, addr.sin_addr.s_addr=%.16s\n", ntohs(addr.sin_port), inet_ntoa(addr.sin_addr)));
|
||||
|
||||
/* Only allow DNS requests */
|
||||
if (slirp_nooutgoing && ntohs(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, sizeof (struct sockaddr));
|
||||
|
@@ -324,6 +324,9 @@ 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)
|
||||
{
|
||||
Slirp *slirp = so->slirp;
|
||||
@@ -332,6 +335,11 @@ int tcp_fconnect(struct socket *so)
|
||||
DEBUG_CALL("tcp_fconnect");
|
||||
DEBUG_ARG("so = %lx", (long )so);
|
||||
|
||||
if (slirp_nooutgoing) {
|
||||
errno = EHOSTUNREACH;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( (ret = so->s = qemu_socket(AF_INET,SOCK_STREAM,0)) >= 0) {
|
||||
int opt, s=so->s;
|
||||
struct sockaddr_in addr;
|
||||
@@ -424,6 +432,13 @@ tcp_connect(struct socket *inso)
|
||||
tcp_close(sototcpcb(so)); /* This will sofree() as well */
|
||||
return;
|
||||
}
|
||||
|
||||
if (slirp_nooutgoing && addr.sin_addr.s_addr != slirp_nooutgoing) {
|
||||
tcp_close(sototcpcb(so)); /* This will sofree() as well */
|
||||
close(s);
|
||||
return;
|
||||
}
|
||||
|
||||
socket_set_nonblock(s);
|
||||
opt = 1;
|
||||
setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int));
|
||||
@@ -434,6 +449,7 @@ tcp_connect(struct socket *inso)
|
||||
|
||||
so->so_fport = addr.sin_port;
|
||||
so->so_faddr = addr.sin_addr;
|
||||
|
||||
/* Translate connections from localhost to the real hostname */
|
||||
if (so->so_faddr.s_addr == 0 ||
|
||||
(so->so_faddr.s_addr & loopback_mask) ==
|
||||
|
@@ -124,7 +124,11 @@ static void arm_cpu_reset(CPUState *s)
|
||||
* bake assumptions about into translated code, so we need to
|
||||
* tb_flush().
|
||||
*/
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
/* XXX hack alert! automoc4 segaults after spawning a new thread with this
|
||||
flush enabled */
|
||||
tb_flush(env);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void set_feature(CPUARMState *env, int feature)
|
||||
|
@@ -3152,7 +3152,7 @@ target_ulong helper_##name(CPUMIPSState *env, target_ulong rs, \
|
||||
\
|
||||
filter = ((int32_t)0x01 << size) - 1; \
|
||||
filter = filter << pos; \
|
||||
temprs = rs & filter; \
|
||||
temprs = (rs << pos) & filter; \
|
||||
temprt = rt & ~filter; \
|
||||
temp = temprs | temprt; \
|
||||
\
|
||||
@@ -3814,17 +3814,18 @@ void helper_shilo(target_ulong ac, target_ulong rs, CPUMIPSState *env)
|
||||
|
||||
rs5_0 = rs & 0x3F;
|
||||
rs5_0 = (int8_t)(rs5_0 << 2) >> 2;
|
||||
rs5_0 = MIPSDSP_ABS(rs5_0);
|
||||
|
||||
if (unlikely(rs5_0 == 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
acc = (((uint64_t)env->active_tc.HI[ac] << 32) & MIPSDSP_LHI) |
|
||||
((uint64_t)env->active_tc.LO[ac] & MIPSDSP_LLO);
|
||||
if (rs5_0 == 0) {
|
||||
temp = acc;
|
||||
|
||||
if (rs5_0 > 0) {
|
||||
temp = acc >> rs5_0;
|
||||
} else {
|
||||
if (rs5_0 > 0) {
|
||||
temp = acc >> rs5_0;
|
||||
} else {
|
||||
temp = acc << rs5_0;
|
||||
}
|
||||
temp = acc << -rs5_0;
|
||||
}
|
||||
|
||||
env->active_tc.HI[ac] = (target_ulong)(int32_t)((temp & MIPSDSP_LHI) >> 32);
|
||||
|
@@ -486,7 +486,8 @@ static int get_physical_addr_mmu(CPUXtensaState *env, bool update_tlb,
|
||||
INST_FETCH_PRIVILEGE_CAUSE;
|
||||
}
|
||||
|
||||
*access = mmu_attr_to_access(entry->attr);
|
||||
*access = mmu_attr_to_access(entry->attr) &
|
||||
~(dtlb ? PAGE_EXEC : PAGE_READ | PAGE_WRITE);
|
||||
if (!is_access_granted(*access, is_write)) {
|
||||
return dtlb ?
|
||||
(is_write ?
|
||||
|
@@ -2962,7 +2962,11 @@ static void gen_intermediate_code_internal(
|
||||
gen_icount_end(tb, insn_count);
|
||||
*tcg_ctx.gen_opc_ptr = INDEX_op_end;
|
||||
|
||||
if (!search_pc) {
|
||||
if (search_pc) {
|
||||
j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
|
||||
memset(gen_opc_instr_start + lj + 1, 0,
|
||||
(j - lj) * sizeof(gen_opc_instr_start[0]));
|
||||
} else {
|
||||
tb->size = dc.pc - pc_start;
|
||||
tb->icount = insn_count;
|
||||
}
|
||||
|
@@ -1145,7 +1145,7 @@ static inline void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
|
||||
TCG_REG_R0, SHIFT_IMM_LSL(CPU_TLB_ENTRY_BITS));
|
||||
/* We assume that the offset is contained within 20 bits. */
|
||||
tlb_offset = offsetof(CPUArchState, tlb_table[mem_index][0].addr_read);
|
||||
assert(tlb_offset & ~0xfffff == 0);
|
||||
assert((tlb_offset & ~0xfffff) == 0);
|
||||
if (tlb_offset > 0xfff) {
|
||||
tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R0, TCG_REG_R0,
|
||||
0xa00 | (tlb_offset >> 12));
|
||||
@@ -1354,7 +1354,7 @@ static inline void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
|
||||
TCG_AREG0, TCG_REG_R0, SHIFT_IMM_LSL(CPU_TLB_ENTRY_BITS));
|
||||
/* We assume that the offset is contained within 20 bits. */
|
||||
tlb_offset = offsetof(CPUArchState, tlb_table[mem_index][0].addr_write);
|
||||
assert(tlb_offset & ~0xfffff == 0);
|
||||
assert((tlb_offset & ~0xfffff) == 0);
|
||||
if (tlb_offset > 0xfff) {
|
||||
tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R0, TCG_REG_R0,
|
||||
0xa00 | (tlb_offset >> 12));
|
||||
|
36
tcg/tcg.c
36
tcg/tcg.c
@@ -40,6 +40,8 @@
|
||||
#include "cache-utils.h"
|
||||
#include "host-utils.h"
|
||||
#include "qemu-timer.h"
|
||||
#include "config-host.h"
|
||||
#include "qemu-thread.h"
|
||||
|
||||
/* Note: the long term plan is to reduce the dependancies on the QEMU
|
||||
CPU definitions. Currently they are used for qemu_ld/st
|
||||
@@ -96,6 +98,29 @@ const size_t tcg_op_defs_max = ARRAY_SIZE(tcg_op_defs);
|
||||
static TCGRegSet tcg_target_available_regs[2];
|
||||
static TCGRegSet tcg_target_call_clobber_regs;
|
||||
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
static __thread int tcg_lock_count;
|
||||
#endif
|
||||
void tcg_lock(void)
|
||||
{
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
TCGContext *s = &tcg_ctx;
|
||||
if (tcg_lock_count++ == 0) {
|
||||
qemu_mutex_lock(&s->lock);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void tcg_unlock(void)
|
||||
{
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
TCGContext *s = &tcg_ctx;
|
||||
if (--tcg_lock_count == 0) {
|
||||
qemu_mutex_unlock(&s->lock);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void tcg_out8(TCGContext *s, uint8_t v)
|
||||
{
|
||||
*s->code_ptr++ = v;
|
||||
@@ -235,7 +260,8 @@ void tcg_context_init(TCGContext *s)
|
||||
|
||||
memset(s, 0, sizeof(*s));
|
||||
s->nb_globals = 0;
|
||||
|
||||
qemu_mutex_init(&s->lock);
|
||||
|
||||
/* Count total number of arguments and allocate the corresponding
|
||||
space */
|
||||
total_args = 0;
|
||||
@@ -2342,11 +2368,13 @@ int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf)
|
||||
}
|
||||
#endif
|
||||
|
||||
tcg_lock();
|
||||
tcg_gen_code_common(s, gen_code_buf, -1);
|
||||
|
||||
/* flush instruction cache */
|
||||
flush_icache_range((tcg_target_ulong)gen_code_buf,
|
||||
(tcg_target_ulong)s->code_ptr);
|
||||
tcg_unlock();
|
||||
|
||||
return s->code_ptr - gen_code_buf;
|
||||
}
|
||||
@@ -2357,7 +2385,11 @@ int tcg_gen_code(TCGContext *s, uint8_t *gen_code_buf)
|
||||
Return -1 if not found. */
|
||||
int tcg_gen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset)
|
||||
{
|
||||
return tcg_gen_code_common(s, gen_code_buf, offset);
|
||||
int r;
|
||||
tcg_lock();
|
||||
r = tcg_gen_code_common(s, gen_code_buf, offset);
|
||||
tcg_unlock();
|
||||
return r;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PROFILER
|
||||
|
@@ -46,6 +46,8 @@ typedef uint64_t tcg_target_ulong;
|
||||
#error unsupported
|
||||
#endif
|
||||
|
||||
#include "config-host.h"
|
||||
#include "qemu-thread.h"
|
||||
#include "tcg-target.h"
|
||||
#include "tcg-runtime.h"
|
||||
|
||||
@@ -462,6 +464,7 @@ struct TCGContext {
|
||||
TCGLabelQemuLdst *qemu_ldst_labels;
|
||||
int nb_qemu_ldst_labels;
|
||||
#endif
|
||||
QemuMutex lock;
|
||||
};
|
||||
|
||||
extern TCGContext tcg_ctx;
|
||||
@@ -641,6 +644,9 @@ void tcg_gen_shifti_i64(TCGv_i64 ret, TCGv_i64 arg1,
|
||||
TCGArg *tcg_optimize(TCGContext *s, uint16_t *tcg_opc_ptr, TCGArg *args,
|
||||
TCGOpDef *tcg_op_def);
|
||||
|
||||
extern void tcg_lock(void);
|
||||
extern void tcg_unlock(void);
|
||||
|
||||
/* only used for debugging purposes */
|
||||
void tcg_register_helper(void *func, const char *name);
|
||||
const char *tcg_helper_get_name(TCGContext *s, void *func);
|
||||
|
@@ -10,7 +10,7 @@ int main()
|
||||
dsp = 0x305;
|
||||
rt = 0x12345678;
|
||||
rs = 0x87654321;
|
||||
result = 0x12345338;
|
||||
result = 0x12345438;
|
||||
__asm
|
||||
("wrdsp %2, 0x03\n\t"
|
||||
"insv %0, %1\n\t"
|
||||
|
@@ -23,5 +23,23 @@ int main()
|
||||
assert(ach == resulth);
|
||||
assert(acl == resultl);
|
||||
|
||||
|
||||
ach = 0x1;
|
||||
acl = 0x80000000;
|
||||
|
||||
resulth = 0x3;
|
||||
resultl = 0x0;
|
||||
|
||||
__asm
|
||||
("mthi %0, $ac1\n\t"
|
||||
"mtlo %1, $ac1\n\t"
|
||||
"shilo $ac1, -1\n\t"
|
||||
"mfhi %0, $ac1\n\t"
|
||||
"mflo %1, $ac1\n\t"
|
||||
: "+r"(ach), "+r"(acl)
|
||||
);
|
||||
assert(ach == resulth);
|
||||
assert(acl == resultl);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -25,5 +25,25 @@ int main()
|
||||
assert(ach == resulth);
|
||||
assert(acl == resultl);
|
||||
|
||||
|
||||
rs = 0xffffffff;
|
||||
ach = 0x1;
|
||||
acl = 0x80000000;
|
||||
|
||||
resulth = 0x3;
|
||||
resultl = 0x0;
|
||||
|
||||
__asm
|
||||
("mthi %0, $ac1\n\t"
|
||||
"mtlo %1, $ac1\n\t"
|
||||
"shilov $ac1, %2\n\t"
|
||||
"mfhi %0, $ac1\n\t"
|
||||
"mflo %1, $ac1\n\t"
|
||||
: "+r"(ach), "+r"(acl)
|
||||
: "r"(rs)
|
||||
);
|
||||
assert(ach == resulth);
|
||||
assert(acl == resultl);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -315,13 +315,13 @@ static void test_wait_event_notifier_noflush(void)
|
||||
event_notifier_set(&data.e);
|
||||
g_assert(aio_poll(ctx, false));
|
||||
g_assert_cmpint(data.n, ==, 1);
|
||||
g_assert(!aio_poll(ctx, false));
|
||||
g_assert(aio_poll(ctx, false));
|
||||
g_assert_cmpint(data.n, ==, 1);
|
||||
|
||||
event_notifier_set(&data.e);
|
||||
g_assert(aio_poll(ctx, false));
|
||||
g_assert_cmpint(data.n, ==, 2);
|
||||
g_assert(!aio_poll(ctx, false));
|
||||
g_assert(aio_poll(ctx, false));
|
||||
g_assert_cmpint(data.n, ==, 2);
|
||||
|
||||
event_notifier_set(&dummy.e);
|
||||
|
21
thunk.c
21
thunk.c
@@ -41,6 +41,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:
|
||||
@@ -140,6 +141,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);
|
||||
|
3
thunk.h
3
thunk.h
@@ -38,6 +38,7 @@ typedef enum argtype {
|
||||
TYPE_ARRAY,
|
||||
TYPE_STRUCT,
|
||||
TYPE_OLDDEVT,
|
||||
TYPE_INTBITFIELD,
|
||||
} argtype;
|
||||
|
||||
#define MK_PTR(type) TYPE_PTR, type
|
||||
@@ -91,6 +92,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:
|
||||
@@ -153,6 +155,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:
|
||||
|
@@ -732,6 +732,8 @@ int qemu_spice_add_interface(SpiceBaseInstance *sin)
|
||||
*/
|
||||
spice_server = spice_server_new();
|
||||
spice_server_init(spice_server, &core_interface);
|
||||
qemu_add_vm_change_state_handler(vm_change_state_handler,
|
||||
&spice_server);
|
||||
}
|
||||
|
||||
return spice_server_add_interface(spice_server, sin);
|
||||
|
@@ -1212,7 +1212,7 @@ static int send_jpeg_rect(VncState *vs, int x, int y, int w, int h, int quality)
|
||||
buf = (uint8_t *)pixman_image_get_data(linebuf);
|
||||
row[0] = buf;
|
||||
for (dy = 0; dy < h; dy++) {
|
||||
qemu_pixman_linebuf_fill(linebuf, vs->vd->server, w, dy);
|
||||
qemu_pixman_linebuf_fill(linebuf, vs->vd->server, w, x, y + dy);
|
||||
jpeg_write_scanlines(&cinfo, row, 1);
|
||||
}
|
||||
qemu_pixman_image_unref(linebuf);
|
||||
@@ -1356,7 +1356,7 @@ static int send_png_rect(VncState *vs, int x, int y, int w, int h,
|
||||
if (color_type == PNG_COLOR_TYPE_PALETTE) {
|
||||
memcpy(buf, vs->tight.tight.buffer + (dy * w), w);
|
||||
} else {
|
||||
qemu_pixman_linebuf_fill(linebuf, vs->vd->server, w, dy);
|
||||
qemu_pixman_linebuf_fill(linebuf, vs->vd->server, w, x, y + dy);
|
||||
}
|
||||
png_write_row(png_ptr, buf);
|
||||
}
|
||||
|
73
ui/vnc.c
73
ui/vnc.c
@@ -45,6 +45,7 @@ static const struct timeval VNC_REFRESH_LOSSY = { 2, 0 };
|
||||
|
||||
static VncDisplay *vnc_display; /* needed for info vnc */
|
||||
static DisplayChangeListener *dcl;
|
||||
static int allowed_connections = 0;
|
||||
|
||||
static int vnc_cursor_define(VncState *vs);
|
||||
static void vnc_release_modifiers(VncState *vs);
|
||||
@@ -1019,6 +1020,7 @@ static void vnc_disconnect_start(VncState *vs)
|
||||
static void vnc_disconnect_finish(VncState *vs)
|
||||
{
|
||||
int i;
|
||||
static int num_disconnects = 0;
|
||||
|
||||
vnc_jobs_join(vs); /* Wait encoding jobs */
|
||||
|
||||
@@ -1064,6 +1066,13 @@ static void vnc_disconnect_finish(VncState *vs)
|
||||
}
|
||||
g_free(vs->lossy_rect);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
int vnc_client_io_error(VncState *vs, int ret, int last_errno)
|
||||
@@ -2569,7 +2578,7 @@ static int vnc_refresh_server_surface(VncDisplay *vd)
|
||||
uint8_t *server_ptr;
|
||||
|
||||
if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
|
||||
qemu_pixman_linebuf_fill(tmpbuf, vd->guest.fb, width, y);
|
||||
qemu_pixman_linebuf_fill(tmpbuf, vd->guest.fb, width, 0, y);
|
||||
guest_ptr = (uint8_t *)pixman_image_get_data(tmpbuf);
|
||||
} else {
|
||||
guest_ptr = guest_row;
|
||||
@@ -2861,6 +2870,39 @@ char *vnc_display_local_addr(DisplayState *ds)
|
||||
return vnc_socket_local_addr("%s:%s", vs->lsock);
|
||||
}
|
||||
|
||||
static void read_file_password(DisplayState *ds, 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 = malloc(length+1);
|
||||
rc = fread(passwd, 1, length, pfile);
|
||||
fclose(pfile);
|
||||
|
||||
if(rc == length && rc > 0) {
|
||||
vnc_display_password(ds, passwd);
|
||||
}
|
||||
|
||||
free(passwd);
|
||||
}
|
||||
|
||||
void vnc_display_open(DisplayState *ds, const char *display, Error **errp)
|
||||
{
|
||||
VncDisplay *vs = ds ? (VncDisplay *)ds->opaque : vnc_display;
|
||||
@@ -2894,6 +2936,9 @@ void vnc_display_open(DisplayState *ds, const char *display, Error **errp)
|
||||
while ((options = strchr(options, ','))) {
|
||||
options++;
|
||||
if (strncmp(options, "password", 8) == 0) {
|
||||
char *start, *end;
|
||||
start = strchr(options, '=');
|
||||
end = strchr(options, ',');
|
||||
if (fips_get_state()) {
|
||||
error_setg(errp,
|
||||
"VNC password auth disabled due to FIPS mode, "
|
||||
@@ -2902,6 +2947,32 @@ void vnc_display_open(DisplayState *ds, const char *display, Error **errp)
|
||||
goto fail;
|
||||
}
|
||||
password = 1; /* Require password auth */
|
||||
if (start && (!end || (start < end))) {
|
||||
int len = end ? end-(start+1) : strlen(start+1);
|
||||
char *text = g_malloc(len+1);
|
||||
strncpy(text, start+1, len);
|
||||
text[len] = '\0';
|
||||
|
||||
if (strncmp(options, "password-file=", 14) == 0) {
|
||||
read_file_password(ds, text);
|
||||
} else {
|
||||
vnc_display_password(ds, text);
|
||||
}
|
||||
|
||||
free(text);
|
||||
}
|
||||
} else if (strncmp(options, "allowed-connections=", 20) == 0) {
|
||||
char *start, *end;
|
||||
start = strchr(options, '=');
|
||||
end = strchr(options, ',');
|
||||
if (start && (!end || (start < end))) {
|
||||
int len = end ? end-(start+1) : strlen(start+1);
|
||||
char *text = g_malloc(len+1);
|
||||
strncpy(text, start+1, len);
|
||||
text[len] = '\0';
|
||||
VNC_DEBUG("Maximum number of disconnects: %s\n", text);
|
||||
allowed_connections = atoi(text);
|
||||
}
|
||||
} else if (strncmp(options, "reverse", 7) == 0) {
|
||||
reverse = 1;
|
||||
} else if (strncmp(options, "no-lock-key-sync", 16) == 0) {
|
||||
|
10
user-exec.c
10
user-exec.c
@@ -88,12 +88,22 @@ static inline int handle_cpu_signal(uintptr_t pc, unsigned long address,
|
||||
qemu_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? */
|
||||
spin_unlock_safe(&tb_lock);
|
||||
|
||||
/* XXX: locking issue */
|
||||
if (is_write && h2g_valid(address)
|
||||
&& page_unprotect(h2g(address), pc, puc)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (RESERVED_VA) {
|
||||
/* Convert forcefully to guest address space, invalid addresses
|
||||
are still valid segv ones */
|
||||
address = address - GUEST_BASE;
|
||||
}
|
||||
|
||||
/* see if it is an MMU fault */
|
||||
ret = cpu_handle_mmu_fault(cpu_single_env, address, is_write,
|
||||
MMU_USER_IDX);
|
||||
|
14
vl.c
14
vl.c
@@ -177,6 +177,8 @@ int main(int argc, char **argv)
|
||||
|
||||
#define MAX_VIRTIO_CONSOLES 1
|
||||
|
||||
extern int use_stopflag;
|
||||
|
||||
static const char *data_dir;
|
||||
const char *bios_name = NULL;
|
||||
enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB;
|
||||
@@ -215,6 +217,7 @@ const char *vnc_display;
|
||||
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;
|
||||
@@ -2967,6 +2970,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;
|
||||
@@ -3226,6 +3237,9 @@ int main(int argc, char **argv, char **envp)
|
||||
qdev_prop_register_global_list(slew_lost_ticks);
|
||||
break;
|
||||
}
|
||||
case QEMU_OPTION_no_stopflag:
|
||||
use_stopflag = 0;
|
||||
break;
|
||||
case QEMU_OPTION_acpitable:
|
||||
do_acpitable_option(optarg);
|
||||
break;
|
||||
|
@@ -292,7 +292,8 @@ static int xen_add_to_physmap(XenIOState *state,
|
||||
return -1;
|
||||
|
||||
go_physmap:
|
||||
DPRINTF("mapping vram to %llx - %llx\n", start_addr, start_addr + size);
|
||||
DPRINTF("mapping vram to %"HWADDR_PRIx" - %"HWADDR_PRIx"\n",
|
||||
start_addr, start_addr + size);
|
||||
|
||||
pfn = phys_offset >> TARGET_PAGE_BITS;
|
||||
start_gpfn = start_addr >> TARGET_PAGE_BITS;
|
||||
@@ -365,8 +366,8 @@ static int xen_remove_from_physmap(XenIOState *state,
|
||||
phys_offset = physmap->phys_offset;
|
||||
size = physmap->size;
|
||||
|
||||
DPRINTF("unmapping vram to %llx - %llx, from %llx\n",
|
||||
phys_offset, phys_offset + size, start_addr);
|
||||
DPRINTF("unmapping vram to %"HWADDR_PRIx" - %"HWADDR_PRIx", from ",
|
||||
"%"HWADDR_PRIx"\n", phys_offset, phys_offset + size, start_addr);
|
||||
|
||||
size >>= TARGET_PAGE_BITS;
|
||||
start_addr >>= TARGET_PAGE_BITS;
|
||||
|
Reference in New Issue
Block a user