Compare commits

...

72 Commits

Author SHA1 Message Date
Gerd Hoffmann
bd4f41a27f cirrus: add blit_is_unsafe call to cirrus_bitblt_cputovideo (CVE-2017-2620)
CIRRUS_BLTMODE_MEMSYSSRC blits do NOT check blit destination
and blit width, at all.  Oops.  Fix it.

Security impact: high.

The missing blit destination check allows to write to host memory.
Basically same as CVE-2014-8106 for the other blit variants.

Cc: qemu-stable@nongnu.org
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 92f2b88cea)
[BR: BSC#1024972]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2017-02-28 20:35:39 -07:00
Gerd Hoffmann
f369059a4f cirrus: fix patterncopy checks
The blit_region_is_unsafe checks don't work correctly for the
patterncopy source.  It's a fixed-sized region, which doesn't
depend on cirrus_blt_{width,height}.  So go do the check in
cirrus_bitblt_common_patterncopy instead, then tell blit_is_unsafe that
it doesn't need to verify the source.  Also handle the case where we
blit from cirrus_bitbuf correctly.

This patch replaces 5858dd1801.

Security impact:  I think for the most part error on the safe side this
time, refusing blits which should have been allowed.

Only exception is placing the blit source at the end of the video ram,
so cirrus_blt_srcaddr + 256 goes beyond the end of video memory.  But
even in that case I'm not fully sure this actually allows read access to
host memory.  To trick the commit 5858dd18 security checks one has to
pick very small cirrus_blt_{width,height} values, which in turn implies
only a fraction of the blit source will actually be used.

Cc: Wolfgang Bumiller <w.bumiller@proxmox.com>
Cc: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
Reviewed-by: Laurent Vivier <lvivier@redhat.com>
Message-id: 1486645341-5010-1-git-send-email-kraxel@redhat.com
(cherry picked from commit 95280c31cd)
Signed-off-by: Bruce Rogers <brogers@suse.com>
2017-02-28 20:35:35 -07:00
Gerd Hoffmann
cb184e87cf virtio-gpu: fix resource leak in virgl_cmd_resource_unref
When the guest sends VIRTIO_GPU_CMD_RESOURCE_UNREF without detaching the
backing storage beforehand (VIRTIO_GPU_CMD_RESOURCE_DETACH_BACKING)
we'll leak memory.

This patch fixes it for 3d mode, simliar to the 2d mode fix in commit
"b8e2392 virtio-gpu: call cleanup mapping function in resource destroy".

Reported-by: 李强 <liqiang6-s@360.cn>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 1485167210-4757-1-git-send-email-kraxel@redhat.com
(cherry picked from commit 5e8e3c4c75)
[BR: CVE-2017-5857 BSC#1023073]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2017-02-28 20:27:39 -07:00
Prasad J Pandit
f774e0e5e6 sd: sdhci: check data length during dma_memory_read
While doing multi block SDMA transfer in routine
'sdhci_sdma_transfer_multi_blocks', the 's->fifo_buffer' starting
index 'begin' and data length 's->data_count' could end up to be same.
This could lead to an OOB access issue. Correct transfer data length
to avoid it.

Cc: qemu-stable@nongnu.org
Reported-by: Jiang Xin <jiangxin1@huawei.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20170130064736.9236-1-ppandit@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
(cherry picked from commit 42922105be)
[BR: CVE-2017-5667 BSC#1022541]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2017-02-28 20:27:39 -07:00
Prasad J Pandit
424bd9dd9c usb: ccid: check ccid apdu length
CCID device emulator uses Application Protocol Data Units(APDU)
to exchange command and responses to and from the host.
The length in these units couldn't be greater than 65536. Add
check to ensure the same. It'd also avoid potential integer
overflow in emulated_apdu_from_guest.

Reported-by: Li Qiang <liqiang6-s@360.cn>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Message-id: 20170202192228.10847-1-ppandit@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit c7dfbf3225)
[BR: CVE-2017-5898 BSC#1023907]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2017-02-28 20:27:39 -07:00
Li Qiang
5ac15a00c1 cirrus: fix oob access issue (CVE-2017-2615)
When doing bitblt copy in backward mode, we should minus the
blt width first just like the adding in the forward mode. This
can avoid the oob access of the front of vga's vram.

Signed-off-by: Li Qiang <liqiang6-s@360.cn>

{ kraxel: with backward blits (negative pitch) addr is the topmost
          address, so check it as-is against vram size ]

Cc: qemu-stable@nongnu.org
Cc: P J P <ppandit@redhat.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Wolfgang Bumiller <w.bumiller@proxmox.com>
Fixes: d3532a0db0 (CVE-2014-8106)
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 1485938101-26602-1-git-send-email-kraxel@redhat.com
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
(cherry picked from commit 62d4c6bd52)
[BR: CVE-2017-2615 BSC#1023004]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2017-02-28 20:27:39 -07:00
Gerd Hoffmann
2d9d551729 cirrus: fix blit address mask handling
Apply the cirrus_addr_mask to cirrus_blt_dstaddr and cirrus_blt_srcaddr
right after assigning them, in cirrus_bitblt_start(), instead of having
this all over the place in the cirrus code, and missing a few places.

Reported-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 1485338996-17095-1-git-send-email-kraxel@redhat.com
(cherry picked from commit 60cd23e851)
Signed-off-by: Bruce Rogers <brogers@suse.com>
2017-02-28 20:27:37 -07:00
Wolfgang Bumiller
3f442b0623 cirrus: handle negative pitch in cirrus_invalidate_region()
cirrus_invalidate_region() calls memory_region_set_dirty()
on a per-line basis, always ranging from off_begin to
off_begin+bytesperline. With a negative pitch off_begin
marks the top most used address and thus we need to do an
initial shift backwards by a line for negative pitches of
backward blits, otherwise the first iteration covers the
line going from the start offset forwards instead of
backwards.
Additionally since the start address is inclusive, if we
shift by a full `bytesperline` we move to the first address
*not* included in the blit, so we only shift by one less
than bytesperline.

Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
Message-id: 1485352137-29367-1-git-send-email-w.bumiller@proxmox.com

[ kraxel: codestyle fixes ]

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit f153b563f8)
Signed-off-by: Bruce Rogers <brogers@suse.com>
2017-02-28 19:37:58 -07:00
Paolo Bonzini
27db53c8bd megasas: fix guest-triggered memory leak
If the guest sets the sglist size to a value >=2GB, megasas_handle_dcmd
will return MFI_STAT_MEMORY_NOT_AVAILABLE without freeing the memory.
Avoid this by returning only the status from map_dcmd, and loading
cmd->iov_size in the caller.

Reported-by: Li Qiang <liqiang6-s@360.cn>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 765a707000)
[BR: CVE-2017-5856 BSC#1023053]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2017-02-28 19:36:36 -07:00
Li Qiang
ebc039becf audio: ac97: add exit function
Currently the ac97 device emulation doesn't have a exit function,
hot unplug this device will leak some memory. Add a exit function to
avoid this.

Signed-off-by: Li Qiang <liqiang6-s@360.cn>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-id: 58520052.4825ed0a.27a71.6cae@mx.google.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 12351a91da)
[BR: CVE-2017-5525 BSC#1020491]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2017-02-28 19:34:42 -07:00
Li Qiang
6a847bb812 audio: es1370: add exit function
Currently the es1370 device emulation doesn't have a exit function,
hot unplug this device will leak some memory. Add a exit function to
avoid this.

Signed-off-by: Li Qiang <liqiang6-s@360.cn>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-id: 585200c9.a968ca0a.1ab80.4c98@mx.google.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 069eb7b2b8)
[BR: CVE-2017-5526 BSC#1020589]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2017-02-28 19:33:44 -07:00
Halil Pasic
d1d06f7db5 virtio: fix vq->inuse recalc after migr
Correct recalculation of vq->inuse after migration for the corner case
where the avail_idx has already wrapped but used_idx not yet.

Also change the type of the VirtQueue.inuse to unsigned int. This is
done to be consistent with other members representing sizes (VRing.num),
and because C99 guarantees max ring size < UINT_MAX but does not
guarantee max ring size < INT_MAX.

Signed-off-by: Halil Pasic <pasic@linux.vnet.ibm.com>
Fixes: bccdef6b ("virtio: recalculate vq->inuse after migration")
CC: qemu-stable@nongnu.org
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
(cherry picked from commit e66bcc4081)
[BR: BSC#1020928]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2017-02-28 19:32:51 -07:00
Li Qiang
536ae1665b virtio-gpu: fix memory leak in resource attach backing
In the resource attach backing function, everytime it will
allocate 'res->iov' thus can leading a memory leak. This
patch avoid this.

Signed-off-by: Li Qiang <liq3ea@gmail.com>
Message-id: 1483003721-65360-1-git-send-email-liq3ea@gmail.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 204f01b309)
[BR: CVE-2017-5578 BSC#1021481]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2017-02-28 19:31:37 -07:00
Li Qiang
07cbf6021a virtio-gpu-3d: fix memory leak in resource attach backing
If the virgl_renderer_resource_attach_iov function fails the
'res_iovs' will be leaked. Add check of the return value to
free the 'res_iovs' when failing.

Signed-off-by: Li Qiang <liq3ea@gmail.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-id: 1482999086-59795-1-git-send-email-liq3ea@gmail.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 33243031da)
[BR: CVE-2017-5552 BSC#1021195]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2017-02-28 19:30:43 -07:00
Li Qiang
56fb083af9 watchdog: 6300esb: add exit function
When the Intel 6300ESB watchdog is hot unplug. The timer allocated
in realize isn't freed thus leaking memory leak. This patch avoid
this through adding the exit function.

Signed-off-by: Li Qiang <liqiang6-s@360.cn>
Message-Id: <583cde9c.3223ed0a.7f0c2.886e@mx.google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit eb7a20a361)
[BR: CVE-2016-10155 BSC#1021129]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2017-02-28 19:27:43 -07:00
Prasad J Pandit
818182d604 display: virtio-gpu-3d: check virgl capabilities max_size
Virtio GPU device while processing 'VIRTIO_GPU_CMD_GET_CAPSET'
command, retrieves the maximum capabilities size to fill in the
response object. It continues to fill in capabilities even if
retrieved 'max_size' is zero(0), thus resulting in OOB access.
Add check to avoid it.

Reported-by: Zhenhao Hong <zhenhaohong@gmail.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Message-id: 20161214070156.23368-1-ppandit@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit abd7f08b23)
[BR: CVE-2016-10028 BSC#1017084 BSC#1016503]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2017-02-28 19:25:55 -07:00
Bruce Rogers
5525a02cb6 tests: check path to avoid a failing qga/get-vcpus test
The qga/get-vcpus test fails in a simple chroot environment, as
used in an openSUSE Build Service local build, so first check
that the sysfs based path exists in order to avoid calling this
test in an environment where it won't work right.

Signed-off-by: Bruce Rogers <brogers@suse.com>
2017-02-27 20:47:33 -07:00
Bruce Rogers
a31edb2865 linux-user: exclude cpu model code when building linux-user
A section of s390_realize_cpu_model() needed to be guarded by
CONFIG_USER_ONLY. This omission was causing a segfault when
testing the executable being built for the s390x qemu-linux-user
package.

Signed-off-by: Bruce Rogers <brogers@suse.com>
2017-02-14 14:50:28 -07:00
David Hildenbrand
52f9cd6fd4 target/s390x: use "qemu" cpu model in user mode
"any" does not exist, therefore resulting in a misleading error message.

Reported-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: David Hildenbrand <david@redhat.com>
Message-Id: <20170130145025.26475-1-david@redhat.com>
Reviewed-by: Stefan Weil <sw@weilnetz.de>
Reviewed-by: Alexander Graf <agraf@suse.de>
Cc: qemu-stable@nongnu.org
(cherry picked from commit d8923bc754)
Signed-off-by: Bruce Rogers <brogers@suse.com>
2017-02-02 09:40:14 -07:00
Christian Borntraeger
65cef1a069 s390x/kvm: fix small race reboot vs. cmma
Right now we reset all devices before we reset the cmma states.  This
can result in the host kernel discarding guest pages that were
previously in the unused state but already contain a bios or a -kernel
file before the cmma reset has finished.  This race results in random
guest crashes or hangs during very early reboot.

Fixes: 1cd4e0f6f0 ("s390x/cmma: clean up cmma reset")
Cc: qemu-stable@nongnu.org
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
(cherry picked from commit 1a0e4c8b02)
Signed-off-by: Bruce Rogers <brogers@suse.com>
2017-02-02 09:39:58 -07:00
Bruce Rogers
3b4bf7e1b3 display: cirrus: ignore source pitch value as needed in blit_is_unsafe
Commit 4299b90 added a check which is too broad, given that the source
pitch value is not required to be initialized for solid fill operations.
This patch refines the blit_is_unsafe() check to ignore source pitch in
that case. After applying the above commit as a security patch, we
noticed the SLES 11 SP4 guest gui failed to initialize properly.

Signed-off-by: Bruce Rogers <brogers@suse.com>
Message-id: 20170109203520.5619-1-brogers@suse.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 913a87885f)
[BR: BSC#1016779]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2017-01-18 10:29:07 -07:00
Li Qiang
0cfea2b4d6 virtio-gpu: fix information leak in capset get dispatch
In virgl_cmd_get_capset function, it uses g_malloc to allocate
a response struct to the guest. As the 'resp'struct hasn't been full
initialized it will lead the 'resp->padding' field to the guest.
Use g_malloc0 to avoid this.

Signed-off-by: Li Qiang <liqiang6-s@360.cn>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-id: 58188cae.4a6ec20a.3d2d1.aff2@mx.google.com

[ kraxel: resolved conflict ]

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit 85d9d04447)
[BR: CVE-2016-9908 BSC#1014514]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2017-01-18 10:29:06 -07:00
Andreas Färber
e01538b755 tests: Add scsi-disk test
Test scsi-{disk,hd,cd} wwn properties for correct 64-bit parsing.

For now piggyback on virtio-scsi.

Cc: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2017-01-18 10:29:06 -07:00
Andreas Färber
bf1cd7a4b8 tests: Add QOM property unit tests
Add a test for parsing and setting a uint64 property.

Signed-off-by: Andreas Färber <afaerber@suse.de>
2017-01-18 10:29:06 -07:00
Andreas Färber
6afc220927 test-string-input-visitor: Add uint64 test
Test parsing of decimal and hexadecimal uint64 numbers with most
significant bit set.

Signed-off-by: Andreas Färber <afaerber@suse.de>
2017-01-18 10:29:06 -07:00
Andreas Färber
70f17e51a9 test-string-input-visitor: Add int test case
In addition to -42 also parse the maximum int64.

Signed-off-by: Andreas Färber <afaerber@suse.de>
2017-01-18 10:29:06 -07:00
Andreas Färber
8e642bbb73 string-input-visitor: Fix uint64 parsing
All integers would get parsed by strtoll(), not handling the case of
UINT64 properties with the most significient bit set.

Implement a .type_uint64 visitor callback, reusing the existing
parse_str() code through a new argument, using strtoull().

As this is a bug fix, it intentionally ignores checkpatch warnings to
prefer the use of qemu_strto[u]ll() over strto[u]ll().

Cc: qemu-stable@nongnu.org
Signed-off-by: Andreas Färber <afaerber@suse.de>
2017-01-18 10:29:06 -07:00
Li Qiang
7b6b039ba5 virtio-gpu: call cleanup mapping function in resource destroy
If the guest destroy the resource before detach banking, the 'iov'
and 'addrs' field in resource is not freed thus leading memory
leak issue. This patch avoid this.

Signed-off-by: Li Qiang <liq3ea@gmail.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-id: 1480386565-10077-1-git-send-email-liq3ea@gmail.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
(cherry picked from commit b8e23926c5)
BR: CVE-2016-9912 BSC#1014112]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2017-01-18 10:29:05 -07:00
Alexander Graf
992fa3653d ARM: KVM: Enable in-kernel timers with user space gic
When running with KVM enabled, you can choose between emulating the
gic in kernel or user space. If the kernel supports in-kernel virtualization
of the interrupt controller, it will default to that. If not, if will
default to user space emulation.

Unfortunately when running in user mode gic emulation, we miss out on
timer events which are only available from kernel space. This patch leverages
the new kernel/user space notification mechanism for those timer events.

Signed-off-by: Alexander Graf <agraf@suse.de>
2017-01-18 10:29:05 -07:00
Chunyan Liu
be38f2a0ff fix xen hvm direct kernel boot
Since commit a1666142: acpi-build: make ROMs RAM blocks resizeable,
xen HVM direct kernel boot failed. Xen HVM direct kernel boot will
insert a linuxboot.bin or multiboot.bin to /genroms, before this
commit, in acpi_setup, for rom linuxboot.bin/multiboot.bin, it
only needs 0x20000 size; after the commit, it will reserve x16
size for resize, that is 0x200000 size. It causes xen_ram_alloc
failed due to running out of memory.

To resolve it, either:
1. keep using original rom size instead of max size, don't reserve x16 size.
2. guest maxmem needs to be increased. (commit c1d322e6 "xen-hvm: increase
   maxmem before calling xc_domain_populate_physmap" solved the problem for
   a time, by accident. But then it is reverted in commit ffffbb369 due to
   other problem.)

For 2, more discussion is needed about howto. So this patch tries 1, to
use unresizable rom size in xen case in rom_set_mr.

[CYL: BSC#970791]

Signed-off-by: Chunyan Liu <cyliu@suse.com>
2017-01-16 15:30:12 -07:00
Chunyan Liu
87164237f3 Fix tigervnc long press issue
Using xen tools 'xl vncviewer' with tigervnc (default on SLE-12),
found that: the display of the guest is unexpected while keep
pressing a key. We expect the same character multiple times, but
it prints only one time. This happens on a PV guest in text mode.

After debugging, found that tigervnc sends repeated key down events
in this case, to differentiate from user pressing the same key many
times. Vnc server only prints the character when it finally receives
key up event.

To solve this issue, this patch tries to add additional key up event
before the next repeated key down event (if the key is not a control
key).

[CYL: BSC#882405]
Signed-off-by: Chunyan Liu <cyliu@suse.com>
2017-01-16 15:28:40 -07:00
Andreas Färber
54d95bf6b1 acpi_piix4: Fix migration from SLE11 SP2
qemu-kvm 0.15 uses the same GPE format as qemu 1.4, but as version 2
rather than 3.

Addresses part of BNC#812836.

Signed-off-by: Andreas Färber <afaerber@suse.de>
2017-01-16 15:28:23 -07:00
Andreas Färber
de2bd411b2 i8254: Fix migration from SLE11 SP2
qemu-kvm 0.15 had a VMSTATE_UINT32(flags, PITState) field that
qemu 1.4 does not have.

Addresses part of BNC#812836.

Signed-off-by: Andreas Färber <afaerber@suse.de>
2017-01-16 15:28:12 -07:00
Andreas Färber
f29449e6c1 vga: Raise VRAM to 16 MiB for pc-0.15 and below
qemu-kvm.git commit a7fe0297840908a4fd65a1cf742481ccd45960eb
(Extend vram size to 16MB) deviated from qemu.git since kvm-61, and only
in commit 9e56edcf8d (vga: raise default
vgamem size) did qemu.git adjust the VRAM size for v1.2.

Add compatibility properties so that up to and including pc-0.15 we
maintain migration compatibility with qemu-kvm rather than QEMU and
from pc-1.0 on with QEMU (last qemu-kvm release was 1.2).

Addresses part of BNC#812836.

Signed-off-by: Andreas Färber <afaerber@suse.de>
[BR: adjust comma position in list in macro for v2.5.0 compat]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2017-01-16 15:27:45 -07:00
Bruce Rogers
6fef5a1f40 increase x86_64 physical bits to 42
Allow for guests with higher amounts of ram. The current thought
is that 2TB specified on qemu commandline would be an appropriate
limit. Note that this requires the next higher bit value since
the highest address is actually more than 2TB due to the pci
memory hole.

Signed-off-by: Bruce Rogers <brogers@suse.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2017-01-16 15:15:24 -07:00
Andreas Färber
a5f88d11e6 Raise soft address space limit to hard limit
For SLES we want users to be able to use large memory configurations
with KVM without fiddling with ulimit -Sv.

Signed-off-by: Andreas Färber <afaerber@suse.de>
[BR: add include for sys/resource.h]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2017-01-16 15:03:40 -07:00
Bruce Rogers
235fbffb3f roms/Makefile: pass a packaging timestamp to subpackages with date info
Certain rom subpackages build from qemu git-submodules call the date
program to include date information in the packaged binaries. This
causes repeated builds of the package to be different, wkere the only
real difference is due to the fact that time build timestamp has
changed. To promote reproducible builds and avoid customers being
prompted to update packages needlessly, we'll use the timestamp of the
VERSION file as the packaging timestamp for all packages that build in a
timestamp for whatever reason.

[BR: BSC#1011213]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2017-01-11 10:15:08 -07:00
P J P
101b933ef8 net: imx: limit buffer descriptor count
i.MX Fast Ethernet Controller uses buffer descriptors to manage
data flow to/fro receive & transmit queues. While transmitting
packets, it could continue to read buffer descriptors if a buffer
descriptor has length of zero and has crafted values in bd.flags.
Set an upper limit to number of buffer descriptors.

Reported-by: Li Qiang <liqiang6-s@360.cn>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
[BR: CVE-2016-7907 BSC#1002549]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2017-01-11 10:15:08 -07:00
P J P
920c90f434 dma: rc4030: limit interval timer reload value
The JAZZ RC4030 chipset emulator has a periodic timer and
associated interval reload register. The reload value is used
as divider when computing timer's next tick value. If reload
value is large, it could lead to divide by zero error. Limit
the interval reload value to avoid it.

Reported-by: Huawei PSIRT <psirt@huawei.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
[BR: CVE-2016-8667 BSC#1004702]
Signed-off-by: Bruce Rogers <brogers@suse.com>
2017-01-11 10:15:08 -07:00
667601cdfb linux-user: remove all traces of qemu from /proc/self/cmdline
Instead of post-processing the real contents use the remembered target
argv.  That removes all traces of qemu, including command line options,
and handles QEMU_ARGV0.

Signed-off-by: Andreas Schwab <schwab@suse.de>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2017-01-11 10:15:08 -07:00
a420f344ce linux-user: properly test for infinite timeout in poll (#8)
After "linux-user: use target_ulong" the poll syscall was no longer
handling infinite timeout.

/home/abuild/rpmbuild/BUILD/qemu-2.7.0-rc5/linux-user/syscall.c:9773:26: warning: comparison of unsigned expression >= 0 is always true [-Wtype-limits]
                 if (arg3 >= 0) {
                          ^~

Signed-off-by: Andreas Schwab <schwab@suse.de>
2017-01-11 10:15:08 -07:00
markkp
6163925a8a configure: Fix detection of seccomp on s390x
Signed-off-by: Mark Post <mpost@suse.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2017-01-11 10:15:07 -07:00
36996f68dc qemu-binfmt-conf: use qemu-ARCH-binfmt
Signed-off-by: Andreas Schwab <schwab@suse.de>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2017-01-11 10:15:07 -07:00
Bruce Rogers
b05bd87923 qemu-bridge-helper: reduce security profile
Change from using glib alloc and free routines to those
from libc. Also perform safety measure of dropping privs
to user if configured no-caps.

[BR: BOO#988279]
Signed-off-by: Bruce Rogers <brogers@suse.com>
[AF: Rebased for v2.7.0-rc2]
Signed-off-by: Andreas Färber <afaerber@suse.de>
2017-01-11 10:15:07 -07:00
Bruce Rogers
1e4469088f xen_disk: Add suse specific flush disable handling and map to QEMU equiv
Add code to read the suse specific suse-diskcache-disable-flush flag out
of xenstore, and set the equivalent flag within QEMU.

Patch taken from Xen's patch queue, Olaf Hering being the original author.
[bsc#879425]

Signed-off-by: Bruce Rogers <brogers@suse.com>
Signed-off-by: Olaf Hering <olaf@aepfle.de>
2017-01-11 10:15:07 -07:00
Alexander Graf
69fae9cfe2 dictzip: Fix on big endian systems
The dictzip code in SLE11 received some treatment over time to support
running on big endian hosts. Somewhere in the transition to SLE12 this
support got lost. Add it back in again from the SLE11 code base.

Furthermore while at it, fix up the debug prints to not emit warnings.

[AG: BSC#937572]
Signed-off-by: Alexander Graf <agraf@suse.de>
[AF: Rebased for v2.7.0-rc2]
Signed-off-by: Andreas Färber <afaerber@suse.de>
2017-01-11 10:15:07 -07:00
Alexander Graf
9a6dabcb75 AIO: Reduce number of threads for 32bit hosts
On hosts with limited virtual address space (32bit pointers), we can very
easily run out of virtual memory with big thread pools.

Instead, we should limit ourselves to small pools to keep memory footprint
low on those systems.

This patch fixes random VM stalls like

  (process:25114): GLib-ERROR **: gmem.c:103: failed to allocate 1048576 bytes

on 32bit ARM systems for me.

Signed-off-by: Alexander Graf <agraf@suse.de>
2017-01-11 10:15:07 -07:00
Dinar Valeev
1825b6ee2b configure: Enable PIE for ppc and ppc64 hosts
Signed-off-by: Dinar Valeev <dvaleev@suse.com>
[AF: Rebased for v1.7]
Signed-off-by: Andreas Färber <afaerber@suse.de>
2017-01-11 10:15:06 -07:00
Bruce Rogers
68cabc26aa virtfs-proxy-helper: Provide __u64 for broken sys/capability.h
Fixes the build on SLE 11 SP2.

[AF: Extend to ppc64]
2017-01-11 10:15:06 -07:00
Alexander Graf
2be621021e linux-user: lseek: explicitly cast non-set offsets to signed
When doing lseek, SEEK_SET indicates that the offset is an unsigned variable.
Other seek types have parameters that can be negative.

When converting from 32bit to 64bit parameters, we need to take this into
account and enable SEEK_END and SEEK_CUR to be negative, while SEEK_SET stays
absolute positioned which we need to maintain as unsigned.

Signed-off-by: Alexander Graf <agraf@suse.de>
2017-01-11 10:15:06 -07:00
Alexander Graf
047016003b Make char muxer more robust wrt small FIFOs
Virtio-Console can only process one character at a time. Using it on S390
gave me strage "lags" where I got the character I pressed before when
pressing one. So I typed in "abc" and only received "a", then pressed "d"
but the guest received "b" and so on.

While the stdio driver calls a poll function that just processes on its
queue in case virtio-console can't take multiple characters at once, the
muxer does not have such callbacks, so it can't empty its queue.

To work around that limitation, I introduced a new timer that only gets
active when the guest can not receive any more characters. In that case
it polls again after a while to check if the guest is now receiving input.

This patch fixes input when using -nographic on s390 for me.

[AF: Rebased for v2.7.0-rc2]
2017-01-11 10:15:06 -07:00
Alexander Graf
b6dbfd4547 console: add question-mark escape operator
Some termcaps (found using SLES11SP1) use [? sequences. According to man
console_codes (http://linux.die.net/man/4/console_codes) the question mark
is a nop and should simply be ignored.

This patch does exactly that, rendering screen output readable when
outputting guest serial consoles to the graphical console emulator.

Signed-off-by: Alexander Graf <agraf@suse.de>
2017-01-11 10:15:06 -07:00
Alexander Graf
a4e7e274fa Legacy Patch kvm-qemu-preXX-dictzip3.patch 2017-01-11 10:15:06 -07:00
Alexander Graf
dae0d107e0 block: Add tar container format
Tar is a very widely used format to store data in. Sometimes people even put
virtual machine images in there.

So it makes sense for qemu to be able to read from tar files. I implemented a
written from scratch reader that also knows about the GNU sparse format, which
is what pigz creates.

This version checks for filenames that end on well-known extensions. The logic
could be changed to search for filenames given on the command line, but that
would require changes to more parts of qemu.

The tar reader in conjunctiuon with dzip gives us the chance to download
tar'ed up virtual machine images (even via http) and instantly make use of
them.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Bruce Rogers <brogers@novell.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
[TH: Use bdrv_open options instead of filename]
Signed-off-by: Tim Hardeck <thardeck@suse.de>
[AF: bdrv_file_open got an Error **errp argument, bdrv_delete -> brd_unref]
[AF: qemu_opts_create_nofail() -> qemu_opts_create(),
     bdrv_file_open() -> bdrv_open(), based on work by brogers]
[AF: error_is_set() dropped for v2.1.0-rc0]
[AF: BlockDriverAIOCB -> BlockAIOCB,
     BlockDriverCompletionFunc -> BlockCompletionFunc,
     qemu_aio_release() -> qemu_aio_unref(),
     drop tar_aio_cancel()]
[AF: common-obj-y -> block-obj-y, drop probe hook (bsc#945778)]
[AF: Drop bdrv_open() drv parameter for 2.5]
Signed-off-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Bruce Rogers <brogers@suse.com>
[AF: Changed bdrv_open() bs parameter and return value for v2.7.0-rc2,
     for bdrv_pread() and bdrv_aio_readv() s/s->hd/s->hd->file/]
Signed-off-by: Andreas Färber <afaerber@suse.de>
2017-01-11 10:15:05 -07:00
Alexander Graf
2f2838f6f1 block: Add support for DictZip enabled gzip files
DictZip is an extension to the gzip format that allows random seeks in gzip
compressed files by cutting the file into pieces and storing the piece offsets
in the "extra" header of the gzip format.

Thanks to that extension, we can use gzip compressed files as block backend,
though only in read mode.

This makes a lot of sense when stacked with tar files that can then be shipped
to VM users. If a VM image is inside a tar file that is inside a DictZip
enabled gzip file, the user can run the tar.gz file as is without having to
extract the image first.

Tar patch follows.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Bruce Rogers <brogers@novell.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
[TH: Use bdrv_open options instead of filename]
Signed-off-by: Tim Hardeck <thardeck@suse.de>
[AF: Error **errp added for bdrv_file_open, bdrv_delete -> bdrv_unref]
[AF: qemu_opts_create_nofail() -> qemu_opts_create(),
     bdrv_file_open() -> bdrv_open(), based on work by brogers]
[AF: error_is_set() dropped for v2.1.0-rc0]
[AF: BlockDriverAIOCB -> BlockAIOCB,
     BlockDriverCompletionFunc -> BlockCompletionFunc,
     qemu_aio_release() -> qemu_aio_unref(),
     drop dictzip_aio_cancel()]
[AF: common-obj-y -> block-obj-y, drop probe hook (bsc#945778)]
[AF: Drop bdrv_open() drv parameter for 2.5]
Signed-off-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Bruce Rogers <brogers@suse.com>
[AF: Drop bdrv_open() bs parameter and change return value for v2.7.0-rc2,
     for bdrv_pread() and bdrv_aio_readv() do s/s->hd/s->hd->file/]
Signed-off-by: Andreas Färber <afaerber@suse.de>
2017-01-11 10:15:05 -07:00
Alexander Graf
725c9b6ff4 linux-user: use target_ulong
Linux syscalls pass pointers or data length or other information of that sort
to the kernel. This is all stuff you don't want to have sign extended.
Otherwise a host 64bit variable parameter with a size parameter will extend
it to a negative number, breaking lseek for example.

Pass syscall arguments as ulong always.

Signed-off-by: Alexander Graf <agraf@suse.de>
2017-01-11 10:15:05 -07:00
Andreas Färber
4338d0069c vnc: password-file= and incoming-connections=
TBD (from SUSE Studio team)
2017-01-11 10:15:05 -07:00
Andreas Färber
e69941d829 slirp: -nooutgoing
TBD (from SUSE Studio team)
2017-01-11 10:15:05 -07:00
Alexander Graf
772c86a0d0 linux-user: XXX disable fiemap
agraf: fiemap breaks in libarchive. Disable it for now.
2017-01-11 10:15:05 -07:00
Alexander Graf
8af212a8fa linux-user: Fake /proc/cpuinfo
Fedora 17 for ARM reads /proc/cpuinfo and fails if it doesn't contain
ARM related contents. This patch implements a quick hack to expose real
/proc/cpuinfo data taken from a real world machine.

The real fix would be to generate at least the flags automatically based
on the selected CPU. Please do not submit this patch upstream until this
has happened.

Signed-off-by: Alexander Graf <agraf@suse.de>
[AF: Rebased for v1.6 and v1.7]
Signed-off-by: Andreas Färber <afaerber@suse.de>
2017-01-10 14:51:49 -07:00
Alexander Graf
21c1118213 linux-user: binfmt: support host binaries
When we have a working host binary equivalent for the guest binary we're
trying to run, let's just use that instead as it will be a lot faster.

Signed-off-by: Alexander Graf <agraf@suse.de>
2017-01-10 14:04:26 -07:00
Alexander Graf
34a749afcf linux-user: fix segfault deadlock
When entering the guest we take a lock to ensure that nobody else messes
with our TB chaining while we're doing it. If we get a segfault inside that
code, we manage to work on, but will not unlock the lock.

This patch forces unlocking of that lock in the segv handler. I'm not sure
this is the right approach though. Maybe we should rather make sure we don't
segfault in the code? I would greatly appreciate someone more intelligible
than me to look at this :).

Example code to trigger this is at: http://csgraf.de/tmp/conftest.c

Reported-by: Fabio Erculiani <lxnay@sabayon.org>
Signed-off-by: Alexander Graf <agraf@suse.de>
[AF: Drop spinlock_safe_unlock() and switch to tb_lock_reset() (bonzini)]
Signed-off-by: Andreas Färber <afaerber@suse.de>
2017-01-10 14:04:26 -07:00
Alexander Graf
74afa36996 PPC: KVM: Disable mmu notifier check
When using hugetlbfs (which is required for HV mode KVM on 970), we
check for MMU notifiers that on 970 can not be implemented properly.

So disable the check for mmu notifiers on PowerPC guests, making
KVM guests work there, even if possibly racy in some odd circumstances.
2017-01-10 14:04:26 -07:00
Alexander Graf
fd1e321c4e linux-user: add binfmt wrapper for argv[0] handling
When using qemu's linux-user binaries through binfmt, argv[0] gets lost
along the execution because qemu only gets passed in the full file name
to the executable while argv[0] can be something completely different.

This breaks in some subtile situations, such as the grep and make test
suites.

This patch adds a wrapper binary called qemu-$TARGET-binfmt that can be
used with binfmt's P flag which passes the full path _and_ argv[0] to
the binfmt handler.

The binary would be smart enough to be versatile and only exist in the
system once, creating the qemu binary path names from its own argv[0].
However, this seemed like it didn't fit the make system too well, so
we're currently creating a new binary for each target archictecture.

CC: Reinhard Max <max@suse.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
[AF: Rebased onto new Makefile infrastructure, twice]
[AF: Updated for aarch64 for v2.0.0-rc1]
[AF: Rebased onto Makefile changes for v2.1.0-rc0]
[AF: Rebased onto script rewrite for v2.7.0-rc2 - to be fixed]
Signed-off-by: Andreas Färber <afaerber@suse.de>
2017-01-10 14:04:26 -07:00
Alexander Graf
380059e6c4 qemu-cvs-ioctl_nodirection
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.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Ulrich Hecht <uli@suse.de>
2017-01-10 14:04:26 -07:00
Alexander Graf
34dcc1febe qemu-cvs-ioctl_debug
Extends unsupported ioctl debug output.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Ulrich Hecht <uli@suse.de>
2017-01-10 14:04:26 -07:00
Ulrich Hecht
e073096e40 qemu-cvs-gettimeofday
No clue what this is for.
2017-01-10 14:04:26 -07:00
Alexander Graf
9ef9e8d6c4 qemu-cvs-alsa_mmap
Hack to prevent ALSA from using mmap() interface to simplify emulation.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Ulrich Hecht <uli@suse.de>
2017-01-10 14:04:26 -07:00
Alexander Graf
8a4092a66e qemu-cvs-alsa_ioctl
Implements ALSA ioctls on PPC hosts.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Ulrich Hecht <uli@suse.de>
[AF: Rebased for v2.7.0-rc2]
Signed-off-by: Andreas Färber <afaerber@suse.de>
2017-01-10 14:04:25 -07:00
Alexander Graf
beff0040fc qemu-cvs-alsa_bitfield
Implements TYPE_INTBITFIELD partially. (required for ALSA support)

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Ulrich Hecht <uli@suse.de>
2017-01-10 14:04:25 -07:00
Andreas Färber
e9b62c0a3f qemu-binfmt-conf: Modify default path
Change QEMU_PATH from /usr/local/bin to /usr/bin prefix.

Signed-off-by: Andreas Färber <afaerber@suse.de>
2017-01-10 14:04:25 -07:00
Alexander Graf
cf0874f4e2 XXX dont dump core on sigabort 2017-01-10 14:04:25 -07:00
67 changed files with 5501 additions and 125 deletions

View File

@@ -920,6 +920,7 @@ M: Paolo Bonzini <pbonzini@redhat.com>
S: Supported
F: include/hw/scsi/*
F: hw/scsi/*
F: tests/scsi-disk-test.c
F: tests/virtio-scsi-test.c
T: git git://github.com/bonzini/qemu.git scsi-next
@@ -1361,6 +1362,7 @@ F: qom/
X: qom/cpu.c
F: tests/check-qom-interface.c
F: tests/check-qom-proplist.c
F: tests/check-qom-props.c
F: tests/qom-test.c
QMP

View File

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

View File

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

586
block/dictzip.c Normal file
View File

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

379
block/tar.c Normal file
View File

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

5
configure vendored
View File

@@ -1567,7 +1567,7 @@ fi
if test "$pie" = ""; then
case "$cpu-$targetos" in
i386-Linux|x86_64-Linux|x32-Linux|i386-OpenBSD|x86_64-OpenBSD)
i386-Linux|x86_64-Linux|x32-Linux|ppc*-Linux|i386-OpenBSD|x86_64-OpenBSD)
;;
*)
pie="no"
@@ -1928,6 +1928,9 @@ if test "$seccomp" != "no" ; then
ppc|ppc64)
libseccomp_minver="2.3.0"
;;
s390|s390x)
libseccomp_minver="2.2.0"
;;
*)
libseccomp_minver=""
;;

2
exec.c
View File

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

View File

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

View File

@@ -311,7 +311,7 @@ static const VMStateDescription vmstate_cpuhp_state = {
static const VMStateDescription vmstate_acpi = {
.name = "piix4_pm",
.version_id = 3,
.minimum_version_id = 3,
.minimum_version_id = 2, /* qemu-kvm */
.minimum_version_id_old = 1,
.load_state_old = acpi_load_old,
.post_load = vmstate_acpi_post_load,

View File

@@ -623,6 +623,24 @@ static void create_gic(VirtBoardInfo *vbi, qemu_irq *pic, int type,
} else if (type == 2) {
create_v2m(vbi, pic);
}
#ifdef CONFIG_KVM
if (kvm_enabled() && !kvm_irqchip_in_kernel()) {
for (i = 0; i < smp_cpus; i++) {
CPUState *cs = qemu_get_cpu(i);
int ret;
ret = kvm_vcpu_enable_cap(cs, KVM_CAP_ARM_TIMER, 0,
KVM_ARM_TIMER_VTIMER);
if (ret) {
error_report("KVM with user space irqchip only works when the "
"host kernel supports KVM_CAP_ARM_TIMER");
exit(1);
}
}
}
#endif
}
static void create_uart(const VirtBoardInfo *vbi, qemu_irq *pic, int uart,

View File

@@ -1387,6 +1387,16 @@ static void ac97_realize(PCIDevice *dev, Error **errp)
ac97_on_reset (&s->dev.qdev);
}
static void ac97_exit(PCIDevice *dev)
{
AC97LinkState *s = DO_UPCAST(AC97LinkState, dev, dev);
AUD_close_in(&s->card, s->voice_pi);
AUD_close_out(&s->card, s->voice_po);
AUD_close_in(&s->card, s->voice_mc);
AUD_remove_card(&s->card);
}
static int ac97_init (PCIBus *bus)
{
pci_create_simple (bus, -1, "AC97");
@@ -1404,6 +1414,7 @@ static void ac97_class_init (ObjectClass *klass, void *data)
PCIDeviceClass *k = PCI_DEVICE_CLASS (klass);
k->realize = ac97_realize;
k->exit = ac97_exit;
k->vendor_id = PCI_VENDOR_ID_INTEL;
k->device_id = PCI_DEVICE_ID_INTEL_82801AA_5;
k->revision = 0x01;

View File

@@ -1041,6 +1041,19 @@ static void es1370_realize(PCIDevice *dev, Error **errp)
es1370_reset (s);
}
static void es1370_exit(PCIDevice *dev)
{
ES1370State *s = ES1370(dev);
int i;
for (i = 0; i < 2; ++i) {
AUD_close_out(&s->card, s->dac_voice[i]);
}
AUD_close_in(&s->card, s->adc_voice);
AUD_remove_card(&s->card);
}
static int es1370_init (PCIBus *bus)
{
pci_create_simple (bus, -1, TYPE_ES1370);
@@ -1053,6 +1066,7 @@ static void es1370_class_init (ObjectClass *klass, void *data)
PCIDeviceClass *k = PCI_DEVICE_CLASS (klass);
k->realize = es1370_realize;
k->exit = es1370_exit;
k->vendor_id = PCI_VENDOR_ID_ENSONIQ;
k->device_id = PCI_DEVICE_ID_ENSONIQ_ES1370;
k->class_id = PCI_CLASS_MULTIMEDIA_AUDIO;

View File

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

View File

@@ -55,6 +55,7 @@
#include "exec/address-spaces.h"
#include "hw/boards.h"
#include "qemu/cutils.h"
#include "hw/xen/xen.h"
#include <zlib.h>
@@ -858,7 +859,10 @@ static void *rom_set_mr(Rom *rom, Object *owner, const char *name)
void *data;
rom->mr = g_malloc(sizeof(*rom->mr));
memory_region_init_resizeable_ram(rom->mr, owner, name,
if (xen_enabled())
memory_region_init_ram(rom->mr, owner, name, rom->datasize, &error_fatal);
else
memory_region_init_resizeable_ram(rom->mr, owner, name,
rom->datasize, rom->romsize,
fw_cfg_resized,
&error_fatal);

View File

@@ -277,10 +277,9 @@ static bool blit_region_is_unsafe(struct CirrusVGAState *s,
}
if (pitch < 0) {
int64_t min = addr
+ ((int64_t)s->cirrus_blt_height-1) * pitch;
int32_t max = addr
+ s->cirrus_blt_width;
if (min < 0 || max > s->vga.vram_size) {
+ ((int64_t)s->cirrus_blt_height - 1) * pitch
- s->cirrus_blt_width;
if (min < -1 || addr >= s->vga.vram_size) {
return true;
}
} else {
@@ -294,7 +293,7 @@ static bool blit_region_is_unsafe(struct CirrusVGAState *s,
return false;
}
static bool blit_is_unsafe(struct CirrusVGAState *s)
static bool blit_is_unsafe(struct CirrusVGAState *s, bool dst_only)
{
/* should be the case, see cirrus_bitblt_start */
assert(s->cirrus_blt_width > 0);
@@ -305,11 +304,15 @@ static bool blit_is_unsafe(struct CirrusVGAState *s)
}
if (blit_region_is_unsafe(s, s->cirrus_blt_dstpitch,
s->cirrus_blt_dstaddr & s->cirrus_addr_mask)) {
s->cirrus_blt_dstaddr)) {
return true;
}
if (dst_only) {
return false;
}
if (blit_region_is_unsafe(s, s->cirrus_blt_srcpitch,
s->cirrus_blt_srcaddr & s->cirrus_addr_mask)) {
s->cirrus_blt_srcaddr)) {
return true;
}
@@ -658,22 +661,52 @@ static void cirrus_invalidate_region(CirrusVGAState * s, int off_begin,
int off_cur;
int off_cur_end;
if (off_pitch < 0) {
off_begin -= bytesperline - 1;
}
for (y = 0; y < lines; y++) {
off_cur = off_begin;
off_cur_end = (off_cur + bytesperline) & s->cirrus_addr_mask;
assert(off_cur_end >= off_cur);
memory_region_set_dirty(&s->vga.vram, off_cur, off_cur_end - off_cur);
off_begin += off_pitch;
}
}
static int cirrus_bitblt_common_patterncopy(CirrusVGAState * s,
const uint8_t * src)
static int cirrus_bitblt_common_patterncopy(CirrusVGAState *s, bool videosrc)
{
uint32_t patternsize;
uint8_t *dst;
uint8_t *src;
dst = s->vga.vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask);
dst = s->vga.vram_ptr + s->cirrus_blt_dstaddr;
if (blit_is_unsafe(s))
if (videosrc) {
switch (s->vga.get_bpp(&s->vga)) {
case 8:
patternsize = 64;
break;
case 15:
case 16:
patternsize = 128;
break;
case 24:
case 32:
default:
patternsize = 256;
break;
}
s->cirrus_blt_srcaddr &= ~(patternsize - 1);
if (s->cirrus_blt_srcaddr + patternsize > s->vga.vram_size) {
return 0;
}
src = s->vga.vram_ptr + s->cirrus_blt_srcaddr;
} else {
src = s->cirrus_bltbuf;
}
if (blit_is_unsafe(s, true))
return 0;
(*s->cirrus_rop) (s, dst, src,
@@ -691,11 +724,11 @@ static int cirrus_bitblt_solidfill(CirrusVGAState *s, int blt_rop)
{
cirrus_fill_t rop_func;
if (blit_is_unsafe(s)) {
if (blit_is_unsafe(s, true)) {
return 0;
}
rop_func = cirrus_fill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
rop_func(s, s->vga.vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask),
rop_func(s, s->vga.vram_ptr + s->cirrus_blt_dstaddr,
s->cirrus_blt_dstpitch,
s->cirrus_blt_width, s->cirrus_blt_height);
cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
@@ -713,9 +746,7 @@ static int cirrus_bitblt_solidfill(CirrusVGAState *s, int blt_rop)
static int cirrus_bitblt_videotovideo_patterncopy(CirrusVGAState * s)
{
return cirrus_bitblt_common_patterncopy(s,
s->vga.vram_ptr + ((s->cirrus_blt_srcaddr & ~7) &
s->cirrus_addr_mask));
return cirrus_bitblt_common_patterncopy(s, true);
}
static int cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
@@ -769,10 +800,8 @@ static int cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
if (notify)
graphic_hw_update(s->vga.con);
(*s->cirrus_rop) (s, s->vga.vram_ptr +
(s->cirrus_blt_dstaddr & s->cirrus_addr_mask),
s->vga.vram_ptr +
(s->cirrus_blt_srcaddr & s->cirrus_addr_mask),
(*s->cirrus_rop) (s, s->vga.vram_ptr + s->cirrus_blt_dstaddr,
s->vga.vram_ptr + s->cirrus_blt_srcaddr,
s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch,
s->cirrus_blt_width, s->cirrus_blt_height);
@@ -795,7 +824,7 @@ static int cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s)
{
if (blit_is_unsafe(s))
if (blit_is_unsafe(s, false))
return 0;
return cirrus_do_copy(s, s->cirrus_blt_dstaddr - s->vga.start_addr,
@@ -816,15 +845,14 @@ static void cirrus_bitblt_cputovideo_next(CirrusVGAState * s)
if (s->cirrus_srccounter > 0) {
if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
cirrus_bitblt_common_patterncopy(s, s->cirrus_bltbuf);
cirrus_bitblt_common_patterncopy(s, false);
the_end:
s->cirrus_srccounter = 0;
cirrus_bitblt_reset(s);
} else {
/* at least one scan line */
do {
(*s->cirrus_rop)(s, s->vga.vram_ptr +
(s->cirrus_blt_dstaddr & s->cirrus_addr_mask),
(*s->cirrus_rop)(s, s->vga.vram_ptr + s->cirrus_blt_dstaddr,
s->cirrus_bltbuf, 0, 0, s->cirrus_blt_width, 1);
cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, 0,
s->cirrus_blt_width, 1);
@@ -871,6 +899,10 @@ static int cirrus_bitblt_cputovideo(CirrusVGAState * s)
{
int w;
if (blit_is_unsafe(s, true)) {
return 0;
}
s->cirrus_blt_mode &= ~CIRRUS_BLTMODE_MEMSYSSRC;
s->cirrus_srcptr = &s->cirrus_bltbuf[0];
s->cirrus_srcptr_end = &s->cirrus_bltbuf[0];
@@ -896,6 +928,10 @@ static int cirrus_bitblt_cputovideo(CirrusVGAState * s)
}
s->cirrus_srccounter = s->cirrus_blt_srcpitch * s->cirrus_blt_height;
}
/* the blit_is_unsafe call above should catch this */
assert(s->cirrus_blt_srcpitch <= CIRRUS_BLTBUFSIZE);
s->cirrus_srcptr = s->cirrus_bltbuf;
s->cirrus_srcptr_end = s->cirrus_bltbuf + s->cirrus_blt_srcpitch;
cirrus_update_memory_access(s);
@@ -943,6 +979,9 @@ static void cirrus_bitblt_start(CirrusVGAState * s)
s->cirrus_blt_modeext = s->vga.gr[0x33];
blt_rop = s->vga.gr[0x32];
s->cirrus_blt_dstaddr &= s->cirrus_addr_mask;
s->cirrus_blt_srcaddr &= s->cirrus_addr_mask;
#ifdef DEBUG_BITBLT
printf("rop=0x%02x mode=0x%02x modeext=0x%02x w=%d h=%d dpitch=%d spitch=%d daddr=0x%08x saddr=0x%08x writemask=0x%02x\n",
blt_rop,

View File

@@ -77,10 +77,18 @@ static void virgl_cmd_resource_unref(VirtIOGPU *g,
struct virtio_gpu_ctrl_command *cmd)
{
struct virtio_gpu_resource_unref unref;
struct iovec *res_iovs = NULL;
int num_iovs = 0;
VIRTIO_GPU_FILL_CMD(unref);
trace_virtio_gpu_cmd_res_unref(unref.resource_id);
virgl_renderer_resource_detach_iov(unref.resource_id,
&res_iovs,
&num_iovs);
if (res_iovs != NULL && num_iovs != 0) {
virtio_gpu_cleanup_mapping_iov(res_iovs, num_iovs);
}
virgl_renderer_resource_unref(unref.resource_id);
}
@@ -291,8 +299,11 @@ static void virgl_resource_attach_backing(VirtIOGPU *g,
return;
}
virgl_renderer_resource_attach_iov(att_rb.resource_id,
res_iovs, att_rb.nr_entries);
ret = virgl_renderer_resource_attach_iov(att_rb.resource_id,
res_iovs, att_rb.nr_entries);
if (ret != 0)
virtio_gpu_cleanup_mapping_iov(res_iovs, att_rb.nr_entries);
}
static void virgl_resource_detach_backing(VirtIOGPU *g,
@@ -371,8 +382,12 @@ static void virgl_cmd_get_capset(VirtIOGPU *g,
virgl_renderer_get_cap_set(gc.capset_id, &max_ver,
&max_size);
resp = g_malloc(sizeof(*resp) + max_size);
if (!max_size) {
cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER;
return;
}
resp = g_malloc0(sizeof(*resp) + max_size);
resp->hdr.type = VIRTIO_GPU_RESP_OK_CAPSET;
virgl_renderer_fill_caps(gc.capset_id,
gc.capset_version,

View File

@@ -28,6 +28,8 @@
static struct virtio_gpu_simple_resource*
virtio_gpu_find_resource(VirtIOGPU *g, uint32_t resource_id);
static void virtio_gpu_cleanup_mapping(struct virtio_gpu_simple_resource *res);
#ifdef CONFIG_VIRGL
#include <virglrenderer.h>
#define VIRGL(_g, _virgl, _simple, ...) \
@@ -359,6 +361,7 @@ static void virtio_gpu_resource_destroy(VirtIOGPU *g,
struct virtio_gpu_simple_resource *res)
{
pixman_image_unref(res->image);
virtio_gpu_cleanup_mapping(res);
QTAILQ_REMOVE(&g->reslist, res, next);
g_free(res);
}
@@ -705,6 +708,11 @@ virtio_gpu_resource_attach_backing(VirtIOGPU *g,
return;
}
if (res->iov) {
cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;
return;
}
ret = virtio_gpu_create_mapping_iov(&ab, cmd, &res->addrs, &res->iov);
if (ret != 0) {
cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC;

View File

@@ -460,7 +460,7 @@ static void rc4030_write(void *opaque, hwaddr addr, uint64_t data,
break;
/* Interval timer reload */
case 0x0228:
s->itr = val;
s->itr = val & 0x01FF;
qemu_irq_lower(s->timer_irq);
set_next_tick(s);
break;

View File

@@ -770,7 +770,32 @@ DEFINE_I440FX_MACHINE(v1_0, "pc-1.0", pc_compat_1_2,
#define PC_COMPAT_0_15 \
PC_CPU_MODEL_IDS("0.15")
PC_CPU_MODEL_IDS("0.15")\
{\
.driver = "VGA",\
.property = "vgamem_mb",\
.value = stringify(16),\
},{\
.driver = "vmware-svga",\
.property = "vgamem_mb",\
.value = stringify(16),\
},{\
.driver = "qxl-vga",\
.property = "vgamem_mb",\
.value = stringify(16),\
},{\
.driver = "qxl",\
.property = "vgamem_mb",\
.value = stringify(16),\
},{\
.driver = "isa-cirrus-vga",\
.property = "vgamem_mb",\
.value = stringify(16),\
},{\
.driver = "cirrus-vga",\
.property = "vgamem_mb",\
.value = stringify(16),\
},
static void pc_i440fx_0_15_machine_options(MachineClass *m)
{

View File

@@ -10,7 +10,6 @@ common-obj-$(CONFIG_REALVIEW) += realview_gic.o
common-obj-$(CONFIG_SLAVIO) += slavio_intctl.o
common-obj-$(CONFIG_IOAPIC) += ioapic_common.o
common-obj-$(CONFIG_ARM_GIC) += arm_gic_common.o
common-obj-$(CONFIG_ARM_GIC) += arm_gic.o
common-obj-$(CONFIG_ARM_GIC) += arm_gicv2m.o
common-obj-$(CONFIG_ARM_GIC) += arm_gicv3_common.o
common-obj-$(CONFIG_ARM_GIC) += arm_gicv3.o
@@ -21,6 +20,7 @@ common-obj-$(CONFIG_OPENPIC) += openpic.o
common-obj-y += intc.o
obj-$(CONFIG_APIC) += apic.o apic_common.o
obj-$(CONFIG_ARM_GIC) += arm_gic.o
obj-$(CONFIG_ARM_GIC_KVM) += arm_gic_kvm.o
obj-$(call land,$(CONFIG_ARM_GIC_KVM),$(TARGET_AARCH64)) += arm_gicv3_kvm.o
obj-$(call land,$(CONFIG_ARM_GIC_KVM),$(TARGET_AARCH64)) += arm_gicv3_its_kvm.o

View File

@@ -25,6 +25,7 @@
#include "qom/cpu.h"
#include "qemu/log.h"
#include "trace.h"
#include "kvm_arm.h"
//#define DEBUG_GIC
@@ -557,6 +558,11 @@ static void gic_deactivate_irq(GICState *s, int cpu, int irq, MemTxAttrs attrs)
return;
}
/* Tell KVM that we want to know about timer IRQs again */
if (kvm_enabled()) {
kvm_arm_eoi_notify(cpu);
}
GIC_CLEAR_ACTIVE(irq, cm);
}
@@ -566,6 +572,12 @@ void gic_complete_irq(GICState *s, int cpu, int irq, MemTxAttrs attrs)
int group;
DPRINTF("EOI %d\n", irq);
/* Tell KVM that we want to know about timer IRQs again */
if (kvm_enabled()) {
kvm_arm_eoi_notify(cpu);
}
if (irq >= s->num_irq) {
/* This handles two cases:
* 1. If software writes the ID of a spurious interrupt [ie 1023]
@@ -915,6 +927,10 @@ static void gic_dist_writeb(void *opaque, hwaddr offset,
trace_gic_enable_irq(irq + i);
}
GIC_SET_ENABLED(irq + i, cm);
/* Tell KVM that we want to know about timer IRQs again */
if (kvm_enabled()) {
kvm_arm_eoi_notify(cpu);
}
/* If a raised level triggered IRQ enabled then mark
is as pending. */
if (GIC_TEST_LEVEL(irq + i, mask)

View File

@@ -220,6 +220,8 @@ static const VMStateDescription vmstate_imx_eth = {
#define PHY_INT_PARFAULT (1 << 2)
#define PHY_INT_AUTONEG_PAGE (1 << 1)
#define IMX_MAX_DESC 1024
static void imx_eth_update(IMXFECState *s);
/*
@@ -402,12 +404,12 @@ static void imx_eth_update(IMXFECState *s)
static void imx_fec_do_tx(IMXFECState *s)
{
int frame_size = 0;
int frame_size = 0, descnt = 0;
uint8_t frame[ENET_MAX_FRAME_SIZE];
uint8_t *ptr = frame;
uint32_t addr = s->tx_descriptor;
while (1) {
while (descnt++ < IMX_MAX_DESC) {
IMXFECBufDesc bd;
int len;

View File

@@ -204,8 +204,8 @@ void s390_machine_reset(void)
{
S390CPU *ipl_cpu = S390_CPU(qemu_get_cpu(0));
qemu_devices_reset();
s390_cmma_reset();
qemu_devices_reset();
s390_crypto_reset();
/* all cpus are stopped - configure and start the ipl cpu only */

View File

@@ -683,14 +683,14 @@ static int megasas_map_dcmd(MegasasState *s, MegasasCmd *cmd)
trace_megasas_dcmd_invalid_sge(cmd->index,
cmd->frame->header.sge_count);
cmd->iov_size = 0;
return -1;
return -EINVAL;
}
iov_pa = megasas_sgl_get_addr(cmd, &cmd->frame->dcmd.sgl);
iov_size = megasas_sgl_get_len(cmd, &cmd->frame->dcmd.sgl);
pci_dma_sglist_init(&cmd->qsg, PCI_DEVICE(s), 1);
qemu_sglist_add(&cmd->qsg, iov_pa, iov_size);
cmd->iov_size = iov_size;
return cmd->iov_size;
return 0;
}
static void megasas_finish_dcmd(MegasasCmd *cmd, uint32_t iov_size)
@@ -1559,19 +1559,20 @@ static const struct dcmd_cmd_tbl_t {
static int megasas_handle_dcmd(MegasasState *s, MegasasCmd *cmd)
{
int opcode, len;
int opcode;
int retval = 0;
size_t len;
const struct dcmd_cmd_tbl_t *cmdptr = dcmd_cmd_tbl;
opcode = le32_to_cpu(cmd->frame->dcmd.opcode);
trace_megasas_handle_dcmd(cmd->index, opcode);
len = megasas_map_dcmd(s, cmd);
if (len < 0) {
if (megasas_map_dcmd(s, cmd) < 0) {
return MFI_STAT_MEMORY_NOT_AVAILABLE;
}
while (cmdptr->opcode != -1 && cmdptr->opcode != opcode) {
cmdptr++;
}
len = cmd->iov_size;
if (cmdptr->opcode == -1) {
trace_megasas_dcmd_unhandled(cmd->index, opcode, len);
retval = megasas_dcmd_dummy(s, cmd);

View File

@@ -536,7 +536,7 @@ static void sdhci_sdma_transfer_multi_blocks(SDHCIState *s)
boundary_count -= block_size - begin;
}
dma_memory_read(&address_space_memory, s->sdmasysad,
&s->fifo_buffer[begin], s->data_count);
&s->fifo_buffer[begin], s->data_count - begin);
s->sdmasysad += s->data_count - begin;
if (s->data_count == block_size) {
for (n = 0; n < block_size; n++) {

View File

@@ -258,6 +258,12 @@ static int pit_dispatch_post_load(void *opaque, int version_id)
return 0;
}
static bool is_qemu_kvm(void *opaque, int version_id)
{
/* HACK: We ignore incoming migration from upstream qemu */
return version_id < 3;
}
static const VMStateDescription vmstate_pit_common = {
.name = "i8254",
.version_id = 3,
@@ -267,6 +273,7 @@ static const VMStateDescription vmstate_pit_common = {
.pre_save = pit_dispatch_pre_save,
.post_load = pit_dispatch_post_load,
.fields = (VMStateField[]) {
VMSTATE_UNUSED_TEST(is_qemu_kvm, 4),
VMSTATE_UINT32_V(channels[0].irq_disabled, PITCommonState, 3),
VMSTATE_STRUCT_ARRAY(channels, PITCommonState, 3, 2,
vmstate_pit_channel, PITChannelState),

View File

@@ -967,7 +967,7 @@ static void ccid_on_apdu_from_guest(USBCCIDState *s, CCID_XferBlock *recv)
DPRINTF(s, 1, "%s: seq %d, len %d\n", __func__,
recv->hdr.bSeq, len);
ccid_add_pending_answer(s, (CCID_Header *)recv);
if (s->card) {
if (s->card && len <= BULK_OUT_DATA_SIZE) {
ccid_card_apdu_from_guest(s->card, recv->abData, len);
} else {
DPRINTF(s, D_WARN, "warning: discarded apdu\n");

View File

@@ -92,7 +92,7 @@ struct VirtQueue
uint16_t queue_index;
int inuse;
unsigned int inuse;
uint16_t vector;
VirtIOHandleOutput handle_output;
@@ -1855,9 +1855,11 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id)
/*
* Some devices migrate VirtQueueElements that have been popped
* from the avail ring but not yet returned to the used ring.
* Since max ring size < UINT16_MAX it's safe to use modulo
* UINT16_MAX + 1 subtraction.
*/
vdev->vq[i].inuse = vdev->vq[i].last_avail_idx -
vdev->vq[i].used_idx;
vdev->vq[i].inuse = (uint16_t)(vdev->vq[i].last_avail_idx -
vdev->vq[i].used_idx);
if (vdev->vq[i].inuse > vdev->vq[i].vring.num) {
error_report("VQ %d size 0x%x < last_avail_idx 0x%x - "
"used_idx 0x%x",

View File

@@ -428,6 +428,14 @@ static void i6300esb_realize(PCIDevice *dev, Error **errp)
/* qemu_register_coalesced_mmio (addr, 0x10); ? */
}
static void i6300esb_exit(PCIDevice *dev)
{
I6300State *d = WATCHDOG_I6300ESB_DEVICE(dev);
timer_del(d->timer);
timer_free(d->timer);
}
static WatchdogTimerModel model = {
.wdt_name = "i6300esb",
.wdt_description = "Intel 6300ESB",
@@ -441,6 +449,7 @@ static void i6300esb_class_init(ObjectClass *klass, void *data)
k->config_read = i6300esb_config_read;
k->config_write = i6300esb_config_write;
k->realize = i6300esb_realize;
k->exit = i6300esb_exit;
k->vendor_id = PCI_VENDOR_ID_INTEL;
k->device_id = PCI_DEVICE_ID_INTEL_ESB_9;
k->class_id = PCI_CLASS_SYSTEM_OTHER;

View File

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

View File

@@ -205,6 +205,7 @@ struct kvm_hyperv_exit {
#define KVM_EXIT_S390_STSI 25
#define KVM_EXIT_IOAPIC_EOI 26
#define KVM_EXIT_HYPERV 27
#define KVM_EXIT_ARM_TIMER 28
/* For KVM_EXIT_INTERNAL_ERROR */
/* Emulate instruction failed. */
@@ -361,6 +362,10 @@ struct kvm_run {
} eoi;
/* KVM_EXIT_HYPERV */
struct kvm_hyperv_exit hyperv;
/* KVM_EXIT_ARM_TIMER */
struct {
__u8 timesource;
} arm_timer;
/* Fix the size of the union. */
char padding[256];
};
@@ -870,6 +875,7 @@ struct kvm_ppc_smmu_info {
#define KVM_CAP_S390_USER_INSTR0 130
#define KVM_CAP_MSI_DEVID 131
#define KVM_CAP_PPC_HTM 132
#define KVM_CAP_ARM_TIMER 133
#ifdef KVM_CAP_IRQ_ROUTING
@@ -1327,4 +1333,12 @@ struct kvm_assigned_msix_entry {
#define KVM_X2APIC_API_USE_32BIT_IDS (1ULL << 0)
#define KVM_X2APIC_API_DISABLE_BROADCAST_QUIRK (1ULL << 1)
/* Available with KVM_CAP_ARM_TIMER */
/* Bits for run->request_interrupt_window */
#define KVM_IRQWINDOW_VTIMER (1 << 0)
/* Bits for run->arm_timer.timesource */
#define KVM_ARM_TIMER_VTIMER (1 << 0)
#endif /* __LINUX_KVM_H */

View File

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

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

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

View File

@@ -351,6 +351,11 @@
IOCTL(VFAT_IOCTL_READDIR_BOTH, IOC_R, MK_PTR(MK_ARRAY(MK_STRUCT(STRUCT_dirent), 2)))
IOCTL(VFAT_IOCTL_READDIR_SHORT, IOC_R, MK_PTR(MK_ARRAY(MK_STRUCT(STRUCT_dirent), 2)))
/* FIXME: including these on x86 / x86_64 breaks qemu-i386 */
#ifdef __powerpc__
#include "ioctls_alsa.h"
#endif
IOCTL(LOOP_SET_FD, 0, TYPE_INT)
IOCTL(LOOP_CLR_FD, 0, TYPE_INT)
IOCTL(LOOP_SET_STATUS, IOC_W, MK_PTR(MK_STRUCT(STRUCT_loop_info)))

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

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

File diff suppressed because it is too large Load Diff

View File

@@ -4045,6 +4045,8 @@ int main(int argc, char **argv, char **envp)
# endif
#elif defined TARGET_SH4
cpu_model = TYPE_SH7785_CPU;
#elif defined TARGET_S390X
cpu_model = "qemu";
#else
cpu_model = "any";
#endif

View File

@@ -360,6 +360,9 @@ abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size)
}
}
#define SNDRV_PCM_MMAP_OFFSET_STATUS 0x80000000
#define SNDRV_PCM_MMAP_OFFSET_CONTROL 0x81000000
/* NOTE: all the constants are the HOST ones */
abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
int flags, int fd, abi_ulong offset)
@@ -394,6 +397,17 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
}
#endif
/* Alsa tries to communcate with the kernel via mmap. This usually
* is a good idea when user- and kernelspace are running on the
* same architecture but does not work out when not. To make alsa
* not to use mmap, we can just have it fail on the mmap calls that
* would initiate this.
*/
if(offset == SNDRV_PCM_MMAP_OFFSET_STATUS || offset == SNDRV_PCM_MMAP_OFFSET_CONTROL) {
errno = EINVAL;
return -1;
}
if (offset & ~TARGET_PAGE_MASK) {
errno = EINVAL;
goto fail;

View File

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

View File

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

View File

@@ -4938,6 +4938,11 @@ static abi_long do_ioctl_fs_ioc_fiemap(const IOCTLEntry *ie, uint8_t *buf_temp,
uint32_t outbufsz;
int free_fm = 0;
if (1) {
/* XXX agraf: fiemap breaks for me */
return -TARGET_EINVAL;
}
assert(arg_type[0] == TYPE_PTR);
assert(ie->access == IOC_RW);
arg_type++;
@@ -5471,7 +5476,12 @@ static abi_long do_ioctl(int fd, int cmd, abi_long arg)
ie = ioctl_entries;
for(;;) {
if (ie->target_cmd == 0) {
gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd);
int i;
gemu_log("Unsupported ioctl: cmd=0x%04lx (%x)\n", (unsigned long)cmd, (unsigned int)(cmd & (TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) >> TARGET_IOC_SIZESHIFT);
for (i = 0; ioctl_entries[i].target_cmd; i++) {
if ((ioctl_entries[i].target_cmd & ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) == (cmd & ~(TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)))
gemu_log("%p\t->\t%s (%x)\n", (void *)(unsigned long)ioctl_entries[i].host_cmd, ioctl_entries[i].name, (ioctl_entries[i].target_cmd & (TARGET_IOC_SIZEMASK << TARGET_IOC_SIZESHIFT)) >> TARGET_IOC_SIZESHIFT);
}
return -TARGET_ENOSYS;
}
if (ie->target_cmd == cmd)
@@ -5499,6 +5509,11 @@ static abi_long do_ioctl(int fd, int cmd, abi_long arg)
arg_type++;
target_size = thunk_type_size(arg_type, 0);
switch(ie->access) {
/* FIXME: actually the direction given in the ioctl should be
* correct so we can assume the communication is uni-directional.
* The alsa developers did not like this concept though and
* declared ioctls IOC_R and IOC_W even though they were IOC_RW.*/
/*
case IOC_R:
ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp));
if (!is_error(ret)) {
@@ -5517,6 +5532,7 @@ static abi_long do_ioctl(int fd, int cmd, abi_long arg)
unlock_user(argptr, arg, 0);
ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp));
break;
*/
default:
case IOC_RW:
argptr = lock_user(VERIFY_READ, arg, target_size, 1);
@@ -7214,52 +7230,19 @@ int host_to_target_waitstatus(int status)
static int open_self_cmdline(void *cpu_env, int fd)
{
int fd_orig = -1;
bool word_skipped = false;
CPUState *cpu = ENV_GET_CPU((CPUArchState *)cpu_env);
struct linux_binprm *bprm = ((TaskState *)cpu->opaque)->bprm;
int i;
fd_orig = open("/proc/self/cmdline", O_RDONLY);
if (fd_orig < 0) {
return fd_orig;
}
for (i = 0; i < bprm->argc; i++) {
size_t len = strlen(bprm->argv[i]) + 1;
while (true) {
ssize_t nb_read;
char buf[128];
char *cp_buf = buf;
nb_read = read(fd_orig, buf, sizeof(buf));
if (nb_read < 0) {
int e = errno;
fd_orig = close(fd_orig);
errno = e;
if (write(fd, bprm->argv[i], len) != len) {
return -1;
} else if (nb_read == 0) {
break;
}
if (!word_skipped) {
/* Skip the first string, which is the path to qemu-*-static
instead of the actual command. */
cp_buf = memchr(buf, 0, nb_read);
if (cp_buf) {
/* Null byte found, skip one string */
cp_buf++;
nb_read -= cp_buf - buf;
word_skipped = true;
}
}
if (word_skipped) {
if (write(fd, cp_buf, nb_read) != nb_read) {
int e = errno;
close(fd_orig);
errno = e;
return -1;
}
}
}
return close(fd_orig);
return 0;
}
static int open_self_maps(void *cpu_env, int fd)
@@ -7348,6 +7331,25 @@ static int open_self_stat(void *cpu_env, int fd)
return 0;
}
static int open_cpuinfo(void *cpu_env, int fd)
{
dprintf(fd,
"Processor : ARMv7 Processor rev 5 (v7l)\n"
"BogoMIPS : 799.53\n"
"Features : swp half thumb fastmult vfp edsp thumbee neon vfpv3\n"
"CPU implementer : 0x41\n"
"CPU architecture: 7\n"
"CPU variant : 0x2\n"
"CPU part : 0xc08\n"
"CPU revision : 5\n"
"\n"
"Hardware : Genesi Efika MX (Smarttop)\n"
"Revision : 51030\n"
"Serial : 0000000000000000\n");
return 0;
}
static int open_self_auxv(void *cpu_env, int fd)
{
CPUState *cpu = ENV_GET_CPU((CPUArchState *)cpu_env);
@@ -7462,6 +7464,7 @@ static int do_openat(void *cpu_env, int dirfd, const char *pathname, int flags,
#if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
{ "/proc/net/route", open_net_route, is_proc },
#endif
{ "cpuinfo", open_cpuinfo, is_proc_myself },
{ NULL, NULL, NULL }
};
@@ -7530,10 +7533,10 @@ static target_timer_t get_timer_id(abi_long arg)
/* do_syscall() should always have a single exit point at the end so
that actions, such as logging of syscall results, can be performed.
All errnos that do_syscall() returns must be -TARGET_<errcode>. */
abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
abi_long arg2, abi_long arg3, abi_long arg4,
abi_long arg5, abi_long arg6, abi_long arg7,
abi_long arg8)
abi_long do_syscall(void *cpu_env, int num, abi_ulong arg1,
abi_ulong arg2, abi_ulong arg3, abi_ulong arg4,
abi_ulong arg5, abi_ulong arg6, abi_ulong arg7,
abi_ulong arg8)
{
CPUState *cpu = ENV_GET_CPU(cpu_env);
abi_long ret;
@@ -7896,9 +7899,14 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
case TARGET_NR_oldstat:
goto unimplemented;
#endif
case TARGET_NR_lseek:
ret = get_errno(lseek(arg1, arg2, arg3));
case TARGET_NR_lseek: {
off_t off = arg2;
if (arg3 != SEEK_SET) {
off = (abi_long)arg2;
}
ret = get_errno(lseek(arg1, off, arg3));
break;
}
#if defined(TARGET_NR_getxpid) && defined(TARGET_ALPHA)
/* Alpha specific */
case TARGET_NR_getxpid:
@@ -8770,6 +8778,8 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
case TARGET_NR_gettimeofday:
{
struct timeval tv;
if(copy_from_user_timeval(&tv, arg1))
goto efault;
ret = get_errno(gettimeofday(&tv, NULL));
if (!is_error(ret)) {
if (copy_to_user_timeval(arg1, &tv))
@@ -10018,7 +10028,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
{
struct timespec ts, *pts;
if (arg3 >= 0) {
if ((abi_long)arg3 >= 0) {
/* Convert ms to secs, ns */
ts.tv_sec = arg3 / 1000;
ts.tv_nsec = (arg3 % 1000) * 1000000LL;

View File

@@ -2640,6 +2640,8 @@ struct target_ucred {
uint32_t gid;
};
#include "ioctls_alsa_structs.h"
typedef int32_t target_timer_t;
#define TARGET_SIGEV_MAX_SIZE 64

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -43,7 +43,8 @@ static void free_range(void *range, void *dummy)
g_free(range);
}
static int parse_str(StringInputVisitor *siv, const char *name, Error **errp)
static int parse_str(StringInputVisitor *siv, const char *name, bool u64,
Error **errp)
{
char *str = (char *) siv->string;
long long start, end;
@@ -56,7 +57,11 @@ static int parse_str(StringInputVisitor *siv, const char *name, Error **errp)
do {
errno = 0;
start = strtoll(str, &endptr, 0);
if (u64) {
start = strtoull(str, &endptr, 0);
} else {
start = strtoll(str, &endptr, 0);
}
if (errno == 0 && endptr > str) {
if (*endptr == '\0') {
cur = g_malloc0(sizeof(*cur));
@@ -67,7 +72,11 @@ static int parse_str(StringInputVisitor *siv, const char *name, Error **errp)
} else if (*endptr == '-') {
str = endptr + 1;
errno = 0;
end = strtoll(str, &endptr, 0);
if (u64) {
end = strtoull(str, &endptr, 0);
} else {
end = strtoll(str, &endptr, 0);
}
if (errno == 0 && endptr > str && start <= end &&
(start > INT64_MAX - 65536 ||
end < start + 65536)) {
@@ -123,7 +132,7 @@ start_list(Visitor *v, const char *name, GenericList **list, size_t size,
assert(list);
siv->list = list;
if (parse_str(siv, name, errp) < 0) {
if (parse_str(siv, name, false, errp) < 0) {
*list = NULL;
return;
}
@@ -188,7 +197,7 @@ static void parse_type_int64(Visitor *v, const char *name, int64_t *obj,
return;
}
if (parse_str(siv, name, errp) < 0) {
if (parse_str(siv, name, false, errp) < 0) {
return;
}
@@ -224,15 +233,43 @@ error:
static void parse_type_uint64(Visitor *v, const char *name, uint64_t *obj,
Error **errp)
{
/* FIXME: parse_type_int64 mishandles values over INT64_MAX */
int64_t i;
Error *err = NULL;
parse_type_int64(v, name, &i, &err);
if (err) {
error_propagate(errp, err);
} else {
*obj = i;
StringInputVisitor *siv = to_siv(v);
if (!siv->string) {
error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",
"integer");
return;
}
parse_str(siv, name, true, errp);
if (!siv->ranges) {
goto error;
}
if (!siv->cur_range) {
Range *r;
siv->cur_range = g_list_first(siv->ranges);
if (!siv->cur_range) {
goto error;
}
r = siv->cur_range->data;
if (!r) {
goto error;
}
siv->cur = range_lob(r);
}
*obj = siv->cur;
siv->cur++;
return;
error:
error_setg(errp, QERR_INVALID_PARAMETER_VALUE, name,
"a uint64 value or range");
}
static void parse_type_size(Visitor *v, const char *name, uint64_t *obj,

View File

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

View File

@@ -531,6 +531,9 @@ static CharDriverState *qemu_chr_open_null(const char *id,
struct MuxDriver {
CharBackend *backends[MAX_MUX];
CharBackend chr;
#if defined(TARGET_S390X)
QEMUTimer *accept_timer;
#endif
int focus;
int mux_cnt;
int term_got_escape;
@@ -694,6 +697,15 @@ static void mux_chr_accept_input(CharDriverState *chr)
be->chr_read(be->opaque,
&d->buffer[m][d->cons[m]++ & MUX_BUFFER_MASK], 1);
}
#if defined(TARGET_S390X)
/* We're still not able to sync producer and consumer, so let's wait a bit
and try again by then. */
if (d->prod[m] != d->cons[m]) {
qemu_mod_timer(d->accept_timer, qemu_get_clock_ns(vm_clock)
+ (int64_t)100000);
}
#endif
}
static int mux_chr_can_read(void *opaque)
@@ -864,6 +876,10 @@ static CharDriverState *qemu_chr_open_mux(const char *id,
chr->opaque = d;
d->focus = -1;
#if defined(TARGET_S390X)
d->accept_timer = qemu_new_timer_ns(vm_clock,
(QEMUTimerCB*)mux_chr_accept_input, chr);
#endif
chr->chr_free = mux_chr_free;
chr->chr_write = mux_chr_write;
chr->chr_accept_input = mux_chr_accept_input;

View File

@@ -3162,6 +3162,16 @@ Store the QEMU process PID in @var{file}. It is useful if you launch QEMU
from a script.
ETEXI
DEF("nooutgoing", HAS_ARG, QEMU_OPTION_nooutgoing, \
"-nooutgoing <IP>\n" \
" incoming traffic only from IP, no outgoing\n", \
QEMU_ARCH_ALL)
STEXI
@item -nooutgoing
Forbid userspace networking to make outgoing connections. Only accept incoming
connections from ip address IP.
ETEXI
DEF("singlestep", 0, QEMU_OPTION_singlestep, \
"-singlestep always run in singlestep mode\n", QEMU_ARCH_ALL)
STEXI

View File

@@ -52,6 +52,12 @@ SEABIOS_EXTRAVERSION="-prebuilt.qemu-project.org"
#
EFIROM ?= $(shell which EfiRom 2>/dev/null)
# NB: Certain SUSE qemu subpackages use date information, but we want
# reproducible builds, so we use a pre-determined timestamp, rather
# than the current timestamp to acheive consistent results build to
# build.
PACKAGING_TIMESTAMP = $(shell date -r ../VERSION +%s)
default:
@echo "nothing is build by default"
@echo "available build targets:"
@@ -106,7 +112,7 @@ build-lgplvgabios:
.PHONY: sgabios skiboot
sgabios:
$(MAKE) -C sgabios
$(MAKE) -C sgabios PACKAGING_TIMESTAMP=$(PACKAGING_TIMESTAMP)
cp sgabios/sgabios.bin ../pc-bios
@@ -126,18 +132,22 @@ efi-rom-%: build-pxe-roms build-efi-roms
build-pxe-roms:
$(MAKE) -C ipxe/src CONFIG=qemu \
PACKAGING_TIMESTAMP=$(PACKAGING_TIMESTAMP) \
CROSS_COMPILE=$(x86_64_cross_prefix) \
$(patsubst %,bin/%.rom,$(pxerom_targets))
build-efi-roms: build-pxe-roms
$(MAKE) -C ipxe/src CONFIG=qemu \
PACKAGING_TIMESTAMP=$(PACKAGING_TIMESTAMP) \
CROSS_COMPILE=$(x86_64_cross_prefix) \
$(patsubst %,bin-i386-efi/%.efidrv,$(pxerom_targets)) \
$(patsubst %,bin-x86_64-efi/%.efidrv,$(pxerom_targets))
slof:
$(MAKE) -C SLOF CROSS=$(powerpc64_cross_prefix) qemu
$(MAKE) -C SLOF CROSS=$(powerpc64_cross_prefix) \
PACKAGING_TIMESTAMP=$(PACKAGING_TIMESTAMP) \
qemu
cp SLOF/boot_rom.bin ../pc-bios/slof.bin
u-boot.e500:

View File

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

View File

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

View File

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

View File

@@ -530,7 +530,6 @@ MemTxAttrs kvm_arch_post_run(CPUState *cs, struct kvm_run *run)
return MEMTXATTRS_UNSPECIFIED;
}
int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
{
int ret = 0;
@@ -541,6 +540,23 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
ret = EXCP_DEBUG;
} /* otherwise return to guest */
break;
case KVM_EXIT_ARM_TIMER:
/* We only support the vtimer today */
if (run->arm_timer.timesource != KVM_ARM_TIMER_VTIMER) {
return -EINVAL;
}
/*
* We ask the kernel to not tell us about pending virtual timer irqs,
* so that we can process the IRQ until we get an EOI for it. Once the
* EOI hits, we unset and unmask the interrupt again and if it is still
* pending, we set the line high again
*/
run->request_interrupt_window = KVM_IRQWINDOW_VTIMER;
/* Internally trigger virtual timer IRQ */
qemu_set_irq(ARM_CPU(cs)->gt_timer_outputs[GTIMER_VIRT], 1);
break;
default:
qemu_log_mask(LOG_UNIMP, "%s: un-handled exit reason %d\n",
__func__, run->exit_reason);
@@ -638,3 +654,14 @@ int kvm_arch_msi_data_to_gsi(uint32_t data)
{
return (data - 32) & 0xffff;
}
void kvm_arm_eoi_notify(int cpu)
{
CPUState *cs;
cs = qemu_get_cpu(cpu);
/* Disable vtimer - if it's still pending we get notified again */
cs->kvm_run->request_interrupt_window &= ~KVM_ARM_TIMER_VTIMER;
qemu_set_irq(ARM_CPU(cs)->gt_timer_outputs[GTIMER_VIRT], 0);
}

View File

@@ -288,4 +288,15 @@ static inline const char *its_class_name(void)
}
}
/**
* kvm_arm_eoi_notify:
*
* @cpu: CPU index the EOI is for
*
* Notify KVM that we're done processing an interrupt. This is
* used to unmask any pending timer interrupts and potentially
* learn about the fact that the level is still high.
*/
void kvm_arm_eoi_notify(int cpu);
#endif

View File

@@ -1465,7 +1465,7 @@ uint64_t cpu_get_tsc(CPUX86State *env);
/* XXX: This value should match the one returned by CPUID
* and in exec.c */
# if defined(TARGET_X86_64)
# define TCG_PHYS_ADDR_BITS 40
# define TCG_PHYS_ADDR_BITS 42
# else
# define TCG_PHYS_ADDR_BITS 36
# endif

View File

@@ -738,6 +738,7 @@ void s390_realize_cpu_model(CPUState *cs, Error **errp)
return;
}
#ifndef CONFIG_USER_ONLY
/* copy over properties that can vary */
cpu->model->lowest_ibc = max_model->lowest_ibc;
cpu->model->cpu_id = max_model->cpu_id;
@@ -750,6 +751,7 @@ void s390_realize_cpu_model(CPUState *cs, Error **errp)
}
apply_cpu_model(cpu->model, errp);
#endif
}
static void get_feature(Object *obj, Visitor *v, const char *name,

View File

@@ -86,6 +86,8 @@ check-unit-y += tests/check-qom-interface$(EXESUF)
gcov-files-check-qom-interface-y = qom/object.c
check-unit-y += tests/check-qom-proplist$(EXESUF)
gcov-files-check-qom-proplist-y = qom/object.c
check-unit-y += tests/check-qom-props$(EXESUF)
gcov-files-check-qom-props-y = qom/object.c
check-unit-y += tests/test-qemu-opts$(EXESUF)
gcov-files-test-qemu-opts-y = qom/test-qemu-opts.c
check-unit-y += tests/test-write-threshold$(EXESUF)
@@ -146,6 +148,8 @@ check-qtest-virtio-y += tests/virtio-rng-test$(EXESUF)
gcov-files-virtio-y += hw/virtio/virtio-rng.c
check-qtest-virtio-y += tests/virtio-scsi-test$(EXESUF)
gcov-files-virtio-y += i386-softmmu/hw/scsi/virtio-scsi.c
check-qtest-virtio-y += tests/scsi-disk-test$(EXESUF)
gcov-files-virtio-y += i386-softmmu/hw/scsi/scsi-disk.c
ifeq ($(CONFIG_VIRTIO)$(CONFIG_VIRTFS)$(CONFIG_PCI),yyy)
check-qtest-virtio-y += tests/virtio-9p-test$(EXESUF)
gcov-files-virtio-y += hw/9pfs/virtio-9p.c
@@ -487,6 +491,7 @@ tests/check-qnull$(EXESUF): tests/check-qnull.o $(test-util-obj-y)
tests/check-qjson$(EXESUF): tests/check-qjson.o $(test-util-obj-y)
tests/check-qom-interface$(EXESUF): tests/check-qom-interface.o $(test-qom-obj-y)
tests/check-qom-proplist$(EXESUF): tests/check-qom-proplist.o $(test-qom-obj-y)
tests/check-qom-props$(EXESUF): tests/check-qom-props.o $(test-qom-obj-y)
tests/test-char$(EXESUF): tests/test-char.o qemu-char.o qemu-timer.o $(test-util-obj-y) $(qtest-obj-y) $(test-io-obj-y)
tests/test-coroutine$(EXESUF): tests/test-coroutine.o $(test-block-obj-y)
@@ -679,6 +684,7 @@ tests/usb-hcd-xhci-test$(EXESUF): tests/usb-hcd-xhci-test.o $(libqos-usb-obj-y)
tests/pc-cpu-test$(EXESUF): tests/pc-cpu-test.o
tests/postcopy-test$(EXESUF): tests/postcopy-test.o
tests/vhost-user-test$(EXESUF): tests/vhost-user-test.o qemu-char.o qemu-timer.o $(qtest-obj-y) $(test-io-obj-y) $(libqos-virtio-obj-y) $(libqos-pc-obj-y)
tests/scsi-disk-test$(EXESUF): tests/scsi-disk-test.o
tests/qemu-iotests/socket_scm_helper$(EXESUF): tests/qemu-iotests/socket_scm_helper.o
tests/test-qemu-opts$(EXESUF): tests/test-qemu-opts.o $(test-util-obj-y)
tests/test-write-threshold$(EXESUF): tests/test-write-threshold.o $(test-block-obj-y)

122
tests/check-qom-props.c Normal file
View File

@@ -0,0 +1,122 @@
/*
* Copyright (C) 2015 Red Hat, Inc.
* Copyright (c) 2015 SUSE Linux GmbH
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <http://www.gnu.org/licenses/>.
*
* Author: Daniel P. Berrange <berrange@redhat.com>
* Andreas Färber <afaerber@suse.com>
*/
#include "qemu/osdep.h"
#include <glib.h>
#include "qapi/visitor.h"
#include "qom/object.h"
#include "qemu/module.h"
#define TYPE_DUMMY "qemu-dummy"
typedef struct DummyObject DummyObject;
typedef struct DummyObjectClass DummyObjectClass;
#define DUMMY_OBJECT(obj) \
OBJECT_CHECK(DummyObject, (obj), TYPE_DUMMY)
struct DummyObject {
Object parent_obj;
uint64_t u64val;
};
struct DummyObjectClass {
ObjectClass parent_class;
};
static void dummy_set_uint64(Object *obj, Visitor *v,
const char *name, void *opaque,
Error **errp)
{
uint64_t *ptr = (uint64_t *)opaque;
visit_type_uint64(v, name, ptr, errp);
}
static void dummy_get_uint64(Object *obj, Visitor *v,
const char *name, void *opaque,
Error **errp)
{
uint64_t value = *(uint64_t *)opaque;
visit_type_uint64(v, name, &value, errp);
}
static void dummy_init(Object *obj)
{
DummyObject *dobj = DUMMY_OBJECT(obj);
object_property_add(obj, "u64val", "uint64",
dummy_get_uint64,
dummy_set_uint64,
NULL, &dobj->u64val, NULL);
}
static const TypeInfo dummy_info = {
.name = TYPE_DUMMY,
.parent = TYPE_OBJECT,
.instance_size = sizeof(DummyObject),
.instance_init = dummy_init,
.class_size = sizeof(DummyObjectClass),
};
static void test_dummy_uint64(void)
{
Error *err = NULL;
char *str;
DummyObject *dobj = DUMMY_OBJECT(object_new(TYPE_DUMMY));
g_assert(dobj->u64val == 0);
str = g_strdup_printf("%" PRIu64, UINT64_MAX);
object_property_parse(OBJECT(dobj), str, "u64val", &err);
g_free(str);
g_assert(!err);
g_assert_cmpint(dobj->u64val, ==, UINT64_MAX);
dobj->u64val = 0;
str = g_strdup_printf("0x%" PRIx64, UINT64_MAX);
object_property_parse(OBJECT(dobj), str, "u64val", &err);
g_free(str);
g_assert(!err);
g_assert_cmpint(dobj->u64val, ==, UINT64_MAX);
object_unref(OBJECT(dobj));
}
int main(int argc, char **argv)
{
g_test_init(&argc, &argv, NULL);
module_call_init(MODULE_INIT_QOM);
type_register_static(&dummy_info);
g_test_add_func("/qom/props/uint64", test_dummy_uint64);
return g_test_run();
}

82
tests/scsi-disk-test.c Normal file
View File

@@ -0,0 +1,82 @@
/*
* QTest testcase for SCSI disks
* See virtio-scsi-test for more integrated tests.
*
* Copyright (c) 2015 SUSE Linux GmbH
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/
#include "qemu/osdep.h"
#include <glib.h>
#include "libqtest.h"
#include "qapi/qmp/qint.h"
static void test_scsi_disk_common(const char *type, const char *id)
{
char *cmdline, *path;
QDict *response;
QInt *value;
cmdline = g_strdup_printf(
"-drive id=drv0,if=none,file=/dev/null,format=raw "
"-device virtio-scsi-pci,id=scsi0 "
"-device %s,id=%s,bus=scsi0.0,drive=drv0"
",wwn=0x%" PRIx64 ",port_wwn=0x%" PRIx64,
type, id, UINT64_MAX, UINT64_C(1) << 63);
qtest_start(cmdline);
g_free(cmdline);
path = g_strdup_printf("/machine/peripheral/%s", id);
response = qmp("{ 'execute': 'qom-get',"
" 'arguments': { 'path': %s,"
" 'property': 'wwn' } }",
path);
g_assert(response);
g_assert(qdict_haskey(response, "return"));
value = qobject_to_qint(qdict_get(response, "return"));
g_assert_cmpint(qint_get_int(value), ==, UINT64_MAX);
response = qmp("{ 'execute': 'qom-get',"
" 'arguments': { 'path': %s,"
" 'property': 'port_wwn' } }",
path);
g_assert(response);
g_assert(qdict_haskey(response, "return"));
value = qobject_to_qint(qdict_get(response, "return"));
g_assert_cmpint(qint_get_int(value), ==, UINT64_C(1) << 63);
g_free(path);
qtest_end();
}
static void test_scsi_disk(void)
{
test_scsi_disk_common("scsi-disk", "disk0");
}
static void test_scsi_hd(void)
{
test_scsi_disk_common("scsi-hd", "hd0");
}
static void test_scsi_cd(void)
{
test_scsi_disk_common("scsi-cd", "cd0");
}
int main(int argc, char **argv)
{
int ret;
g_test_init(&argc, &argv, NULL);
qtest_add_func("/scsi-disk/props", test_scsi_disk);
qtest_add_func("/scsi-hd/props", test_scsi_hd);
qtest_add_func("/scsi-cd/props", test_scsi_cd);
ret = g_test_run();
return ret;
}

View File

@@ -924,7 +924,9 @@ int main(int argc, char **argv)
g_test_add_data_func("/qga/info", &fix, test_qga_info);
g_test_add_data_func("/qga/network-get-interfaces", &fix,
test_qga_network_get_interfaces);
g_test_add_data_func("/qga/get-vcpus", &fix, test_qga_get_vcpus);
if (!access("/sys/devices/system/cpu/cpu0", F_OK)) {
g_test_add_data_func("/qga/get-vcpus", &fix, test_qga_get_vcpus);
}
g_test_add_data_func("/qga/get-fsinfo", &fix, test_qga_get_fsinfo);
g_test_add_data_func("/qga/get-memory-block-info", &fix,
test_qga_get_memory_block_info);

View File

@@ -53,6 +53,14 @@ static void test_visitor_in_int(TestInputVisitorData *data,
v = visitor_input_test_init(data, "-42");
visit_type_int(v, NULL, &res, &err);
g_assert(!err);
g_assert_cmpint(res, ==, value);
visitor_input_teardown(data, unused);
value = INT64_MAX;
v = visitor_input_test_init(data, g_strdup_printf("%" PRId64, value));
visit_type_int(v, NULL, &res, &err);
g_assert(!err);
g_assert_cmpint(res, ==, value);
@@ -65,6 +73,27 @@ static void test_visitor_in_int(TestInputVisitorData *data,
error_free_or_abort(&err);
}
static void test_visitor_in_uint64(TestInputVisitorData *data,
const void *unused)
{
uint64_t res = 0, value = UINT64_MAX;
Error *err = NULL;
Visitor *v;
v = visitor_input_test_init(data, g_strdup_printf("%" PRIu64, value));
visit_type_uint64(v, NULL, &res, &err);
g_assert(!err);
g_assert_cmpint(res, ==, value);
visitor_input_teardown(data, unused);
v = visitor_input_test_init(data, g_strdup_printf("0x%" PRIx64, value));
visit_type_uint64(v, NULL, &res, &err);
g_assert(!err);
g_assert_cmpint(res, ==, value);
}
static void test_visitor_in_intList(TestInputVisitorData *data,
const void *unused)
{
@@ -267,6 +296,8 @@ int main(int argc, char **argv)
input_visitor_test_add("/string-visitor/input/int",
&in_visitor_data, test_visitor_in_int);
input_visitor_test_add("/string-visitor/input/uint64",
&in_visitor_data, test_visitor_in_uint64);
input_visitor_test_add("/string-visitor/input/intList",
&in_visitor_data, test_visitor_in_intList);
input_visitor_test_add("/string-visitor/input/bool",

View File

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

21
thunk.c
View File

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

View File

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

View File

@@ -58,6 +58,8 @@ static const struct timeval VNC_REFRESH_LOSSY = { 2, 0 };
static QTAILQ_HEAD(, VncDisplay) vnc_displays =
QTAILQ_HEAD_INITIALIZER(vnc_displays);
static int allowed_connections = 0;
static int vnc_cursor_define(VncState *vs);
static void vnc_release_modifiers(VncState *vs);
@@ -1201,6 +1203,7 @@ static void vnc_disconnect_start(VncState *vs)
void vnc_disconnect_finish(VncState *vs)
{
int i;
static int num_disconnects = 0;
vnc_jobs_join(vs); /* Wait encoding jobs */
@@ -1251,6 +1254,13 @@ void vnc_disconnect_finish(VncState *vs)
object_unref(OBJECT(vs->sioc));
vs->sioc = NULL;
g_free(vs);
num_disconnects++;
if (allowed_connections > 0 && allowed_connections <= num_disconnects) {
VNC_DEBUG("Maximum number of disconnects (%d) reached:"
" Session terminating\n", allowed_connections);
exit(0);
}
}
ssize_t vnc_client_io_error(VncState *vs, ssize_t ret, Error **errp)
@@ -1760,6 +1770,25 @@ static void do_key_event(VncState *vs, int down, int keycode, int sym)
if (down)
vs->modifiers_state[keycode] ^= 1;
break;
default:
if (qemu_console_is_graphic(NULL)) {
/* record key 'down' info. Some client like tigervnc
* will send key down repeatedly if user pressing a
* a key for long time. In this case, we should add
* additional key up event before repeated key down,
* so that it can display the key multiple times.
*/
if (down) {
if (vs->modifiers_state[keycode]) {
/* add a key up event */
do_key_event(vs, 0, keycode, sym);
}
vs->modifiers_state[keycode] = 1;
} else {
vs->modifiers_state[keycode] = 0;
}
}
break;
}
/* Turn off the lock state sync logic if the client support the led
@@ -3244,6 +3273,39 @@ static void vnc_display_print_local_addr(VncDisplay *vd)
qapi_free_SocketAddress(addr);
}
static void read_file_password(const char *id, const char *filename)
{
FILE *pfile = NULL;
char *passwd = NULL;
int start = 0, length = 0, rc = 0;
if (strlen(filename) == 0) {
printf("No file supplied\n");
return;
}
pfile = fopen(filename, "r");
if (pfile == NULL) {
printf("Could not read from %s\n", filename);
return;
}
start = ftell(pfile);
fseek(pfile, 0L, SEEK_END);
length = ftell(pfile);
fseek(pfile, 0L, start);
passwd = g_malloc(length + 1);
rc = fread(passwd, 1, length, pfile);
fclose(pfile);
if (rc == length && rc > 0) {
vnc_display_password(id, passwd);
}
g_free(passwd);
}
static QemuOptsList qemu_vnc_opts = {
.name = "vnc",
.head = QTAILQ_HEAD_INITIALIZER(qemu_vnc_opts.head),
@@ -3274,6 +3336,9 @@ static QemuOptsList qemu_vnc_opts = {
},{
.name = "connections",
.type = QEMU_OPT_NUMBER,
},{
.name = "allowed-connections",
.type = QEMU_OPT_NUMBER,
},{
.name = "to",
.type = QEMU_OPT_NUMBER,
@@ -3286,6 +3351,9 @@ static QemuOptsList qemu_vnc_opts = {
},{
.name = "password",
.type = QEMU_OPT_BOOL,
},{
.name = "password-file",
.type = QEMU_OPT_STRING,
},{
.name = "reverse",
.type = QEMU_OPT_BOOL,
@@ -3486,6 +3554,7 @@ void vnc_display_open(const char *id, Error **errp)
const char *share, *device_id;
QemuConsole *con;
bool password = false;
const char *password_file;
bool reverse = false;
const char *vnc;
char *h;
@@ -3615,6 +3684,10 @@ void vnc_display_open(const char *id, Error **errp)
goto fail;
}
}
password_file = qemu_opt_get(opts, "password-file");
if (password_file) {
read_file_password(id, password_file);
}
reverse = qemu_opt_get_bool(opts, "reverse", false);
lock_key_sync = qemu_opt_get_bool(opts, "lock-key-sync", true);
@@ -3704,6 +3777,7 @@ void vnc_display_open(const char *id, Error **errp)
vd->share_policy = VNC_SHARE_POLICY_ALLOW_EXCLUSIVE;
}
vd->connections_limit = qemu_opt_get_number(opts, "connections", 32);
allowed_connections = qemu_opt_get_number(opts, "allowed-connections", 0);
#ifdef CONFIG_VNC_JPEG
vd->lossy = qemu_opt_get_bool(opts, "lossy", false);

View File

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

21
vl.c
View File

@@ -26,6 +26,7 @@
#include "qemu/cutils.h"
#include "qemu/help_option.h"
#include "qemu/uuid.h"
#include <sys/resource.h>
#ifdef CONFIG_SECCOMP
#include "sysemu/seccomp.h"
@@ -162,6 +163,7 @@ int smp_threads = 1;
int acpi_enabled = 1;
int no_hpet = 0;
int fd_bootchk = 1;
int slirp_nooutgoing = 0;
static int no_reboot;
int no_shutdown = 0;
int cursor_hide = 1;
@@ -3030,6 +3032,7 @@ int main(int argc, char **argv, char **envp)
Error *main_loop_err = NULL;
Error *err = NULL;
bool list_data_dirs = false;
struct rlimit rlimit_as;
module_call_init(MODULE_INIT_TRACE);
@@ -3037,6 +3040,16 @@ int main(int argc, char **argv, char **envp)
qemu_init_cpu_loop();
qemu_mutex_lock_iothread();
/*
* Try to raise the soft address space limit.
* Default on SLES 11 SP2 is 80% of physical+swap memory.
*/
getrlimit(RLIMIT_AS, &rlimit_as);
if (rlimit_as.rlim_cur < rlimit_as.rlim_max) {
rlimit_as.rlim_cur = rlimit_as.rlim_max;
setrlimit(RLIMIT_AS, &rlimit_as);
}
atexit(qemu_run_exit_notifiers);
error_set_progname(argv[0]);
qemu_init_exec_dir(argv[0]);
@@ -3437,6 +3450,14 @@ int main(int argc, char **argv, char **envp)
case QEMU_OPTION_singlestep:
singlestep = 1;
break;
case QEMU_OPTION_nooutgoing:
slirp_nooutgoing = inet_addr(optarg);
if (slirp_nooutgoing == INADDR_NONE) {
printf("Invalid address: %s.\nOnly addresses of the format "
"xxx.xxx.xxx.xxx are supported.\n", optarg);
exit(1);
}
break;
case QEMU_OPTION_S:
autostart = 0;
break;