Compare commits

...

497 Commits

Author SHA1 Message Date
Gerd Hoffmann
eb214ff8ef vnc: fix screen updates
Bug was added by 38ee14f4f3.
vnc_jobs_join call is missing in one code path.

Reported-by: Anthony PERARD <anthony.perard@citrix.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-06-19 12:48:07 +02:00
Markus Armbruster
c14e98479b vnc: Drop superfluous conditionals around g_strdup()
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-06-19 12:48:07 +02:00
Markus Armbruster
64641d8764 vnc: Drop superfluous conditionals around g_free()
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-06-19 12:48:07 +02:00
Petar Jovanovic
d279279e2b target-mips: implement UserLocal Register
From MIPS documentation (Volume III):

UserLocal Register (CP0 Register 4, Select 2)
Compliance Level: Recommended.

The UserLocal register is a read-write register that is not interpreted by
the hardware and conditionally readable via the RDHWR instruction.

This register only exists if the Config3-ULRI register field is set.

Privileged software may write this register with arbitrary information and
make it accessible to unprivileged software via register 29 (ULR) of the
RDHWR instruction. To do so, bit 29 of the HWREna register must be set to a
1 to enable unprivileged access to the register.

Signed-off-by: Petar Jovanovic <petar.jovanovic@imgtec.com>
Reviewed-by: Andreas Färber <afaerber@suse.de>
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
2014-06-18 18:10:47 +02:00
Aurelien Jarno
739b7a9075 bitops: provide an inline implementation of find_first_bit
find_first_bit has started to be used heavily in TCG code. The current
implementation based on find_next_bit is not optimal and can't be
optimized be the compiler if the bit array has a fixed size, which is
the case most of the time.

This new implementation does not use find_next_bit and is yet small
enough to be inlined.

Cc: Corentin Chary <corentin.chary@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
2014-06-18 18:10:47 +02:00
Peter Maydell
2edaf21b93 Merge remote-tracking branch 'remotes/bonzini/memory' into staging
* remotes/bonzini/memory:
  memory: Don't call memory_region_update_coalesced_range if nothing changed
  memory: MemoryRegion: rename parent to container
  memory: MemoryRegion: factor out memory region re-adder
  memory: MemoryRegion: factor out subregion add functionality
  qtest: fix qtest_clock_warp() for no deadline case
  exec: dummy_section: Pass address space through.
  memory: Simplify mr_add_subregion() if-else
  memory: Don't update all memory region when ioeventfd changed
  unset RAMBlock idstr when unregister MemoryRegion
  exec: introduce qemu_ram_unset_idstr() to unset RAMBlock idstr
  MAINTAINERS: Add myself as Memory API maintainer

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-18 15:08:38 +01:00
Fam Zheng
ab5b3db5d7 memory: Don't call memory_region_update_coalesced_range if nothing changed
With huge number of PCI devices in the system (for example, 200
virtio-blk-pci), this unconditional call can slow down emulation of
irrelevant PCI operations drastically, such as a BAR update on a device
that has no coalescing region. So avoid it.

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-18 15:32:50 +02:00
Paolo Bonzini
feca4ac18b memory: MemoryRegion: rename parent to container
Avoid confusion with the QOM parent.

Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-18 15:32:50 +02:00
Peter Crosthwaite
67891b8a85 memory: MemoryRegion: factor out memory region re-adder
memory_region_set_address is mostly just a function that deletes and
re-adds a memory region. Factor this generic functionality out into a
re-usable function. This prepares support for further QOMification
of MemoryRegion.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-17 17:11:13 +02:00
Peter Crosthwaite
0598701a49 memory: MemoryRegion: factor out subregion add functionality
Split off the core looping code that actually adds subregions into
it's own fn. This prepares support for Memory Region qomification
where setting the MR address or parent via QOM will back onto this more
minimal function.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
[Rename new function. - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-17 17:11:10 +02:00
Peter Maydell
0360fbd076 Merge remote-tracking branch 'remotes/riku/linux-user-for-upstream' into staging
* remotes/riku/linux-user-for-upstream:
  User mode support for Linux ELF files with no section header
  linux-user: Return correct errno for unsupported netlink socket
  linux-user: Don't overrun guest buffer in sched_getaffinity
  linux-user/uname: Return correct uname string for x86_64
  linux-user: fix gcc-4.9 compiler error on __{get,put]}_user
  signal/ppc/do_setcontext remove __get_user return check
  signal/sparc64_set_context: remove __get_user checks
  signal/ppc/{save,restore}_user_regs remove __put/get error checks
  signal/all/setup_frame remove __put_user checks
  signal/all/do_sigreturn - remove __get_user checks
  signal/all/do_sigaltstack remove __get_user value check
  signal/sparc/restore_fpu_state: remove
  signal/all: remove return value from restore_sigcontext
  signal/all: remove return value from setup_sigcontext
  signal/all: remove return value from copy_siginfo_to_user
  signal/x86/setup_frame: __put_user cleanup
  signal/all: remove __get/__put_user return value reading

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-17 16:08:06 +01:00
Sergey Fedorov
c9299e2fe7 qtest: fix qtest_clock_warp() for no deadline case
Use dedicated qemu_soonest_timeout() instead of MIN().

Signed-off-by: Sergey Fedorov <serge.fdrv@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-17 16:07:37 +02:00
Peter Crosthwaite
a656e22f09 exec: dummy_section: Pass address space through.
Rather than use the global singleton.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-17 16:07:37 +02:00
Peter Crosthwaite
3fb5bf5730 memory: Simplify mr_add_subregion() if-else
This if else is not needed. The previous call to memory_region_add
(whether _overlap or not) will always set priority and may_overlap
to desired values. And its not possible to get here without having
called memory_region_add_subregion due to the null guard on parent.
So we can just directly call memory_region_add_subregion_common.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-17 16:07:37 +02:00
Gonglei
4dc5615223 memory: Don't update all memory region when ioeventfd changed
memory mappings don't rely on ioeventfds, there is no need
to destroy and rebuild them when manipulating ioeventfds,
otherwise it scarifies performance.

according to testing result, each ioeventfd deleing needs
about 5ms, within which memory mapping rebuilding needs
about 4ms. With many Nics and vmchannel in a VM doing migrating,
there can be many ioeventfds deleting which increasing
downtime remarkably.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Signed-off-by: Herongguang <herongguang.he@huawei.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-17 16:07:37 +02:00
Hu Tao
b0e56e0b63 unset RAMBlock idstr when unregister MemoryRegion
Signed-off-by: Hu Tao <hutao@cn.fujitsu.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-17 16:07:37 +02:00
Hu Tao
20cfe8810d exec: introduce qemu_ram_unset_idstr() to unset RAMBlock idstr
Signed-off-by: Hu Tao <hutao@cn.fujitsu.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-17 16:07:37 +02:00
Paolo Bonzini
01a9c03c39 MAINTAINERS: Add myself as Memory API maintainer
I'm not including Avi since he has already removed himself from the
KVM entry.  I'm not going to commit my patches without review.

Acked-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-17 16:07:37 +02:00
Craig Heffner
d3606f0744 User mode support for Linux ELF files with no section header
In user mode Linux, Qemu currently refuses to load ELF files that do not
contain section headers (ehdr->e_shentsize == 0). Since section headers are not
required in order to load an ELF file, simply removing the e_shentsize check in
elf_check_ehdr() allows ELF binaries with no section headers to be run properly
in user mode:

Signed-off-by: Craig Heffner <cheffner@tacnetsol.com>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
2014-06-17 09:21:41 +03:00
Ed Swierk
480eda2eda linux-user: Return correct errno for unsupported netlink socket
This fixes "Cannot open audit interface - aborting." when the
EAFNOSUPPORT errno differs between the target and host
architectures (e.g. mips target and x86_64 host).

Signed-off-by: Ed Swierk <eswierk@skyportsystems.com>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
2014-06-17 09:21:41 +03:00
Peter Maydell
be3bd286bc linux-user: Don't overrun guest buffer in sched_getaffinity
If the guest's "long" type is smaller than the host's, then
our sched_getaffinity wrapper needs to round the buffer size
up to a multiple of the host sizeof(long). This means that when
we copy the data back from the host buffer to the guest's
buffer there might be more than we can fit. Rather than
overflowing the guest's buffer, handle this case by returning
EINVAL or ignoring the unused extra space, as appropriate.

Note that only guests using the syscall interface directly might
run into this bug -- the glibc wrappers around it will always
use a buffer whose size is a multiple of 8 regardless of guest
architecture.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
2014-06-17 09:21:41 +03:00
Peter Maydell
4d13be8b8b linux-user/uname: Return correct uname string for x86_64
We were returning the incorrect uname string (with a hyphen, not
an underscore) for x86_64. Fix this by removing the x86_64 special
case, since the default "just use UNAME_MACHINE" behaviour suffices.
This leaves cpu_to_uname_machine() special cases for only those
architectures which need to vary the string based on runtime CPU
features.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
2014-06-17 09:21:40 +03:00
Riku Voipio
a42267ef58 linux-user: fix gcc-4.9 compiler error on __{get,put]}_user
gcc-4.9 finds unused operand:

linux-user/syscall.c: In function ‘host_to_target_stat64’:
linux-user/qemu.h:301:19: error: right-hand operand of comma expression
has no effect [-Werror=unused-value]
      ((hptr), (x)), 0)

Just removing the rh operand is no good, it will error in later:

linux-user/main.c: In function ‘arm_kernel_cmpxchg64_helper’:
linux-user/qemu.h:330:15: error: void value not ignored as it ought to be
         __ret = __put_user((x), __hptr);    \

Thus, remove setting __ret from __get_user and __put_user, as and
set the right hand operand to (void)0 to make it clear that these
return never nothing.

This commit depends on the signal.c cleanup, to ensure bisectable
version history.

Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Cc: Richard Henderson <rth@twiddle.net>
2014-06-17 08:52:08 +03:00
Riku Voipio
9e918dc927 signal/ppc/do_setcontext remove __get_user return check
The last remaining check for return value of __get_user.

Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Cc: Alexander Graf <agraf@suse.de>
2014-06-17 08:52:08 +03:00
Riku Voipio
be3ef5c7fa signal/sparc64_set_context: remove __get_user checks
Remove checks of __get_user and the err variable
used to control flow with it.

Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-17 08:52:08 +03:00
Riku Voipio
c650c008e3 signal/ppc/{save,restore}_user_regs remove __put/get error checks
As __get_user and __put_user do not return errors, remove the
if checks from around them. This allows making the save/restore
functions void.

Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Cc: Alexander Graf <agraf@suse.de>
2014-06-17 08:52:07 +03:00
Riku Voipio
0188fadb7f signal/all/setup_frame remove __put_user checks
Remove "if(__put_user" checks and their related error paths
for all architecture's setup_frame, setup_rt_frame and similar.

Remove the unlock_user_struct when the only way to end up there is
from failed lock_user_struct.

Remove err variable if there are no users for it in the function
anymore.

Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-17 08:52:07 +03:00
Riku Voipio
f5f601afce signal/all/do_sigreturn - remove __get_user checks
Remove "if(__get_user" checks and their related error paths
for all architecture's do_sigreturn. Remove the unlock_user_struct
when the only way to end up there is from failed lock_user_struct.

v3: remove unneccesary sigsegv label as suggested by Peter

Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-17 08:52:07 +03:00
Riku Voipio
9eeb8306d5 signal/all/do_sigaltstack remove __get_user value check
Access is already checked in the lock_user_struct
call before.

Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-17 08:52:07 +03:00
Riku Voipio
945473847b signal/sparc/restore_fpu_state: remove
A function never called from anywhere, obviously half-complete.
Remove function and if someone wants to complete this, please
check the old version out of git history.

Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-17 08:52:07 +03:00
Riku Voipio
016d2e1dfa signal/all: remove return value from restore_sigcontext
make most implementations of restore_sigcontext void and
remove checking it's return value from functions calling
restore_sigcontext.

The exception is the X86 version of the function that is
too different from others to deal in this way, and arm
version, to keep possibility of erroring out from failed
valid_user_regs.

v3: keep arm valid_user_regs for filling in near future.

Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-17 08:52:07 +03:00
Riku Voipio
41ecc72ba5 signal/all: remove return value from setup_sigcontext
Make all implementations of setup_sigcontext void and
remove checking it's return value from functions calling
setup_sigcontext.

Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-17 08:52:07 +03:00
Riku Voipio
b0fd8d1868 signal/all: remove return value from copy_siginfo_to_user
Since copy_siginfo_to_user always returns 0, make it void
and remove any checks for return value from calling functions.

Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-17 08:52:07 +03:00
Riku Voipio
7df2fa3623 signal/x86/setup_frame: __put_user cleanup
Remove the remaining check for __put_user return
value, and all the checks for err variable which
isn't set anywhere anymore.

No we can only end up in give_sigsegv due to failed
lock_user_struct - thus we remove the unlock_user_struct
to avoid unlocking a region never locked.

Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-17 08:52:07 +03:00
Riku Voipio
1d8b512bbc signal/all: remove __get/__put_user return value reading
Remove all the simple cases of reading the return value
of __get_user and __put_user.

We set err = 0 in sparc versions of do_sigreturn and
sparc64_set_context to avoid compile error, but else this patch is
just general removal of err |= __get_user ... idiom.

v2: remove err variable from target_rt_restore_ucontext

Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-17 08:52:07 +03:00
Peter Maydell
af44da87e9 Merge remote-tracking branch 'remotes/agraf/tags/signed-ppc-for-upstream' into staging
Patch queue for ppc - 2014-06-16

This pull request brings a lot of fun things. Among others we have

  - e500: u-boot firmware support
  - sPAPR: magic page enablement
  - sPAPR: add "compat" CPU option to support older guests
  - sPAPR: refactorings in preparation for VFIO
  - POWER8 live migration
  - mac99: expose bus frequency
  - little endian core dump, gdb and disas support
  - new ppc64le-linux-user target
  - DFP emulation
  - bug fixes

# gpg: Signature made Mon 16 Jun 2014 12:28:32 BST using RSA key ID 03FEDC60
# gpg: Can't check signature: public key not found

* remotes/agraf/tags/signed-ppc-for-upstream: (156 commits)
  spapr_pci: Advertise MSI quota
  PPC: KVM: Make pv hcall endian agnostic
  powerpc: use float64 for frsqrte
  spapr: Add kvm-type property
  spapr: Create SPAPRMachine struct
  linux-user: Tell guest about big host page sizes
  spapr_hcall: Add address-translation-mode-on-interrupt resource in H_SET_MODE
  spapr_hcall: Split h_set_mode()
  target-ppc: Enable DABRX SPR and limit it to <=POWER7
  target-ppc: Enable PPR and VRSAVE SPRs migration
  target-ppc: Add POWER8's Event Based Branch (EBB) control SPRs
  KVM: target-ppc: Enable TM state migration
  target-ppc: Add POWER8's TM SPRs
  target-ppc: Add POWER8's MMCR2/MMCRS SPRs
  target-ppc: Enable FSCR facility check for TAR
  target-ppc: Add POWER8's FSCR SPR
  target-ppc: Add POWER8's TIR SPR
  target-ppc: Refactor class init for POWER7/8
  target-ppc: Switch POWER7/8 classes to use correct PMU SPRs
  target-ppc: Make use of gen_spr_power5p_lpar() for POWER7/8
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-16 18:26:21 +01:00
Paolo Bonzini
f27701510c rules.mak: remove $(sort) from extract-libs
Duplicate removal was added to extract-libs in order to avoid including
the same library multiple times into the linking command line; this could
potentially happen when using "foo.mo-libs" (which adds the library to
all components, causing it to appear N times if the module is composed
of N objects).  However, sorting and removing duplicates causes problems
with static linking, and also with space-separated linker options as
found in some Mac OS X packaging systems.  Furthermore, the "optimization"
is really a non-problem since we do not expect .mo modules to be composed
of many files.

Reported-by: Sean Bruno <sbruno@ignoranthack.me>
Tested-by: Sean Bruno <sbruno@ignoranthack.me>
Reviewed-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Message-id: 1402929805-16836-1-git-send-email-pbonzini@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-16 16:01:50 +01:00
Peter Maydell
84219c5a21 Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging
Block pull request

# gpg: Signature made Mon 16 Jun 2014 12:22:22 BST using RSA key ID 81AB73C8
# gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>"
# gpg:                 aka "Stefan Hajnoczi <stefanha@gmail.com>"

* remotes/stefanha/tags/block-pull-request: (39 commits)
  QemuOpts: cleanup tmp 'allocated' member from QemuOptsList
  cleanup QEMUOptionParameter
  vpc.c: replace QEMUOptionParameter with QemuOpts
  vmdk.c: replace QEMUOptionParameter with QemuOpts
  vhdx.c: replace QEMUOptionParameter with QemuOpts
  vdi.c: replace QEMUOptionParameter with QemuOpts
  ssh.c: replace QEMUOptionParameter with QemuOpts
  sheepdog.c: replace QEMUOptionParameter with QemuOpts
  rbd.c: replace QEMUOptionParameter with QemuOpts
  raw_bsd.c: replace QEMUOptionParameter with QemuOpts
  raw-win32.c: replace QEMUOptionParameter with QemuOpts
  raw-posix.c: replace QEMUOptionParameter with QemuOpts
  qed.c: replace QEMUOptionParameter with QemuOpts
  qcow2.c: replace QEMUOptionParameter with QemuOpts
  QemuOpts: export qemu_opt_find
  qcow.c: replace QEMUOptionParameter with QemuOpts
  nfs.c: replace QEMUOptionParameter with QemuOpts
  iscsi.c: replace QEMUOptionParameter with QemuOpts
  gluster.c: replace QEMUOptionParameter with QemuOpts
  cow.c: replace QEMUOptionParameter with QemuOpts
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-16 12:27:47 +01:00
Badari Pulavarty
9dbae97723 spapr_pci: Advertise MSI quota
Hotplug of multiple disks fails due to MSI vector quota check.
Number of MSI vectors default to 8 allowing only 4 devices.
This happens on RHEL6.5 guest. RHEL7 and SLES11 guests fallback
to INTX.

One way to workaround the issue is to increase total MSIs,
so that MSI quota check allows us to hotplug multiple disks.

This sets the quota to the maximum number of interupts XICS has
which is 1024 now (XICS_IRQS). This moves XICS_IRQS from spapr.c
to xics.h for wider visibility.

Signed-off-by: Badari Pulavarty <pbadari@us.ibm.com>
[aik: put XICS_IRQS=1024 instead of 64i, fixed endianness and size]
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:46 +02:00
Alexander Graf
d13fc32ecf PPC: KVM: Make pv hcall endian agnostic
There were a few revisions of the Linux kernel that incorrectly swapped
the hcall instructions when they saw ePAPR compliant hypercalls.

We already have fixups for those in place when running with PR KVM, but
HV KVM and systems that don't implement hypercalls at all are still broken
because they fall back to the QEMU implementation of fallback hypercalls.

So let's make the fallback hypercall instruction path endian agnostic. This
only really works well for 64bit guests, but I don't think there are any 32bit
systems left that don't implement real pv hcall support, so we'll never get
into this code path.

Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:46 +02:00
Tristan Gingold
e223bcad6e powerpc: use float64 for frsqrte
Remove the code that reduce the result to float32 as the frsqrte
instruction is defined to return a double-precision estimate of
the reciprocal square root.

Although reducing the fractional part is harmless (as the estimation
must have at least 12 bits of precision according to the old PEM),
reducing the exponent range is not correct.

Signed-off-by: Tristan Gingold <gingold@adacore.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:46 +02:00
Eduardo Habkost
23825581d7 spapr: Add kvm-type property
The kvm-type machine option was left out when MachineState was
introduced, preventing the kvm-type option from being used. Add the
missing property to the sPAPR machine class, so it can be used.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Tested-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:46 +02:00
Eduardo Habkost
748abce94f spapr: Create SPAPRMachine struct
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Tested-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:46 +02:00
Alexander Graf
a70daba377 linux-user: Tell guest about big host page sizes
We tell the guest its page size via AUX vectors. The guest process then uses
this page size as information on which boundaries it can mmap() things.

However, if the host has a bigger page size granularity than the guest, it can
not fulfill these mmap() requests - which falls apart when MAP_FIXED is passed
to mmap.

So in that case, let the guest know that we're running on a bigger page size
granularity than the target would require.

This fixes running qemu-ppc (TARGET_PAGE_SIZE=4k) on a 64k page size ppc64 host
for me.

Signed-off-by: Alexander Graf <agraf@suse.de>
Reviewed-by: Richard Henderson <rth@twiddle.net>
2014-06-16 13:24:45 +02:00
Alexey Kardashevskiy
d5ac4f5433 spapr_hcall: Add address-translation-mode-on-interrupt resource in H_SET_MODE
This adds handling of the RESOURCE_ADDR_TRANS_MODE resource from
the H_SET_MODE, for POWER8 (PowerISA 2.07) only.

This defines AIL flags for LPCR special register.

This changes @excp_prefix according to the mode, takes effect in TCG.

This turns support of a new capability PPC2_ISA207S flag for TCG.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:45 +02:00
Alexey Kardashevskiy
c4015bbd50 spapr_hcall: Split h_set_mode()
This moves H_SET_MODE_RESOURCE_LE handler to a separate function
as there are other "resources" coming and this is going to become ugly.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:45 +02:00
Alexey Kardashevskiy
cd9adfdd77 target-ppc: Enable DABRX SPR and limit it to <=POWER7
This adds DABRX SPR.

As DABR(X) are present in POWER CPUs till POWER7 only and POWER8 does not
have them (as it implements more powerful facility instead), this limits
DABR/DABRX registration by POWER7 (inclusive).

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:45 +02:00
Alexey Kardashevskiy
7303f83db6 target-ppc: Enable PPR and VRSAVE SPRs migration
This hooks SPR with their "KVM set_one_reg" counterparts which enables
their migration.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:45 +02:00
Alexey Kardashevskiy
4ee4a03b38 target-ppc: Add POWER8's Event Based Branch (EBB) control SPRs
POWER8 supports Event-Based Branch Facility (EBB). It is controlled via
set of SPRs access to which should generate an "Facility Unavailable"
interrupt if the facilities are not enabled in FSCR for problem state.

This adds EBB SPRs.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:45 +02:00
Alexey Kardashevskiy
80b3f79b99 KVM: target-ppc: Enable TM state migration
This adds migration support for registers saved before Transactional
Memory (TM) transaction started.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:45 +02:00
Alexey Kardashevskiy
cdcdda27fc target-ppc: Add POWER8's TM SPRs
This adds TM (Transactional Memory) SPRs.

This adds generic spr_read_prev_upper32()/spr_write_prev_upper32() to
handle upper half SPRs such as TEXASRU which is upper half of TEXASR.
Since this is not the only register like that and their numbers go
consequently, it makes sense to generalize the helpers.

This adds a gen_msr_facility_check() helper which purpose is to generate
the Facility Unavailable exception if the facility is disabled.
It is a copy of gen_fscr_facility_check() but it checks for enabled
facility in MSR rather than FSCR/HFSCR. It still sets the interrupt cause
in FSCR/HFSCR (whichever is passed to the helper).

This adds spr_read_tm/spr_write_tm/spr_read_tm_upper32/spr_write_tm_upper32
which are used for TM SPRs.

This adds TM-relates MSR bits definitions. This enables TM in POWER8 CPU class'
msr_mask.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:45 +02:00
Alexey Kardashevskiy
70c5340744 target-ppc: Add POWER8's MMCR2/MMCRS SPRs
This adds POWER8 specific PMU MMCR2/MMCRS SPRs.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:44 +02:00
Alexey Kardashevskiy
45ed0be146 target-ppc: Enable FSCR facility check for TAR
This makes user-privileged read/write fail if TAR facility is not enabled
in FSCR.

Since this is the very first check for enabled in FSCR facility,
this also adds gen_fscr_facility_check() for using in spr_write_tar()/
spr_read_tar().

This enables TAR in FSCR for user mode unconditionally.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:44 +02:00
Alexey Kardashevskiy
7019cb3d88 target-ppc: Add POWER8's FSCR SPR
This adds an FSCR (Facility Status and Control Register) SPR. This defines
names for FSCR bits.

This defines new exception type - POWERPC_EXCP_FU - "facility unavailable" (FU).
This registers an interrupt vector for it at 0xF60 as PowerISA defines.

This adds a TCG helper_fscr_facility_check() helper to raise an exception
if the facility is not enabled. It updates the interrupt cause field
in FSCR. This adds a TCG translation block generation code. The helper
may be used for HFSCR too as it has the same format.

The helper raising FU exceptions is not used by this patch but will be
in the next ones.

This adds gen_update_current_nip() to update NIP in DisasContext.
This helper is not used now and will be called before checking for
a condition for throwing an FU exception.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:44 +02:00
Alexey Kardashevskiy
d1a721ab81 target-ppc: Add POWER8's TIR SPR
This adds TIR (Thread Identification Register) SPR first defined for server
CPUs in PowerISA 2.07.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:44 +02:00
Alexey Kardashevskiy
a242881405 target-ppc: Refactor class init for POWER7/8
This extends init_proc_book3s_64 to support POWER7 and POWER8.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:44 +02:00
Alexey Kardashevskiy
5881c296b9 target-ppc: Switch POWER7/8 classes to use correct PMU SPRs
This replaces gen_spr_7xx() call (which registers 32bit SPRs) with
gen_spr_book3s_pmu() call.

This removes SPR_7XX_PMC5/6 as they are for 32bit and gen_spr_book3s_pmu()
already registers correct PMC5/6 SPRs.

This removes explicit MMCRA registration as gen_spr_book3s_pmu() does it
anyway.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:44 +02:00
Alexey Kardashevskiy
7fc2db18ce target-ppc: Make use of gen_spr_power5p_lpar() for POWER7/8
This makes use of generic gen_spr_power5p_lpar() which registers LPCR SPR.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:44 +02:00
Alexey Kardashevskiy
6a1eed3f49 target-ppc: Make use of gen_spr_book3s_altivec() for POWER7/8
This replaces VRSAVE registration and vscr_init() call with
gen_spr_book3s_altivec() which is generic and does the same thing if
insns_flags has PPC_ALTIVEC bit set (which POWER7/8 have set).

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:44 +02:00
Alexey Kardashevskiy
5db7d4faa3 target-ppc: Move POWER7/8 CFAR/DSCR/CTRL/PPR/PCR SPR registration to helpers
This moves SCFAR/DSCR/CTRL/PPR/PCR PRs to helpers. Later these helpers
will be called from generalized init_proc_book3s_64().

This switches init_proc_POWER7() to use generalized gen_spr_book3s_common()
which registers CRTL SPR under slightly different names. No change in
behaviour or non-debug output is expected.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:43 +02:00
Alexey Kardashevskiy
768167abb9 target-ppc: Move POWER8 TCE Address control (TAR) to a helper
This moves TAR SPR to a helper. Later this helper will be
called from generalized init_proc_book3s_64().

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:43 +02:00
Alexey Kardashevskiy
e61716aa9a target-ppc: Move POWER7/8 PIR/PURR/SPURR SPR registration to helpers
This moves PIR/PURR/SPURR SPRs to helpers. Later these helpers will be
called from generalized init_proc_book3s_64().

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:43 +02:00
Alexey Kardashevskiy
83cc6f8c2f target-ppc: Enable PMU SPRs migration
This enabled PMU SPRs migration by hooking hypv privileged versions with
"KVM one reg" IDs.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:43 +02:00
Alexey Kardashevskiy
90618f4f4d target-ppc: Remove check_pow_970FX
After merging 970s into one class, check_pow_970() is used for all of them.
Since POWER5+ is no different in the matter of supported power modes,
let's use the same check_pow() callback for POWER5+ too,

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:43 +02:00
Alexey Kardashevskiy
7488d481ce target-ppc: Introduce and reuse generalized init_proc_book3s_64()
At the moment every POWER CPU family has its own init_proc_POWERX function.
E500 already has common init function so we try to do the same thing.

This introduces BOOK3S_CPU_TYPE enum with 2 values - 970 and POWER5+.

This introduces generalized init_proc_book3s_64() which accepts a CPU type
as a parameter.

This uses new init function for 970 and POWER5+ CPU classes.

970 and POWER5+ use the same CPU class initialization except 3 things:
1. logical partitioning is controlled by LPCR (POWER5+) and HID4 (970)
SPRs;
2. 970 does not have EAR (External Access Register) SPR and PowerISA 2.03
defines one so keep it only for POWER5+;
3. POWER5+ does not have ALTIVEC so insns_flags does not have PPC_ALTIVEC
flag set and gen_spr_book3s_altivec() won't init ALTIVEC for POWER5+.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:43 +02:00
Alexey Kardashevskiy
ba88100219 target-ppc: Add HID4 SPR for PPC970
Previously LPCR was registered for the 970 class which was wrong as
it does not have LPCR. Instead, HID4 is used which this patch registers.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:43 +02:00
Alexey Kardashevskiy
c36c97f880 target-ppc: Add PMC7/8 to 970 class
Compared to PowerISA-compliant CPUs, 970 family has most of them plus
PMC7/8 which are only present on 970 but not on POWER5 and later CPUs.

Since we are changing SPRs for Book3s/970 families, let's add them too.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:43 +02:00
Alexey Kardashevskiy
077850b037 target-ppc: Add PMC5/6, SDAR and MMCRA to 970 family
MMCR0, MMCR1, MMCRA, PMC1..6, SIAR, SDAR are defined for 970 and PowerISA
CPUs. Since we are building common infrastructure for SPRs intialization
to share it between 970 and POWER5+/7/..., let's add missing SPRs to
the 970 family. Later rework of CPU class initialization will use those
for all PowerISA CPUs.

This adds new SPRs and enables writing to Uxxxx SPRs from supermode.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:42 +02:00
Alexey Kardashevskiy
75b9c321f4 target-ppc: Add "POWER" prefix to MMCRA PMU registers
Since we started adding "POWER" prefix to 64bit PMU SPRs, let's finish
the transition and fix MMCRA and define a supermode version of it.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:42 +02:00
Alexey Kardashevskiy
fd51ff6328 target-ppc: Copy and split gen_spr_7xx() for 970
This stops using 7xx common SPRs init function and adds separate set
of helpers for 970.

This does not copy ICTC SPR as neither 970 manual nor PowerISA mention it.

This defines 970/book3s PMU SPRs constants as they differs from the ones
used for 7XX.

This creates 2 helpers for PMU SPRs, one for supermode privileged SPRs and
one for user privileged SPRs as "sup" versions can be shared across
the family while "user" versions will behave different starting POWER8
(which will be addressed later).

This allows writing to Uxxxx SPRs from supermode. spr_write_ureg() is
implemented for this as a copy of already existing spr_read_ureg().

This allows writing to supervisor's SIAR - it used to be disabled
when gen_spr_7xx() was used.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:42 +02:00
Alexey Kardashevskiy
eb16dd9cc9 target-ppc: Make UCTRL a mirror of CTRL
This changes UCTRL SPR to read from its supermode copy.

This enables reading from UCTRL in user mode.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:42 +02:00
Alexey Kardashevskiy
42382f6244 target-ppc: Refactor PPC970
This splits one init_proc_970() into a set of small helpers. Later
init_proc_970() will be generalized and will call different set of helpers
depending on the current CPU class.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:42 +02:00
Alexey Kardashevskiy
bbc01ca7f2 target-ppc: Merge 970FX and 970MP into a single 970 class
The differences between classes were:
1. SLB size, was 32 for 970 and 64 for others, should be 64 for all;
2. check_pow() callback, HID0 format is the same so should be the same
0x01C00000 which means "deep nap", "doze" and "nap" bits set;
3. LPCR - 970 does not have it but 970MP had one (by mistake).

This fixes wrong differences and makes one 970 class.

This fixes wrong registration of LPCR which is not present on 970.

This defines HID0 bits and uses them in check_pow_970().

This does not copy MSR_SHV (Hypervisor State, HV) bit from 970FX to
970 class as we do not emulate hypervisor in QEMU anyway.

This does not remove check_pow_970FX now as it is still used by POWER5+
class, this will be addressed later.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:42 +02:00
Alexey Kardashevskiy
cb8b8bf840 target-ppc: Rename 7XX/60x/74XX/e600 PMU SPRs
As defined in Linux kernel, PMC*, SIAR, MMCR0/1 have different numbers
for 32 and 64 bit POWERPC. We are going to support 64bit versions too so
let's rename 32bit ones to avoid confusion.

This is a mechanical patch so it does not fix obvious mistake with these
registers in POWER7 yet, this will be fixed later.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:42 +02:00
Tom Musta
a9e8f4e7df target-ppc: Fix Temporary Variable Leak in bctar
Fix a temporary variable leak detected in the bctar instruction:

   Opcode 13 10 11 (4d910460) leaked temporaries

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:42 +02:00
Alexander Graf
13b6a45565 PPC: e500: Merge 32 and 64 bit SPE emulation
Today we have a lot of conditional code in the SPE emulation depending on
whether we have 64bit GPRs or not.

Unfortunately the assumption that we can just recycle the 64bit GPR
implementation is wrong. Normal SPE implementations maintain the upper 32 bits
on all non-SPE instructions which then only modify the low 32 bits. However
all instructions we model that adhere to the normal SF based switching don't
care whether they operate on 32 or 64 bit registers and just always use the full
64 bits.

So let's remove that dubious SPE optimization and revert everything to the same
code path the 32bit target code was taking. That way we get rid of differences
between the two implementations, but will get a slight performance hit when
emulating SPE instructions.

This fixes SPE emulation with qemu-system-ppc64 for me.

Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:41 +02:00
Alexander Graf
f7d6914654 PPC: spapr: Expose /hypervisor node in device tree
PR KVM supports an ePAPR compliant hypercall interface in parallel to the
normal sPAPR one. Expose the ePAPR /hypervisor node and properties to the
guest so it can use it.

This enables magic page sharing on PR KVM with -M pseries.

However we had a few nasty bugs in the magic page implementation on vcpus
newer than 970 (p7, p8) that KVM now has workarounds for. It indicates that
it does have these workarounds through the PPC_FIXUP_HCALL capability.

To not expose broken guest kernels to issues on host kernels that don't
have the fixups in place, we don't expose working hypercall instructions
when the fixups are not available so that the guest can never active the
magic page.

Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:41 +02:00
Alexander Graf
87a91de61a KVM: PPC: Expose fixup hcall capability
New kvm versions expose a PPC_FIXUP_HCALL capability. Make it visible to
machine code so we can take decisions based on it.

Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:41 +02:00
Alexander Graf
b061808d39 linux-headers: update linux headers to kvm/next
This updates the kvm headers to commit 820b3fcd in kvm/next.

Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:41 +02:00
Alexander Graf
2872e1929b linux-headers: include psci.h
The kvm headers now have a dependency on psci.h, sync it into our linux
header copy as well.

Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:41 +02:00
Alexander Graf
ada82b537e PPC: SPE: Fix high-bits bitmask
The SPE emulation code wants to access the highest 32bits of a 64bit register
and uses the andi TCG instruction for that. Unfortunately it masked with the
wrong mask. Fix the mask to actually cover the upper 32 bits.

This fixes simple multiplication tests with SPE guests for me.

Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:41 +02:00
Alexander Graf
deb6ed13eb PPC: e500: Fix TLB lookup for 32bit CPUs
When we run 32bit guest CPUs (or 32bit guest code on 64bit CPUs) on
qemu-system-ppc64 the TLB lookup will use the full effective address
as pointer.

However, only the first 32bits are valid when MSR.CM = 0. Check for
that condition.

This makes QEMU boot an e500v2 guest with more than 1G of RAM for me.

Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:41 +02:00
Peter Maydell
f2e2bc9ca0 hw/pci-host/ppce500: Fix typo in vmstate definition
Fix a typo in the ppce500_pci vmstate definition which meant that
we were migrating the struct pci_inbound using the vmstate for
pci_outbound. Fortunately the two structures have exactly the same
format at the moment (four uint32_ts) so this was harmless, and
we can correcting the typo without a migration compatibility
break because the vmstate name doesn't go out on the wire.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:41 +02:00
Tom Musta
4b1daa72d3 target-ppc: Store Quadword Conditional Drops Size Bit
The size and register information are encoded into the reserve_info field
of CPU state in the store conditional translation code.  Specifically, the
size is shifted left by 5 bits (see target-ppc/translate.c gen_conditional_store).

The user-mode store conditional code erroneously extracts the size by ANDing
with a 4 bit mask; this breaks if size >= 16.

Eliminate the mask to make the extraction of size mirror its encoding.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:40 +02:00
Tom Musta
f46e9a0b99 target-ppc: Confirm That .bss Pages Are Valid
The existing code does a check to ensure that a .bss region is properly
mmap'd.  When additional mmap is required, the (guest) pages are also
validated.  However, this code has a bug: when host page size is larger
than target page size, it is possible for the .bss pages to already be
(host) mapped but the guest .bss pages may not be valid.

The check to mmap additional space is separated from the flagging of the
target (guest) pages, thus ensuring that both aspects are done properly.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:40 +02:00
Tom Musta
5b274ed74d target-ppc: Support VSX in PPC User Mode
Some modern tool chains use VSX instructions.  Therefore attempt to enable the VSX MSR
bit by default, just like similar bits (FP, VEC, SPE, etc.).

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:40 +02:00
Doug Kwan
9c35126c56 target-ppc: Add a new user mode target for little-endian PPC64.
Signed-off-by: Doug Kwan <dougkwan@google.com>
Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:40 +02:00
Doug Kwan
e22c357b3e target-ppc: Allow little-endian user mode.
This allows running PPC64 little-endian in user mode if target is configured
that way.  In PPC64 LE user mode we set MSR.LE during initialization.

Signed-off-by: Doug Kwan <dougkwan@google.com>
Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:40 +02:00
Doug Kwan
d90b94cd78 target-ppc: Support little-endian PPC64 in user mode.
Look at ELF header to determine ABI version on PPC64.  This is required
for executing the first instruction correctly.  Also print correct machine
name in uname() system call.

Signed-off-by: Doug Kwan <dougkwan@google.com>
Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:40 +02:00
Alex Zuepke
a721d390b3 PPC: e500: Fix MMUCSR0 emulation
A  "mtspr SPRMMUCSR0, reg"  always flushed TLB0,
because it passed the SPR number 0x3f4 to the flush routine.
But we want to flush either TLB0 or TBL1 depending on the GPR value.

Signed-off-by: Alex Zuepke <alexander.zuepke@hs-rm.de>
[agraf: change subject line, fix TCGv size mismatch]
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:40 +02:00
Alexey Kardashevskiy
1b8eceee28 spapr_iommu: Introduce bus_offset in sPAPRTCETable
This adds @bus_offset into sPAPRTCETable to tell where TCE table starts
from. It is set to 0 for emulated devices. Dynamic DMA windows will use
other offset.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:39 +02:00
Alexey Kardashevskiy
650f33adbd spapr_iommu: Introduce page_shift in sPAPRTCETable
At the moment only 4K pages are supported by sPAPRTCETable. Since sPAPR
spec allows other page sizes and we are going to implement them, we need
page size to be configrable.

This adds @page_shift into sPAPRTCETable and replaces SPAPR_TCE_PAGE_SHIFT
with it where it is possible.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:39 +02:00
Alexey Kardashevskiy
523e7b8ab8 spapr_iommu: Get rid of window_size in sPAPRTCETable
This removes window_size as it is basically a copy of nb_table
shifted by SPAPR_TCE_PAGE_SHIFT. As new dynamic DMA windows are
going to support windows as big as the entire RAM and this number
will be bigger that 32 capacity, we will have to do something
about @window_size anyway and removal seems to be the right way to go.

This removes dma_window_start/dma_window_size from sPAPRPHBState as
they are no longer used.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:39 +02:00
Alexey Kardashevskiy
e4c35b78bc spapr_iommu: Convert old qdev_init_nofail() to object_property_set_bool
qdev_init_nofail() was replaced by object_property_set_bool("realized")
all over the QEMU so do we.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:39 +02:00
Alexey Kardashevskiy
e28c16f61f spapr_pci: Allow multiple TCE tables per PHB
At the moment sPAPRPHBState contains a @tcet pointer to the only
TCE table. However sPAPR spec allows having more than one DMA window.

Since the TCE object is already a child of SPAPR PHB object, there is
no need to keep an additional pointer to it in sPAPRPHBState so remove it.

This changes the way sPAPRPHBState::reset performs reset of sPAPRTCETable
objects.

This changes the default DMA window properties calculation.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:39 +02:00
Alexey Kardashevskiy
cca7fad576 spapr_pci: spapr_iommu: Make DMA window a subregion
Currently the default DMA window is represented by a single MemoryRegion.
However there can be more than just one window so we need
a "root" memory region to be separated from the actual DMA window(s).

This introduces a "root" IOMMU memory region and adds a subregion for
the default DMA 32bit window. Following patches will add other
subregion(s).

This initializes a default DMA window subregion size to the guest RAM
size as this window can be switched into "bypass" mode which implements
direct DMA mapping.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:39 +02:00
Alexey Kardashevskiy
da6ccee418 spapr_pci: Introduce a finish_realize() callback
The spapr-pci PHB initializes IOMMU for emulated devices only.
The upcoming VFIO support will do it different. However both emulated
and VFIO PHB types share most of the initialization code.
For the type specific things a new finish_realize() callback is
introduced.

This introduces sPAPRPHBClass derived from PCIHostBridgeClass and
adds the callback pointer.

This implements finish_realize() for emulated devices.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
[agraf: Fix compilation]
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:39 +02:00
Alexey Kardashevskiy
da95324ebe spapr_iommu: Enable multiple TCE requests
Currently only single TCE entry per request is supported (H_PUT_TCE).
However PAPR+ specification allows multiple entry requests such as
H_PUT_TCE_INDIRECT and H_STUFF_TCE. Having less transitions to the host
kernel via ioctls, support of these calls can accelerate IOMMU operations.

This implements H_STUFF_TCE and H_PUT_TCE_INDIRECT.

This advertises "multi-tce" capability to the guest if the host kernel
supports it (KVM_CAP_SPAPR_MULTITCE) or guest is running in TCG mode.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:39 +02:00
Alexey Kardashevskiy
a1d59c0ffa spapr: Enable dynamic change of the supported hypercalls list
At the moment the "ibm,hypertas-functions" list is fixed. However some
calls should be listed there if they are supported by QEMU or the host
kernel.

This enables hyperrtas_prop to grow on stack by adding
a SPAPR_HYPERRTAS_ADD macro. "qemu,hypertas-functions" is converted as well.

The first user of this is going to be a "multi-tce" property.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:38 +02:00
Alexander Graf
9397a7c831 macio: Fix timer endianness
The timer registers on our KeyLargo macio emulation are read as byte reversed
from the big endian guest, so we better expose them endian reversed as well.

This fixes initial hickups of booting Mac OS X with -M mac99 for me.

Signed-off-by: Alexander Graf <agraf@suse.de>
Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
2014-06-16 13:24:38 +02:00
Alexander Graf
3e300fa6ad macio ide: Do remainder access asynchronously
The macio IDE controller has some pretty nasty magic in its implementation to
allow for unaligned sector accesses. We used to handle these accesses
synchronously inside the IO callback handler.

However, the block infrastructure changed below our feet and now it's impossible
to call a synchronous block read/write from the aio callback handler of a
previous block access.

Work around that limitation by making the unaligned handling bits also go
through our asynchronous handler.

This fixes booting Mac OS X for me.

Reported-by: John Arbuckle <programmingkidx@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:38 +02:00
Tom Musta
6ab39b1bd3 target-ppc: Fix popcntb Opcode Bug
The popcntb instruction is erroneously encoded with opcode extension (opc1,opc2) = (0x03,0x03).
Bits 21-30 of popcntb are 122 = 0b00011-0b11010 and therefore this should be encoded
as (opc1,opc2) = (0x1A, 0x03).

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:38 +02:00
Alexey Kardashevskiy
00d4f525ec spapr_iommu: Replace @instance_id with LIOBN for migration
SPAPR IOMMU is a bus-less device and therefore its only ID in
migration stream is an instance id which is not reliable ID
as it depends on the command line parameters order. Since
libvirt may change the order, we need something better than that.

This removes VMSD descriptor from the class definitiion and
registers it with @liobn as an intance ID to let the destination
side find the right device to receive migration data.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:38 +02:00
Alexey Kardashevskiy
6db5bb0f54 KVM: PPC: Enable compatibility mode
The host kernel implements a KVM_REG_PPC_ARCH_COMPAT register which
this uses to enable a compatibility mode if any chosen.

This sets the KVM_REG_PPC_ARCH_COMPAT register in KVM. ppc_set_compat()
signals the caller if the mode cannot be enabled by the host kernel.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
[agraf: fix TCG compat setting]
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:38 +02:00
Alexey Kardashevskiy
3794d5482d spapr: Implement processor compatibility in ibm, client-architecture-support
Modern Linux kernels support last POWERPC CPUs so when a kernel boots,
in most cases it can find a matching cpu_spec in the kernel's cpu_specs
list. However if the kernel is quite old, it may be missing a definition
of the actual CPU. To provide an ability for old kernels to work on modern
hardware, a Processor Compatibility Mode has been introduced
by the PowerISA specification.

>From the hardware prospective, it is supported by the Processor
Compatibility Register (PCR) which is defined in PowerISA. The register
enables one of the compatibility modes (2.05/2.06/2.07).
Since PCR is a hypervisor privileged register and cannot be
directly accessed from the guest, the mode selection is done via
ibm,client-architecture-support (CAS) RTAS call using which the guest
specifies what "raw" and "architected" CPU versions it supports.
QEMU works out the best match, changes a "cpu-version" property of
every CPU and notifies the guest about the change by setting these
properties in the buffer passed as a response on a custom H_CAS hypercall.

This implements ibm,client-architecture-support parameters parsing
(now only for PVRs) and cooks the device tree diff with new values for
"cpu-version", "ibm,ppc-interrupt-server#s" and
"ibm,ppc-interrupt-server#s" properties.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:38 +02:00
Alexey Kardashevskiy
2a48d99335 spapr: Limit threads per core according to current compatibility mode
This puts a limit to the number of threads per core based on the current
compatibility mode. Although PowerISA specs do not specify the maximum
threads per core number, the linux guest still expects that
PowerISA2.05-compatible CPU supports only 2 threads per core as this
is what POWER6 (2.05 compliant CPU) implements, the same is for
POWER7 (2.06, 4 threads) and POWER8 (2.07, 8 threads).

This calls spapr_fixup_cpu_smt_dt() with the maximum allowed number of
threads which affects ibm,ppc-interrupt-server#s and
ibm,ppc-interrupt-gserver#s properties.

The number of CPU nodesremains unchanged.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:38 +02:00
Alexey Kardashevskiy
82677ed2f5 spapr: Rework spapr_fixup_cpu_dt()
In PPC code we usually use the "cs" name for a CPUState* variables
and "cpu" for PowerPCCPU. So let's change spapr_fixup_cpu_dt() to
use same rules as spapr_create_fdt_skel() does.

This adds missing nodes creation if they do not already exist in
the current device tree, this is going to be used from
the client-architecture-support handler.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:37 +02:00
Alexey Kardashevskiy
2a6593cb6a spapr: Add ibm, client-architecture-support call
The PAPR+ specification defines a ibm,client-architecture-support (CAS)
RTAS call which purpose is to provide a negotiation mechanism for
the guest and the hypervisor to work out the best compatibility parameters.
During the negotiation process, the guest provides an array of various
options and capabilities which it supports, the hypervisor adjusts
the device tree and (optionally) reboots the guest.

At the moment the Linux guest calls CAS method at early boot so SLOF
gets called. SLOF allocates a memory buffer for the device tree changes
and calls a custom KVMPPC_H_CAS hypercall. QEMU parses the options,
composes a diff for the device tree, copies it to the buffer provided
by SLOF and returns to SLOF. SLOF updates the device tree and returns
control to the guest kernel. Only then the Linux guest parses the device
tree so it is possible to avoid unnecessary reboot in most cases.

The device tree diff is a header with an update format version
(defined as 1 in this patch) followed by a device tree with the properties
which require update.

If QEMU detects that it has to reboot the guest, it silently does so
as the guest expects reboot to happen because this is usual pHyp firmware
behavior.

This defines custom KVMPPC_H_CAS hypercall. The current SLOF already
has support for it.

This implements stub which returns very basic tree (root node,
no properties) to the guest.

As the return buffer does not contain any change, no change in behavior is
expected.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:37 +02:00
Alexey Kardashevskiy
1a68b71419 target-ppc: Define Processor Compatibility Masks
This introduces PCR mask for supported compatibility modes.
This will be used later by the ibm,client-architecture-support call.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:37 +02:00
Alexey Kardashevskiy
6d9412ea81 target-ppc: Implement "compat" CPU option
This adds basic support for the "compat" CPU option. By specifying
the compat property, the user can manually switch guest CPU mode from
"raw" to "architected".

This defines feature disable bits which are not used yet as, for example,
PowerISA 2.07 says if 2.06 mode is selected, the TM bit does not matter -
transactional memory (TM) will be disabled because 2.06 does not define
it at all. The same is true for VSX and 2.05 mode. So just setting a mode
must be ok.

This does not change the existing behavior as the actual compatibility
mode support is coming in next patches.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
[agraf: fix compilation on 32bit hosts]
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:37 +02:00
Alexey Kardashevskiy
833d46685d spapr: Move SMT-related properties out of skeleton fdt
The upcoming support of the "ibm,client-architecture-support"
reconfiguration call will be able to change dynamically the number
of threads per core (SMT mode). From the device tree prospective
this does not change the number of CPU nodes (as it is one node per
a CPU core) but affects content and size of the ibm,ppc-interrupt-server#s
and ibm,ppc-interrupt-gserver#s properties.

This moves ibm,ppc-interrupt-server#s and ibm,ppc-interrupt-gserver#s
out of the device tree skeleton.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:37 +02:00
Alexey Kardashevskiy
8dfa3a5e85 target-ppc: Add "compat" CPU option
PowerISA defines a compatibility mode for server POWERPC CPUs which
is supported by the PCR special register which is hypervisor privileged.
To support this mode for guests, SPAPR defines a set of virtual PVRs,
one per PowerISA spec version. When a hypervisor needs a guest to work in
a compatibility mode, it puts a virtual PVR value into @cpu-version
property of a CPU node.

This introduces a "compat" CPU option which defines maximal compatibility
mode enabled. The supported modes are power6/power7/power8.

This does not change the existing behaviour, new property will be used
by next patches.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:37 +02:00
Alexander Graf
af354f19a9 PPC: openpic_kvm: Implement reset
When we trigger a system reset, the in-kernel openpic controller should also
get reset. This happens through a write to the GCR.RESET register which is
the same mechanism a guest would use to manually reset the device.

Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:36 +02:00
Paul Janzen
ffd5e9fe02 openpic: Reset IRQ source private members
The openpic emulation code maintains an allowable-CPU's bitmap
("destmask") for each IRQ source which is calculated from the IDR
register value whenever the guest OS writes to it.  However, if the
guest OS relies on the system to set the IDR register to a default
value at reset, and does not write IDR, then destmask does not get
updated, and interrupts do not get propagated to the guest.
Additionally, if an IRQ source is marked as critical, the source's
internal "output" and "nomask" fields are not correctly reset when the
PIC is reset.

Fix both these issues by calling write_IRQreg_idr from within
openpic_reset, instead of simply setting the IDR register to the
specified idr_reset value.

Signed-off-by: Paul Janzen <pcj@pauljanzen.org>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:36 +02:00
Paul Janzen
8ebe65f361 openpic: Move definition of openpic_reset
This patch moves the definition of openpic_reset after the various
register read/write functions. No functional change.  It is in
preparation for using the register read/write functions in
openpic_reset.

Signed-off-by: Paul Janzen <pcj@pauljanzen.org>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:36 +02:00
Bharata B Rao
1e6ed54ef8 target-ppc: Set the correct endianness in ELF dump header
Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
Reviewed-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:36 +02:00
Greg Kurz
382d2db62b target-ppc: Introduce callback for interrupt endianness
POWER7, POWER7+ and POWER8 families use the ILE bit of the LPCR
special purpose register to decide the endianness to use when
entering interrupt handlers. When running a Linux guest, this
provides a hint on the endianness used by the kernel. And when
it comes to dumping a guest, the information is needed to write
ELF headers using the kernel endianness.

Suggested-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Reviewed-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
[agraf: change subject line]
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:36 +02:00
Bharata B Rao
0c967de9c0 target-ppc: Support dump for little endian ppc64
Fix ppc64 arch specific dump code to support all combinations of little/big
endian hosts/guests. FWIW the current code is broken for altivec registers
when guest and host have a different endianness: these 128-bit registers
are written to guest memory as a two 64-bit entities and we should also swap
them.

Unit testing was done with the following program provided by Tom Musta:

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

int main(int argc, char** argv)
{

__uint128_t v = ((__uint128_t)0x0001020304050607ull << 64) |
0x08090a0b0c0d0e0full;

register void * vptr asm ("r11");
vptr = &v;

for(;;)
asm volatile ("lvx 30,0,11" );
}

When sending SIGABRT to this program and examining the core file, we get:

- ppc64  : 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
- ppc64le: 0f 0e 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00

We expect to find the very same layout in the QEMU dump since they are
real core files. This is what we get:

- ppc64 host, ppc64 guest   : 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
- ppc64 host, ppc64le guest : 0f 0e 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00
- x86_64 host, ppc64 guest  : 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
- x86_64 host, ppc64le guest: 0f 0e 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00

We introduce a NoteFuncArg type to avoid adding extra arguments to all note
functions.

Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
[ rebased on top of current master branch,
  introduced NoteFuncArg,
  use new cpu_to_dump{16,32,64} endian helpers,
  fix altivec support,
  Greg Kurz <gkurz@linux.vnet.ibm.com> ]
Reviewed-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:36 +02:00
Bharata B Rao
acb0ef5801 dump: Make DumpState and endian conversion routines available for arch-specific dump code
Make DumpState and endian conversion routines available for arch-specific dump
code by moving into dump.h. DumpState will be needed by arch-specific dump
code to access target endian information from DumpState->ArchDumpInfo. Also
break the dependency of dump.h from stubs/dump.c by creating a separate
dump-arch.h.

This patch doesn't change any functionality.

Signed-off-by: Bharata B Rao <bharata@linux.ibm.com>
[ rebased on top of current master branch,
  renamed endian helpers to cpu_to_dump{16,32,64},
  pass a DumpState * argument to endian helpers,
  Greg Kurz <gkurz@linux.vnet.ibm.com> ]
Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
[agraf: fix to apply]
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:36 +02:00
Mark Cave-Ayland
85720d3667 macio: handle non-block ATAPI DMA transfers
Currently the macio DMA routines assume that all DMA requests are for read/write
block transfers. This is not always the case for ATAPI, for example when
requesting a TOC where the response is generated directly in the IDE buffer.

Detect these non-block ATAPI DMA transfers (where no lba is specified in the
command) and copy the results directly into RAM as indicated by the DBDMA
descriptor. This fixes CDROM access under MorphOS.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:36 +02:00
Alexey Kardashevskiy
10582ff832 spapr: Add ibm, chip-id property in device tree
This adds a "ibm,chip-id" property for CPU nodes which should be the same
for all cores in the same CPU socket. The recent guest kernels use this
information to associate threads with sockets.

Refer to the kernel commit 256f2d4b463d3030ebc8d2b54f427543814a2bdc
for more details.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:35 +02:00
Alexey Kardashevskiy
98a8b52442 spapr: Add support for time base offset migration
This allows guests to have a different timebase origin from the host.

This is needed for migration, where a guest can migrate from one host
to another and the two hosts might have a different timebase origin.
However, the timebase seen by the guest must not go backwards, and
should go forwards only by a small amount corresponding to the time
taken for the migration.

This is only supported for recent POWER hardware which has the TBU40
(timebase upper 40 bits) register. That includes POWER6, 7, 8 but not
970.

This adds kvm_access_one_reg() to access a special register which is not
in env->spr. This requires kvm_set_one_reg/kvm_get_one_reg patch.

The feature must be present in the host kernel.

This bumps vmstate_spapr::version_id and enables new vmstate_ppc_timebase
only for it. Since the vmstate_spapr::minimum_version_id remains
unchanged, migration from older QEMU is supported but without
vmstate_ppc_timebase.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:35 +02:00
Alexander Graf
3812c71ffa PPC: e500: Move to u-boot as firmware
Almost all platforms QEMU emulates have some sort of firmware they can load
to expose a guest environment that closely resembles the way it would look
like on real hardware.

This patch introduces such a firmware on our e500 platforms. U-boot is the
default firmware for most of these systems and as such our preferred choice.

For backwards compatibility reasons (and speed and simplicity) we skip u-boot
when you use -kernel and don't pass in -bios. For all other combinations like
-kernel and -bios or no -kernel you get u-boot as firmware.

This allows you to modify the boot environment, execute a networked boot through
the e1000 emulation and execute u-boot payloads.

Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:35 +02:00
Alexander Graf
4e73c78192 PPC: Add u-boot firmware for e500
This adds a special build of u-boot tailored for the e500 platforms we
emulate. It is based on the current version of upstream u-boot which
contains all the code necessary to drive our QEMU provided machines.

Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:35 +02:00
Alexander Graf
903585dec6 PPC: e500: Expose kernel load address in dt
We want to move to a model where firmware loads our kernel. To achieve
this we need to be able to tell firmware where the kernel lies.

Let's copy the mechanism we already use for -M pseries and expose the
kernel load address and size through the device tree.

Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:35 +02:00
Alexander Graf
4d09d5291d PPC: Add dcbtls emulation
The dcbtls instruction is able to lock data inside the L1 cache.

Unfortunately we don't emulate any caches, so we have to tell the guest
that its locking attempt failed.

However, by implementing the instruction we at least don't give the
guest a program exception which it definitely does not expect.

Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:35 +02:00
Alexander Graf
ea71258da4 PPC: Properly emulate L1CSR0 and L1CSR1
There are 2 L1 cache control registers - one for data (L1CSR0) and
one for instructions (L1CSR1).

Emulate both of them well enough to give the guest the illusion that
it could actually do anything about its caches.

Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:35 +02:00
Alexander Graf
d2ea2bf740 PPC: Add L1CFG1 SPR emulation
In addition to the L1 data cache configuration register L1CFG0 there is
also another one for the L1 instruction cache called L1CFG1.

Emulate that one with the same values as the data one.

Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:34 +02:00
Alexander Graf
deb05c4c4c PPC: Fix SPR access control of L1CFG0
The L1CFG0 register on e200 and e500 is "User RO" according to the
specifications. So let's make it user readable and world unwritable.

Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:34 +02:00
Alexander Graf
45eb56110b PPC: Add definitions for GIVORs
We're missing SPR definitions for GIVORs. Add them to the list of SPRs.

Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:34 +02:00
Alexander Graf
f1d9ec8bf7 PPC: Make all e500 CPUs SVR aware
Our pre-e500mc e500 CPU types didn't get instanciated with SVR information,
even though those systems do support the SVR register.

Spawn them with the SVR tag so that they don't get confused when someone tries
to read SPR_SVR.

Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:34 +02:00
Alexander Graf
3de3179782 PPC: Fail on leaking temporaries
When QEMU gets compiled with --enable-debug-tcg we can check for temporary
leakage. Implement the necessary target code for this and fail emulation
when we hit a leakage.

This hopefully ensures that we don't get new leaks.

Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:34 +02:00
Alexander Graf
c80d1df508 PPC: Fix TCG chunks that don't free their temps
We want to make sure that every instruction cleans up after itself and
clears every temporary it allocated.

While checking whether this is already the case, I came across a few
cases where it isn't. This patch fixes every translation I found that
doesn't free their allocated temporaries.

Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:34 +02:00
Bharat Bhushan
3016dca06c PPC: e500: implement PCI INTx routing
This patch adds pci pin to irq_num routing callback.
This callback is called from pci_device_route_intx_to_irq to
find which pci device maps to which irq.
This fix is required for pci-device passthrough using vfio.

Also without this patch we gets below prints

"
  PCI: Bug - unimplemented PCI INTx routing (e500-pcihost)
  qemu-system-ppc64: PCI: Bug - unimplemented PCI INTx routing (e500-pcihost) "

and Legacy interrupt does not work with pci device passthrough.

Signed-off-by: Bharat Bhushan <Bharat.Bhushan@freescale.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
[agraf: remove double semicolon]
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:34 +02:00
Bharat Bhushan
d575a6ce0e PPC: e500: some pci related cleanup
- Use PCI_NUM_PINS rather than hardcoding
 - use "pin" wherever possible

Signed-off-by: Bharat Bhushan <Bharat.Bhushan@freescale.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:34 +02:00
Alexander Graf
08215d8fd8 KVM: PPC: Don't secretly add 1T segment feature to CPU
When we select a CPU type that does not support 1TB segments, we should
not expose 1TB just because KVM supports 1TB segments. User configuration
always wins over feature availability.

Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:33 +02:00
Tom Musta
c15424531f target-ppc: Refactor AES Instructions
This patch refactors the PowerPC Advanced Encryption Standard (AES) instructions
to use the common AES tables (include/qemu/aes.h).

Specifically:
    - vsbox is recoded to use the AES_sbox table.
    - vcipher, vcipherlast and vncipherlast are all recoded to use the optimized
      AES_t[ed][0-4] tables.
    - vncipher is recoded to use a combination of InvS-Box, InvShiftRows and
      InvMixColumns tables.  It was not possible to use AES_Td[0-4] due to a
      slight difference in how PowerPC implements vncipher.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:33 +02:00
Tom Musta
59dcd29a6c target-arm: Use Common Tables in AES Instructions
This patch refactors the ARM cryptographic instructions to use the
(newly) added common tables from include/qemu/aes.h.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:33 +02:00
Tom Musta
04af534d55 target-i386: Use Common ShiftRows and InvShiftRows Tables
This patch eliminates the (now) redundant copy of the Advanced Encryption Standard (AES)
ShiftRows and InvShiftRows tables; the code is updated to use the common tables declared in
include/qemu/aes.h.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:33 +02:00
Tom Musta
bfd8f5b754 util: Add InvMixColumns
This patch adds the table implementation of the Advanced Encryption Standard (AES)
InvMixColumns transformation.

The patch is intentionally asymmetrical -- the MixColumns table is not added because
there is no known use for it at this time.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:33 +02:00
Tom Musta
1c1a6d20e0 util: Add AES ShiftRows and InvShiftRows Tables
This patch adds tables that implement the Advanced Encryption Standard (AES) ShiftRows
and InvShiftRows transformations.  These are commonly used in instruction models.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:33 +02:00
Tom Musta
40c84b54dd util: Add S-Box and InvS-Box Arrays to Common AES Utils
This patch adds tables for the S-Box and InvS-Box transformations commonly used by various
Advanced Encription Standard (AES) instruction models.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:33 +02:00
Alexey Kardashevskiy
28668b5f31 spapr_pci: fix MSI limit
At the moment XICS does not support interrupts reuse so sPAPR PHB
implements this. sPAPRPHBState holds array of 32 spapr_pci_msi to
describe PCI config address, first MSI and number of MSIs. Once
allocated for a device, QEMU tries reusing this config until the number
of MSIs changes.

Existing SPAPR guests call ibm,change-msi in a loop until the handler
returns the requested number of vectors.

Recently introduced check for the maximum number of MSI/MSIX vectors
supported by a device only works for a device which is new for PHB's
MSI cache. If it is already there, the check is not performed which
leads to new IRQ block allocation. This happens during PCI hotplug
even when the user hot plug the same device which he just hot unplugged.

This moves the check earlier.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:32 +02:00
Tom Musta
804e654a56 target-ppc: Introduce DFP Shift Significand
Add emulation of the PowerPC Decimal Floating Point Shift Significand
Left Immediate (dscli[q][.]) and DFP Shift Significant Right Immediate
(dscri[q][.]) instructions.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:32 +02:00
Tom Musta
297666eba0 target-ppc: Introduce DFP Insert Biased Exponent
Add emulation of the PowerPC Decimal Floating Point Insert Biased
Exponent instructions diex[q][.].

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:32 +02:00
Tom Musta
e8a4846031 target-ppc: Introduce DFP Extract Biased Exponent
Add emulation of the PowerPC Decimal Floating Point Extract
Biased Exponent instructions dxex[q][.].

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:32 +02:00
Tom Musta
013c3ac070 target-ppc: Introduce DFP Encode BCD to DPD
Add emulation of the PowerPC Decimal Floating Point Encode Binary
Coded Decimal to Densely Packed Decimal instructions denbcd[q][.].

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:32 +02:00
Tom Musta
7796676fdd target-ppc: Introduce DFP Decode DPD to BCD
Add emulation of the Power PC Decimal Floating Point Decode
Densely Packed Decimal to Binary Coded Decimal instructions
ddedpd[q][.].

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:32 +02:00
Tom Musta
bea0dd7912 target-ppc: Introduce DFP Convert to Fixed
Add emulation of the PowerPC Decimal Floating Point Convert to Fixed
instructions dctfix[q][.].

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:32 +02:00
Tom Musta
f121419355 target-ppc: Introduce DFP Convert to Fixed
Add emulation of the PowerPC Decimal Floating Point Convert to
Fixed instructions dctfix[q][.].

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:31 +02:00
Tom Musta
ca603eb4d7 target-ppc: Introduce Round to DFP Short/Long
Add emulation of the PowerPC Round to DFP Short (drsp[.]) and Round to
DFP Long (drdpq[.]) instructions.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:31 +02:00
Tom Musta
290d9ee537 target-ppc: Introduce DFP Convert to Long/Extended
Add emulation of the PowerPC Convert to DFP Long (dctdp[.]) and
Convert to DFP Extended (dctqpq[.]) instructions.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:31 +02:00
Tom Musta
97c0d93041 target-ppc: Introduce DFP Round to Integer
Add emulation of the PowerPC Decimal Floating Point (DFP) Round
to FP Integer With Inexact (drintx[q][.]) and DFP Round to FP
Integer Without Inexact (drintn[q][.]) instructions.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:31 +02:00
Tom Musta
512918aa79 target-ppc: Introduce DFP Reround
Add emulation of the PowerPC Decimal Floating Point Reround instructions
drrnd[q][.].

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:31 +02:00
Tom Musta
5826ebe27a target-ppc: Introduce DFP Quantize
Add emulation of the PowerPC Decimal Floating Point Quantize instructions
dquai[q][.] and dqua[q][.].

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:31 +02:00
Tom Musta
f6022a7684 target-ppc: Introduce DFP Test Significance
Add emulation of the PowerPC Decimal Floating Point Test Significance
instructions dtstsf[q][.].

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:31 +02:00
Tom Musta
f3d2b0bce0 target-ppc: Introduce DFP Test Exponent
Add emulation of the PowerPC Decimal Floating Point Test Exponent
instructions dtstex[q][.].

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:31 +02:00
Tom Musta
1bf9c0e133 target-ppc: Introduce DFP Test Data Group
Add emulation of the PowerPC Decimal Floating Point Test Data
Group instructions dtstdg[q][.].

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:30 +02:00
Tom Musta
e601c1eead target-ppc: Introduce DFP Test Data Class
Add emulation of the PowerPC Decimal Floating Point Test Data Class
instructions dtstdc[q][.].

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:30 +02:00
Tom Musta
5833505be6 target-ppc: Introduce DFP Compares
Add emulation of the PowerPC Decimal Floating Point Compare instructions
dcmpu[q] and dcmpo[q].

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:30 +02:00
Tom Musta
9024ff40ba target-ppc: Introduce DFP Divide
Add emulation of the PowerPC Decimal Floating Point Divide instructions
ddiv[q][.]

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:30 +02:00
Tom Musta
8de6a1cc67 target-ppc: Introduce DFP Multiply
Add emulation of the PowerPC Decimal Floating Point Multiply instructions
dmul[q][.]

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:30 +02:00
Tom Musta
2128f8a57e target-ppc: Introduce DFP Subtract
Add emulation of the PowerPC Decimal Floating Point Subtract instructions
dsub[q][.]

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:30 +02:00
Tom Musta
a9d7ba03b0 target-ppc: Introduce DFP Add
Add emulation of the PowerPC Decimal Floating Point Add instructions dadd[q][.]

Various GCC unused annotations are removed since it is now safe to remove them.

Signed-off-by: Tom Musta <tommusta@gmail.com>
[agraf: move brace in function definition]
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:30 +02:00
Tom Musta
27722744e9 target-ppc: Introduce DFP Post Processor Utilities
Add post-processing utilities to the PowerPC Decimal Floating Point
(DFP) helper code.  Post-processors are small routines that execute
after a preliminary DFP result is computed.  They are used, among other
things, to compute status bits.

This change defines a function type for post processors as well as a
generic routine to run a list (array) of post-processors.

Actual post-processor implementations will be added as needed by specific
DFP helpers in subsequent changes.

Some routines are annotated with the GCC unused attribute in order to
preserve build bisection.  The annotation will be removed in subsequent
patches.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:30 +02:00
Tom Musta
7b0c0d66e5 target-ppc: Introduce DFP Helper Utilities
Add a new file (dfp_helper.c) to the PowerPC implementation for Decimal Floating
Point (DFP) emulation.  This first version of the file declares a structure that
will be used by DFP helpers.  It also implements utilities that will initialize
such a structure for either a long (64 bit) DFP instruction or an extended (128
bit, aka "quad") instruction.

Some utility functions are annotated with the unused attribute in order to preserve
build bisection.

Signed-off-by: Tom Musta <tommusta@gmail.com>
[agraf: Add never reached assert on dfp_prepare_rounding_mode()]
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:29 +02:00
Tom Musta
275e35c6c1 target-ppc: Introduce Decoder Macros for DFP
Add decoder macros for the various Decimal Floating Point
instruction forms.  Illegal instruction masks are used to not only
guard against reserved instruction field use, but also to catch
illegal quad word forms that use odd-numbered floating point registers.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:29 +02:00
Tom Musta
f0b01f02a4 target-ppc: Introduce Generator Macros for DFP Arithmetic Forms
Add general support for generators of PowerPC Decimal Floating Point helpers.

Some utilities are annotated with GCC attribute unused in order to preserve
build bisection.  These annotations will be removed in later patches.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:29 +02:00
Tom Musta
a4f27cc82c target-ppc: Define FPR Pointer Type for Helpers
Define a floating pointer register pointer type in the PowerPC
helper header.  The type will be used to pass FPR register operands
to Decimal Floating Point (DFP) helpers.  A pointer is used because
the quad word forms of PowerPC DFP instructions operate on adjacent
pairs of floating point registers and thus can be thought of as
arrays of length 2.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:29 +02:00
Tom Musta
0a322e7e7c libdecnumber: Fix decNumberSetBCD
Fix a simple bug in the decNumberSetBCD() function.  This function
encodes a decNumber with "n" BCD digits.  The original code erroneously
computed the number of declets from the dn argument, which is the output
decNumber value, and hence may contain garbage.  Instead, the input "n"
value is used.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:29 +02:00
Tom Musta
79af357225 libdecnumber: Introduce decNumberIntegralToInt64
Introduce a new conversion function to the libdecnumber library.
This function converts a decNumber to a signed 64-bit integer.
In order to support 64-bit integers (which may have up to 19
decimal digits), the existing "powers of 10" array is expanded
from 10 to 19 entries.

Signed-off-by: Tom Musta <tommusta@gmail.com>
[agraf: fix 32bit host compile]
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:29 +02:00
Tom Musta
8e706db21e libdecnumber: Introduce decNumberFrom[U]Int64
Introduce two conversion functions to the libdecnumber library.
These conversions transform 64 bit integers to the internal decNumber
representation.  Both a signed and unsigned version is added.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:29 +02:00
Tom Musta
e58f8d1ff9 target-ppc: Enable Building of libdecnumber
Enable compilation of the newly added libdecnumber library code.
Object file targets are added to Makefile.target using a newly
introduced flag CONFIG_LIBDECNUMBER.  The flag is added
to the PowerPC targets (ppc[64]-linux-user, ppc[64]-softmmu).

Signed-off-by: Tom Musta <tommusta@gmail.com>
[agraf: add ppcemb and ppc64abi32 config]
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:29 +02:00
Tom Musta
4922fd7d52 libdecnumber: Eliminate Unused Variable in decSetSubnormal
Eliminate an unused variable in the decSetSubnormal routine.  The
variable dnexp is declared and eventually set but never used, and
thus may trigger an unused-but-set-variable warning.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:28 +02:00
Tom Musta
426d9a1a59 libdecnumber: Eliminate redundant declarations
Eliminate redundant declarations of symbols DPD2BIN and BIN2DPD in
various .c source files.  These symbols are already declared in decDPD.h and
thus will trigger 'redundant redeclaration of ?XXX?' warnings, which, of
course, may fail QEMU compilation.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:28 +02:00
Tom Musta
9b7a14b064 libdecnumber: Change gstdint.h to stdint.h
Replace the inclusion of gstdint.h with the standard stdint.h
header file.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:28 +02:00
Tom Musta
7275585b8c libdecnumber: Modify dconfig.h to Integrate with QEMU
Modify the dconfig.h header file so that libdecnumber code integrates QEMU
configuration.   Specifically:

  - the WORDS_BIGENDIAN preprocessor macro is used in libdecnumber code to
    determines endianness.  It is derived from the existing QEMU macro
    HOST_WORDS_BIGENDIAN which is defined in config-host.h.

  - the DECPUN macro determines the number of decimal digits (aka declets) per
    unit (byte).  This is 3 for PowerPC DFP.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:28 +02:00
Tom Musta
0f2d373220 libdecnumber: Prepare libdecnumber for QEMU include structure
Consistent with other libraries in QEMU, the libdecnumber header files were
placed in include/libdecnumber, separate from the C code.  This is different
from the original libdecnumber source, where they were co-located.

Change the libdecnumber source code so that it reflects this split.  Specifically,
modify directives of the form:

    #include "xxx.h"

to look like:

    #include "libdecnumber/xxx.h"

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:28 +02:00
Tom Musta
f5d7f14646 libdecnumber: Eliminate #include *Symbols.h
The various *Symbols.h files were not copied from the original GCC libdecnumber
library; they are not necessary for use in QEMU.  Remove all instances of

    #include "*Symbols.h"

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:28 +02:00
Tom Musta
72ac97cdfc libdecnumber: Introduce libdecnumber Code
Add files from the libdecnumber decimal floating point library to QEMU.  The libdecnumber
library was originally part of GCC and contains code that is useful in emulating the PowerPC
decimal floating point (DFP) instructions.  This particular copy of the source comes from
GCC 4.3 and is licensed at GPLv2+.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:28 +02:00
BALATON Zoltan
9d1c128341 mac99: Added FW_CFG_PPC_BUSFREQ to match CLOCKFREQ and TBFREQ already there
While there, also moved the hard coded value for CLOCKFREQ to a #define.

Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:28 +02:00
Alexey Kardashevskiy
569be9f055 target-ppc: Remove PVR check from migration
Currently migration fails if CPU version (PVR register) is different
even a bit. This check is performed at the very end of migration when
device states are sent. This is too late for management software and
we need to provide a way for the user to make sure that migration
will succeed if QEMU is started with appropritate command line parameters.

This removes the PVR check.

This resets PVR to the default value as the existing VMSTATE record
for SPR array sends all 1024 registers unconditionally and overwrites
the destination PVR.

If the user wants some guarantees for migration to succeed, then
a CPU name or "host" CPU with a "compat" option (on its way to upsteam)
should be used and KVM or TCG is expected to fail on unsupported values
at the moment of QEMU start.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:27 +02:00
Tom Musta
9df5a46632 target-ppc: Eliminate Magic Number MSR Masks
Use MSR mnemonics from cpu.h instead of magic numbers for the CPUPPCState.msr_mask
initialization.

There is one bit in the 401x2 (and subsequent) model that I could not find any
documentation for.  It is open coded at little endian bit position 20:

    pcc->msr_mask = (1ull << 20) |
                    (1ull << MSR_KEY) |
                    (1ull << MSR_POW) |
                    (1ull << MSR_CE) |
                    ...

Signed-off-by: Tom Musta <tommusta@gmail.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:27 +02:00
Alexey Kardashevskiy
b26696b519 spapr_pci: Fix number of returned vectors in ibm, change-msi
Current guest kernels try allocating as many vectors as the quota is.
For example, in the case of virtio-net (which has just 3 vectors)
the guest requests 4 vectors (that is the quota in the test) and
the existing ibm,change-msi handler returns 4. But before it returns,
it calls msix_set_message() in a loop and corrupts memory behind
the end of msix_table.

This limits the number of vectors returned by ibm,change-msi to
the maximum supported by the actual device.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Cc: qemu-stable@nongnu.org
[agraf: squash in bugfix from aik]
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:27 +02:00
Greg Kurz
fabe9ee113 spapr-pci: remove io ports workaround
In the past, IO space could not be mapped into the memory address space
so we introduced a workaround for that. Nowadays it does not look
necessary so we can remove the workaround and make sPAPR PCI
configuration simplier.

Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
Acked-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:27 +02:00
Alexey Kardashevskiy
70d246c335 target-ppc: Remove redundant POWER7 declarations
At the moment there are 3 versions of POWER7 CPUs defined. However
we do not emulate these CPUs diffent and it does not make much
sense to keep them all.

This removes POWER7_v2.0 and POWER7_v2.1 and leaves just one versioned
CPU per family which is POWER7_v2.3 with POWER7 alias.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:27 +02:00
Alexey Kardashevskiy
fdf8a960e2 target-ppc: Move alias lookup after class lookup
This moves aliases lookup after CPU class lookup. This is to let new generic
CPU to be found first if it is present and only if it is not (TCG case), use
aliases.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:27 +02:00
Alexey Kardashevskiy
5b79b1cadd target-ppc: Create versionless CPU class per family if KVM
At the moment generic version-less CPUs are supported via hardcoded aliases.
For example, POWER7 is an alias for POWER7_v2.1. So when QEMU is started
with -cpu POWER7, the POWER7_v2.1 class instance is created.

This approach works for TCG and KVMs other than HV KVM. HV KVM cannot emulate
PVR value so the guest always sees the real PVR. HV KVM will not allow setting
PVR other that the host PVR because of that (the kernel patch for it is on
its way). So in most cases it is impossible to run QEMU with -cpu POWER7
unless the host PVR is exactly the same as the one from the alias (which
is now POWER7_v2.3). It was decided that under HV KVM QEMU should use
-cpu host.

Using "host" CPU type creates a problem for management tools such as libvirt
because they want to know in advance if the destination guest can possibly
run on the destination. Since the "host" type is really not a type and will
always work with any KVM, there is no way for libvirt to know if the migration
will success.

This registers additional CPU class derived from the host CPU family.
The name for it is taken from @desc field of the CPU family class.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:27 +02:00
Thomas Falcon
8a286ce450 target-ppc: gdbstub allow byte swapping for reading/writing registers
This patch allows registers to be properly read from and written to
when using the gdbstub to debug a ppc guest running in little
endian mode.

Reviewed-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:27 +02:00
Thomas Falcon
c46e983106 target-ppc: extract register length calculation in gdbstub
This patch extracts the method to determine a register's size
into a separate function.

Reviewed-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:26 +02:00
Alexey Kardashevskiy
4e2ca12785 spapr_nvram: Correct max nvram size
Currently it is UINT16_MAX*16 = 65536*16 = 1048560 which is not
a round number and therefore a bit confusing.

This defines MAX_NVRAM_SIZE precisely as 1MB.

Suggested-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:26 +02:00
Fabien Chouteau
d584348589 Fix typo in eTSEC Ethernet controller
IRQ are lowered when ievent bit is cleared, so irq_pulse makes no sense
here...

Signed-off-by: Fabien Chouteau <chouteau@adacore.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:26 +02:00
Tom Musta
1c38f84373 monitor: QEMU Monitor Instruction Disassembly Incorrect for PowerPC LE Mode
The monitor support for disassembling instructions does not honor the MSR[LE]
bit for PowerPC processors.

This change enhances the monitor_disas() routine by supporting a flag bit
for Little Endian mode.  Bit 16 is used since that bit was used in the
analagous guest disassembly routine target_disas().

Also, to be consistent with target_disas(), the disassembler bfd_mach field
can be passed in the flags argument.

Reported-by: Anton Blanchard <anton@samba.org>
Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:26 +02:00
Tom Musta
e13951f896 target-ppc: Fix target_disas
Inspect only bit 16 for the Little Endian test.  Correct comment preceding
the target_disas() function.  Correct grammar in comment for flags processing.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Alexander Graf <agraf@suse.de>
2014-06-16 13:24:26 +02:00
Peter Maydell
0bbac62618 Merge remote-tracking branch 'remotes/juanquintela/tags/migration/20140616' into staging
migration/next for 20140616

# gpg: Signature made Mon 16 Jun 2014 04:10:18 BST using RSA key ID 5872D723
# gpg: Can't check signature: public key not found

* remotes/juanquintela/tags/migration/20140616:
  migration: catch unknown flags in ram_load
  rdma: Fix block during rdma migration
  migration: Increase default max_downtime from 30ms to 300ms
  vmstate: Refactor opening of files
  savevm: Remove all the unneeded version_minimum_id_old (x86)
  savevm: Remove all the unneeded version_minimum_id_old (ppc)

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-16 11:06:06 +01:00
Chunyan Liu
98d896d978 QemuOpts: cleanup tmp 'allocated' member from QemuOptsList
Now only qemu_opts_append uses 'allocated' to indicate free memory.
For this function only, we can also let result list's (const char *)
members point to input list's members, only if the input list has
longer lifetime than result list. In current code, that is true.
So, we can remove the 'allocated' member from QemuOptsList definition
to keep code clean.

Signed-off-by: Chunyan Liu <cyliu@suse.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-16 17:23:21 +08:00
Chunyan Liu
c282e1fdf7 cleanup QEMUOptionParameter
Now that all backend drivers are using QemuOpts, remove all
QEMUOptionParameter related codes.

Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
Signed-off-by: Chunyan Liu <cyliu@suse.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-16 17:23:21 +08:00
Chunyan Liu
fec9921f0a vpc.c: replace QEMUOptionParameter with QemuOpts
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
Signed-off-by: Chunyan Liu <cyliu@suse.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-16 17:23:21 +08:00
Chunyan Liu
5820f1da51 vmdk.c: replace QEMUOptionParameter with QemuOpts
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
Signed-off-by: Chunyan Liu <cyliu@suse.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-16 17:23:21 +08:00
Chunyan Liu
5366092c7a vhdx.c: replace QEMUOptionParameter with QemuOpts
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
Signed-off-by: Chunyan Liu <cyliu@suse.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-16 17:23:21 +08:00
Chunyan Liu
004b7f2522 vdi.c: replace QEMUOptionParameter with QemuOpts
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
Signed-off-by: Chunyan Liu <cyliu@suse.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-16 17:23:21 +08:00
Chunyan Liu
766181fe57 ssh.c: replace QEMUOptionParameter with QemuOpts
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
Signed-off-by: Chunyan Liu <cyliu@suse.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-16 17:23:21 +08:00
Chunyan Liu
b222237b7b sheepdog.c: replace QEMUOptionParameter with QemuOpts
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
Signed-off-by: Chunyan Liu <cyliu@suse.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-16 17:23:21 +08:00
Chunyan Liu
bd0cf596fd rbd.c: replace QEMUOptionParameter with QemuOpts
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
Signed-off-by: Chunyan Liu <cyliu@suse.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-16 17:23:21 +08:00
Chunyan Liu
cd3a4cf631 raw_bsd.c: replace QEMUOptionParameter with QemuOpts
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
Signed-off-by: Chunyan Liu <cyliu@suse.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-16 17:23:21 +08:00
Chunyan Liu
ddef769993 raw-win32.c: replace QEMUOptionParameter with QemuOpts
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
Signed-off-by: Chunyan Liu <cyliu@suse.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-16 17:23:21 +08:00
Chunyan Liu
6f482f742d raw-posix.c: replace QEMUOptionParameter with QemuOpts
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
Signed-off-by: Chunyan Liu <cyliu@suse.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-16 17:23:21 +08:00
Chunyan Liu
7ab74849a5 qed.c: replace QEMUOptionParameter with QemuOpts
One extra change is to define QED_DEFAULT_CLUSTER_SIZE = 65536 instead
of 64 * 1024; because:
according to existing create_options, "cluster size" has default value =
QED_DEFAULT_CLUSTER_SIZE, after switching to create_opts, this has to be
stringized and set to .def_value_str. That is,
  .def_value_str = stringify(QED_DEFAULT_CLUSTER_SIZE),
so the QED_DEFAULT_CLUSTER_SIZE could not be a expression.

Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
Signed-off-by: Chunyan Liu <cyliu@suse.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-16 17:23:21 +08:00
Chunyan Liu
1bd0e2d1c4 qcow2.c: replace QEMUOptionParameter with QemuOpts
Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
Signed-off-by: Chunyan Liu <cyliu@suse.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-16 17:23:21 +08:00
Chunyan Liu
74c3c19765 QemuOpts: export qemu_opt_find
Export qemu_opt_find for qcow2 driver using it.
After replacing QEMUOptionParameter with QemuOpts, qcow2 driver will
use qemu_opt_find to judge if an option is explicitly set, to replace
the usage of .assigned in QEMUOptionParameter.

Signed-off-by: Chunyan Liu <cyliu@suse.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-16 17:23:21 +08:00
Chunyan Liu
16d12159e2 qcow.c: replace QEMUOptionParameter with QemuOpts
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
Signed-off-by: Chunyan Liu <cyliu@suse.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-16 17:23:20 +08:00
Chunyan Liu
98c10b810a nfs.c: replace QEMUOptionParameter with QemuOpts
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Chunyan Liu <cyliu@suse.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-16 17:23:20 +08:00
Chunyan Liu
a59479e3f3 iscsi.c: replace QEMUOptionParameter with QemuOpts
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
Signed-off-by: Chunyan Liu <cyliu@suse.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-16 17:23:20 +08:00
Chunyan Liu
90c772de56 gluster.c: replace QEMUOptionParameter with QemuOpts
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
Signed-off-by: Chunyan Liu <cyliu@suse.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-16 17:23:20 +08:00
Chunyan Liu
25814e8987 cow.c: replace QEMUOptionParameter with QemuOpts
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
Signed-off-by: Chunyan Liu <cyliu@suse.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-16 17:23:20 +08:00
Chunyan Liu
facdbb0272 vvfat.c: handle cross_driver's create_options and create_opts
vvfat shares create options of qcow driver. To avoid vvfat breaking when
qcow driver changes from QEMUOptionParameter to QemuOpts, let it able
to handle both cases.

Signed-off-by: Chunyan Liu <cyliu@suse.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-16 17:23:20 +08:00
Chunyan Liu
83d0521a1e change block layer to support both QemuOpts and QEMUOptionParamter
Change block layer to support both QemuOpts and QEMUOptionParameter.
After this patch, it will change backend drivers one by one. At the end,
QEMUOptionParameter will be removed and only QemuOpts is kept.

Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
Signed-off-by: Chunyan Liu <cyliu@suse.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-16 17:23:20 +08:00
Chunyan Liu
4782183da3 QemuOpts: check NULL input for qemu_opts_del
To simplify later using of qemu_opts_del, accept NULL input.

Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Leandro Dorileo <l@dorileo.org>
Signed-off-by: Chunyan Liu <cyliu@suse.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-16 17:23:20 +08:00
Chunyan Liu
a1097a2614 QemuOpts: add qemu_opts_append to replace append_option_parameters
For later merge .create_opts of drv and proto_drv in qemu-img commands.

Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Leandro Dorileo <l@dorileo.org>
Signed-off-by: Chunyan Liu <cyliu@suse.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-16 17:23:20 +08:00
Chunyan Liu
8559e45e51 QemuOpts: add conversion between QEMUOptionParameter to QemuOpts
Add two temp conversion functions between QEMUOptionParameter to QemuOpts,
so that next patch can use it. It will simplify later patch for easier
review. And will be finally removed after all backend drivers switch to
QemuOpts.

Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Leandro Dorileo <l@dorileo.org>
Signed-off-by: Chunyan Liu <cyliu@suse.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-16 17:23:20 +08:00
Chunyan Liu
504189a96f QemuOpts: add qemu_opts_print_help to replace print_option_help
print_option_help takes QEMUOptionParameter as parameter, add
qemu_opts_print_help to take QemuOptsList as parameter for later
replace work.

Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Leandro Dorileo <l@dorileo.org>
Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
Signed-off-by: Chunyan Liu <cyliu@suse.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-16 17:23:20 +08:00
Chunyan Liu
782730b0bc QemuOpts: add qemu_opt_get_*_del functions for replace work
Add qemu_opt_get_del, qemu_opt_get_bool_del, qemu_opt_get_number_del and
qemu_opt_get_size_del to replace the same handling of QEMUOptionParameter
(get and delete).

Several drivers are coded to parse a known subset of options, then
remove them from the list before handing all remaining options to a
second driver for further option processing.  get_*_del makes it easier
to retrieve a known option (or its default) and remove it from the list
all in one action.

Share common helper function:

For qemu_opt_get_bool/size/number, they and their get_*_del counterpart
could share most of the code except whether or not deleting the opt from
option list, so generate common helper functions.

For qemu_opt_get and qemu_opt_get_del, keep code duplication, since
1. qemu_opt_get_del returns malloc'd memory while qemu_opt_get returns
in-place memory
2. qemu_opt_get_del returns (char *), qemu_opt_get returns (const char *),
and could not change to (char *), since in one case, it will return
desc->def_value_str, which is (const char *).

Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
Signed-off-by: Chunyan Liu <cyliu@suse.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-16 17:23:20 +08:00
Chunyan Liu
fc345512c5 QemuOpts: move qemu_opt_del ahead for later calling
In later patch, qemu_opt_get_del functions will be added, they will
first get the option value, then call qemu_opt_del to remove the option
from opt list. To prepare for that purpose, move qemu_opt_del ahead first.

Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Leandro Dorileo <l@dorileo.org>
Signed-off-by: Chunyan Liu <cyliu@suse.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-16 17:23:20 +08:00
Chunyan Liu
dc8622f2bf QemuOpts: change opt->name|str from (const char *) to (char *)
qemu_opt_del() already assumes that all QemuOpt instances contain
malloc'd name and value; but it had to cast away const because
opts_start_struct() was doing its own thing and using static storage
instead.  By using the correct type and malloced strings everywhere, the
usage of this struct becomes clearer.

Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Leandro Dorileo <l@dorileo.org>
Signed-off-by: Chunyan Liu <cyliu@suse.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-16 17:23:20 +08:00
Chunyan Liu
e36af94f86 qapi: output def_value_str when query command line options
Change qapi interfaces to output the newly added def_value_str when querying
command line options.

Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Leandro Dorileo <l@dorileo.org>
Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
Signed-off-by: Chunyan Liu <cyliu@suse.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-16 17:23:20 +08:00
Chunyan Liu
09722032e1 QemuOpts: add def_value_str to QemuOptDesc
Add def_value_str (default value) to QemuOptDesc, to replace function of the
default value in QEMUOptionParameter.

Improve qemu_opts_get_* functions: if find opt, return opt->str; otherwise,
if desc->def_value_str is set, return desc->def_value_str; otherwise, return
input defval.

Improve qemu_opts_print: if option is set, print opt->str; otherwise, if
desc->def_value_str is set, print it.

Signed-off-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
Signed-off-by: Chunyan Liu <cyliu@suse.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-16 17:23:20 +08:00
Chunyan Liu
e67905426b QemuOpts: repurpose qemu_opts_print to replace print_option_parameters
Currently this function is not used anywhere. In later patches, it will
replace print_option_parameters. To avoid print info changes, change
qemu_opts_print from fprintf stderr to printf, and remove last printf.

Signed-off-by: Chunyan Liu <cyliu@suse.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-16 17:23:19 +08:00
Chunyan Liu
5e89db7641 QemuOpts: move find_desc_by_name ahead for later calling
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Chunyan Liu <cyliu@suse.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-16 17:23:19 +08:00
Peter Lieven
a2c0fe2fd2 block/nfs: fix potential segfault on early callback
it will happen in the future that the callback of a libnfs call
directly invokes the callback. In this case we end up in a segfault
because the NFSRPC is gone when we the BH is scheduled.

Signed-off-by: Peter Lieven <pl@kamp.de>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-16 17:23:19 +08:00
Markus Armbruster
ae60e8e378 blockdev: Remove unused DriveInfo reference count
It's always one since commit fa510eb dropped the last drive_get_ref().

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-16 17:23:19 +08:00
Markus Armbruster
60e19e06a4 blockdev: Rename drive_init(), drive_uninit() to drive_new(), drive_del()
"Init" and "uninit" suggest the functions don't allocate / free
storage.  But they do.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-16 17:23:19 +08:00
Kevin Wolf
bcf8315857 blockdev: Move 'serial' option to drive_init()
It is not available with blockdev-add.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-16 17:23:19 +08:00
Markus Armbruster
f7047c2daf block: Drop superfluous conditionals around g_free()
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-16 17:23:19 +08:00
Stefan Weil
b25c9dff35 configure: Enable dead code (lzo, snappy, quorum)
Those options were not enabled by default, even when the build
environment would have supported them, so the corresponding
code was not compiled in normal test builds like on build bots.

[Building quorum by default "broke" qemu-iotests ./check 081.  It turns
out the 081.out master output was just bitrotted.  Fix this by updating
the error message.
--Stefan]

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Reviewed-by: Qiao Nuohan <qiaonuohan@cn.fujitsu.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-16 17:23:19 +08:00
Peter Lieven
db80facefa migration: catch unknown flags in ram_load
if a saved vm has unknown flags in the memory data qemu
currently simply ignores this flag and continues which
yields in an unpredictable result.

This patch catches all unknown flags and aborts the
loading of the vm. Additionally error reports are thrown
if the migration aborts abnormally.

Signed-off-by: Peter Lieven <pl@kamp.de>
Signed-off-by: Juan Quintela <quintela@redhat.com>
2014-06-16 04:55:27 +02:00
Gonglei
2a93434704 rdma: Fix block during rdma migration
If the networking break or there's something wrong with rdma
device(ib0 with no IP) during rdma migration, the main_loop of
qemu will be blocked in rdma_destroy_id. I add rdma_ack_cm_event
to fix this bug.

Signed-off-by: Mo Yuxiang <Moyuxiang@huawei.com>
Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Michael R. Hines <mrhines@us.ibm.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
2014-06-16 04:55:27 +02:00
Alexey Kardashevskiy
f7cd55a023 migration: Increase default max_downtime from 30ms to 300ms
The existing timeout is 30ms which on 100MB/s (1Gbit) gives us
3MB/s rate maximum. If we put some load on the guest, it is easy to
get page dirtying rate too big so live migration will never complete.
In the case of libvirt that means that the guest will be stopped
anyway after a timeout specified in the "virsh migrate" command and
this normally generates even bigger delay.

This changes max_downtime to 300ms which seems to be more
reasonable value.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Juan Quintela <quintela@redhat.com>
2014-06-16 04:55:27 +02:00
Juan Quintela
c6f6646c60 vmstate: Refactor opening of files
Signed-off-by: Juan Quintela <quintela@redhat.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: Amit Shah <amit.shah@redhat.com>
2014-06-16 04:55:27 +02:00
Juan Quintela
d49805aeea savevm: Remove all the unneeded version_minimum_id_old (x86)
After previous Peter patch, they are redundant.  This way we don't
assign them except when needed.  Once there, there were lots of case
where the ".fields" indentation was wrong:

     .fields = (VMStateField []) {
and
     .fields =      (VMStateField []) {

Change all the combinations to:

     .fields = (VMStateField[]){

The biggest problem (appart from aesthetics) was that checkpatch complained
when we copy&pasted the code from one place to another.

Signed-off-by: Juan Quintela <quintela@redhat.com>
Acked-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
2014-06-16 04:55:26 +02:00
Juan Quintela
3aff6c2fea savevm: Remove all the unneeded version_minimum_id_old (ppc)
After previous Peter patch, they are redundant.  This way we don't
assign them except when needed.  Once there, there were lots of case
where the ".fields" indentation was wrong:

     .fields = (VMStateField []) {
and
     .fields =      (VMStateField []) {

Change all the combinations to:

     .fields = (VMStateField[]){

The biggest problem (appart from aesthetics) was that checkpatch complained
when we copy&pasted the code from one place to another.

Signed-off-by: Juan Quintela <quintela@redhat.com>
Acked-by: Alexey Kardashevskiy <aik@ozlabs.ru>
2014-06-16 04:55:26 +02:00
Peter Maydell
06a59afac4 Merge remote-tracking branch 'remotes/kraxel/tags/pull-usb-20140613-1' into staging
usb-host: add range checks for usb-host parameters

# gpg: Signature made Fri 13 Jun 2014 12:33:05 BST using RSA key ID D3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>"
# gpg:                 aka "Gerd Hoffmann <gerd@kraxel.org>"
# gpg:                 aka "Gerd Hoffmann (private) <kraxel@gmail.com>"

* remotes/kraxel/tags/pull-usb-20140613-1:
  usb-host: add range checks for usb-host parameters

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-13 18:18:55 +01:00
Peter Maydell
80008a6a29 Merge remote-tracking branch 'remotes/kraxel/tags/pull-trivial-20140613-1' into staging
inet_listen_opts: add error checking

# gpg: Signature made Fri 13 Jun 2014 12:29:43 BST using RSA key ID D3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>"
# gpg:                 aka "Gerd Hoffmann <gerd@kraxel.org>"
# gpg:                 aka "Gerd Hoffmann (private) <kraxel@gmail.com>"

* remotes/kraxel/tags/pull-trivial-20140613-1:
  inet_listen_opts: add error checking

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-13 16:07:04 +01:00
Peter Maydell
592fb17691 Merge remote-tracking branch 'remotes/spice/tags/pull-spice-20140613-1' into staging
spice: add mouse cursor support
qxl-render: add sanity check

# gpg: Signature made Fri 13 Jun 2014 12:22:45 BST using RSA key ID D3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>"
# gpg:                 aka "Gerd Hoffmann <gerd@kraxel.org>"
# gpg:                 aka "Gerd Hoffmann (private) <kraxel@gmail.com>"

* remotes/spice/tags/pull-spice-20140613-1:
  qxl-render: add sanity check
  spice: add mouse cursor support

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-13 15:15:31 +01:00
Peter Maydell
7d5bef0873 Merge remote-tracking branch 'remotes/kraxel/tags/pull-chardev-20140613-1' into staging
char: fix avail_connections init in qemu_chr_open_eventfd()

# gpg: Signature made Fri 13 Jun 2014 12:16:50 BST using RSA key ID D3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>"
# gpg:                 aka "Gerd Hoffmann <gerd@kraxel.org>"
# gpg:                 aka "Gerd Hoffmann (private) <kraxel@gmail.com>"

* remotes/kraxel/tags/pull-chardev-20140613-1:
  char: fix avail_connections init in qemu_chr_open_eventfd()

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-13 14:57:56 +01:00
Peter Maydell
d61de7255b Merge remote-tracking branch 'remotes/kraxel/tags/pull-audio-20140613-1' into staging
audio: Drop superfluous conditionals around g_free()

# gpg: Signature made Fri 13 Jun 2014 12:14:24 BST using RSA key ID D3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>"
# gpg:                 aka "Gerd Hoffmann <gerd@kraxel.org>"
# gpg:                 aka "Gerd Hoffmann (private) <kraxel@gmail.com>"

* remotes/kraxel/tags/pull-audio-20140613-1:
  audio: Drop superfluous conditionals around g_free()

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-13 12:58:24 +01:00
Gerd Hoffmann
f3cda6e060 usb-host: add range checks for usb-host parameters
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-06-13 12:34:57 +02:00
Gerd Hoffmann
8bc8912796 inet_listen_opts: add error checking
Don't use atoi() function which doesn't detect errors, switch to
strtol and error out on failures.  Also add a range check while
being at it.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
2014-06-13 12:34:57 +02:00
Gerd Hoffmann
788fbf042f qxl-render: add sanity check
Verify dirty rectangle is completely within the primary surface,
just ignore it in case it isn't.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-06-13 12:34:57 +02:00
Gerd Hoffmann
5643fc012c spice: add mouse cursor support
So you'll have a mouse pointer when running non-qxl gfx cards with
mouse pointer support (virtio-gpu, IIRC vmware too).

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-06-13 12:34:57 +02:00
David Marchand
e9d21c436f char: fix avail_connections init in qemu_chr_open_eventfd()
When trying to use a ivshmem server with qemu, ivshmem init code tries to
create a CharDriverState object for each eventfd retrieved from the server.
To create this object, a call to qemu_chr_open_eventfd() is done.
Right after this, before adding a frontend, qemu_chr_fe_claim_no_fail() is
called.
qemu_chr_open_eventfd() does not set avail_connections to 1, so no frontend can
be associated because qemu_chr_fe_claim_no_fail() makes qemu stop right away.

This problem comes from 456d606923
"qemu-char: Call fe_claim / fe_release when not using qdev chr properties".

Fix this, by setting avail_connections to 1 in qemu_chr_open_eventfd().

Signed-off-by: David Marchand <david.marchand@6wind.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-06-13 12:34:55 +02:00
Markus Armbruster
fb7da626c0 audio: Drop superfluous conditionals around g_free()
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-06-13 12:34:54 +02:00
Peter Maydell
2a2c4830c0 Merge remote-tracking branch 'remotes/kraxel/tags/pull-gtk-20140611-1' into staging
gtk: misc fixes & cleanups.

# gpg: Signature made Wed 11 Jun 2014 13:28:12 BST using RSA key ID D3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>"
# gpg:                 aka "Gerd Hoffmann <gerd@kraxel.org>"
# gpg:                 aka "Gerd Hoffmann (private) <kraxel@gmail.com>"

* remotes/kraxel/tags/pull-gtk-20140611-1:
  gtk: update window size after showing/hiding tabs
  gtk: factor out gtk3 grab into the new gd_grab_devices function
  gtk: cleanup backend dependencies
  gtk: factor out keycode mapping

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-12 09:51:41 +01:00
Peter Maydell
05fedeef83 Merge remote-tracking branch 'remotes/qmp-unstable/queue/qmp' into staging
* remotes/qmp-unstable/queue/qmp:
  json-parser: drop superfluous assignment for token variable
  readline: Clear screen on form feed.
  monitor: Add delvm and loadvm argument completion
  monitor: Add host_net_remove arguments completion
  readline: Make completion strings always unique
  monitor: Add host_net_add device argument completion
  net: Export valid host network devices list
  monitor: Add migrate_set_capability completion
  monitor: Add watchdog_action argument completion
  monitor: Add ringbuf_write and ringbuf_read argument completion
  dump: simplify get_len_buf_out()
  dump: hoist lzo_init() from get_len_buf_out() to dump_init()
  dump: select header bitness based on ELF class, not ELF architecture
  dump: eliminate DumpState.page_size ("guest's page size")
  dump: eliminate DumpState.page_shift ("guest's page shift")
  dump: simplify write_start_flat_header()
  dump: fill in the flat header signature more pleasingly to the eye

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-11 21:34:08 +01:00
Peter Maydell
706808585a Merge remote-tracking branch 'remotes/pmaydell/tags/pull-bsd-user-20140611' into staging
bsd-user queue:
 * build fixes
 * improvements to strace

# gpg: Signature made Wed 11 Jun 2014 15:23:40 BST using RSA key ID 14360CDE
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>"

* remotes/pmaydell/tags/pull-bsd-user-20140611:
  bsd-user: Fix syscall format, add strace support for more syscalls
  bsd-user: Implement strace support for thr_* syscalls
  bsd-user: Implement strace support for extattr_* syscalls
  bsd-user: Implement strace support for __acl_* syscalls
  bsd-user: Implement strace support for print_ioctl syscall
  bsd-user: Implement strace support for print_sysctl syscall
  bsd-user: GPL v2 attribution update and style
  bsd-user: add HOST_VARIANT_DIR for various *BSD dependent code
  exec: replace ffsl with ctzl
  vhost: replace ffsl with ctzl
  xen: replace ffsl with ctzl
  util/qemu-openpty: fix build with musl libc by include termios.h as fallback
  bsd-user/mmap.c: Don't try to override g_malloc/g_free
  util/hbitmap.c: Use ctpopl rather than reimplementing a local equivalent
  bsd-user: refresh freebsd system call numbers

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-11 18:05:21 +01:00
Peter Maydell
c5cb1afc46 Merge remote-tracking branch 'remotes/bonzini/configure' into staging
* remotes/bonzini/configure:
  rules.mak: Rewrite unnest-vars
  configure: unset interfering variables
  configure: duplicate/incorrect order of -lrt
  libcacard: improve documentation
  libcacard: actually use symbols file
  libcacard: replace qemu thread primitives with glib ones
  vscclient: use glib thread primitives not qemu
  glib-compat.h: add new thread API emulation on top of pre-2.31 API

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-11 15:36:48 +01:00
Gonglei
a491af471b json-parser: drop superfluous assignment for token variable
Signed-off-by: ChenLiang <chenliang88@huawei.com>
Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-06-11 10:10:29 -04:00
Hani Benhabiles
075ccb6cd3 readline: Clear screen on form feed.
Signed-off-by: Hani Benhabiles <hani@linux.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-06-11 10:10:29 -04:00
Hani Benhabiles
b21631f3b5 monitor: Add delvm and loadvm argument completion
Signed-off-by: Hani Benhabiles <hani@linux.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-06-11 10:10:29 -04:00
Hani Benhabiles
ddd6b45ce2 monitor: Add host_net_remove arguments completion
Relies on readline unique completion strings patch to make the added vlan/hub
completion values unique, instead of using something like a hash table.

Signed-off-by: Hani Benhabiles <hani@linux.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-06-11 10:10:29 -04:00
Hani Benhabiles
e70871d8b5 readline: Make completion strings always unique
There is no need to clutter the user's choices with repeating the same value
multiple times.

Signed-off-by: Hani Benhabiles <hani@linux.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-06-11 10:10:29 -04:00
Hani Benhabiles
e3bb532cc7 monitor: Add host_net_add device argument completion
Also fix the parameters documentation.

Signed-off-by: Hani Benhabiles <hani@linux.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-06-11 10:10:29 -04:00
Hani Benhabiles
84007e8181 net: Export valid host network devices list
Signed-off-by: Hani Benhabiles <hani@linux.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-06-11 10:10:29 -04:00
Hani Benhabiles
c68a0409b3 monitor: Add migrate_set_capability completion
Signed-off-by: Hani Benhabiles <hani@linux.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-06-11 10:10:29 -04:00
Hani Benhabiles
d0ece345cb monitor: Add watchdog_action argument completion
Signed-off-by: Hani Benhabiles <hani@linux.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-06-11 10:10:28 -04:00
Hani Benhabiles
8e5977797d monitor: Add ringbuf_write and ringbuf_read argument completion
Export chr_is_ringbuf() function. Also remove left-over function prototypes
while at it.

Signed-off-by: Hani Benhabiles <hani@linux.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-06-11 10:10:28 -04:00
Laszlo Ersek
b87ef3518b dump: simplify get_len_buf_out()
We can (and should) rely on the fact that s->flag_compress is exactly one
of DUMP_DH_COMPRESSED_ZLIB, DUMP_DH_COMPRESSED_LZO, and
DUMP_DH_COMPRESSED_SNAPPY.

This is ensured by the QMP schema and dump_init() in combination.

Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-06-11 10:10:28 -04:00
Laszlo Ersek
c998acb03d dump: hoist lzo_init() from get_len_buf_out() to dump_init()
qmp_dump_guest_memory()
  dump_init()
    lzo_init() <---------+
  create_kdump_vmcore()  |
    write_dump_pages()   |
      get_len_buf_out()  |
        lzo_init() ------+

This patch doesn't change the fact that lzo_init() is called for every
LZO-compressed dump, but it makes get_len_buf_out() more focused (single
responsibility).

Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-06-11 10:10:28 -04:00
Laszlo Ersek
24aeeace7a dump: select header bitness based on ELF class, not ELF architecture
The specific ELF architecture (d_machine) carries Too Much Information
(TM) for deciding between create_header32() and create_header64(), use
"d_class" instead (ELFCLASS32 vs. ELFCLASS64).

This change adapts write_dump_header() to write_elf_loads(), dump_begin()
etc. that also rely on the ELF class of the target for bitness selection.

Considering the current targets that support dumping, cpu_get_dump_info()
works as follows:
- target-s390x/arch_dump.c: (EM_S390, ELFCLASS64) only
- target-ppc/arch_dump.c (EM_PPC64, ELFCLASS64) only
- target-i386/arch_dump.c: sets (EM_X86_64, ELFCLASS64) vs. (EM_386,
  ELFCLASS32) keying off the same Long Mode Active flag.

Hence no observable change.

Approximately-suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-06-11 10:10:28 -04:00
Laszlo Ersek
2f859f80c2 dump: eliminate DumpState.page_size ("guest's page size")
Use TARGET_PAGE_SIZE and ~TARGET_PAGE_MASK instead.

"DumpState.page_size" has type "size_t", whereas TARGET_PAGE_SIZE has type
"int". TARGET_PAGE_MASK is of type "int" and has negative value. The patch
affects the implicit type conversions as follows:

- create_header32() and create_header64(): assigned to "block_size", which
  has type "uint32_t". No change.

- get_next_page(): "block->target_start", "block->target_end" and "addr"
  have type "hwaddr" (uint64_t).

  Before the patch,
  - if "size_t" was "uint64_t", then no additional conversion was done as
    part of the usual arithmetic conversions,
  - If "size_t" was "uint32_t", then it was widened to uint64_t as part of
    the usual arithmetic conversions,
  for the remainder and addition operators.

  After the patch,
  - "~TARGET_PAGE_MASK" expands to  ~~((1 << TARGET_PAGE_BITS) - 1). It
    has type "int" and positive value (only least significant bits set).
    That's converted (widened) to "uint64_t" for the bit-ands. No visible
    change.
  - The same holds for the (addr + TARGET_PAGE_SIZE) addition.

- write_dump_pages():
  - TARGET_PAGE_SIZE passed as argument to a bunch of functions that all
    have prototypes. No change.

  - When incrementing "offset_data" (of type "off_t"): given that we never
    build for ILP32_OFF32 (see "-D_FILE_OFFSET_BITS=64" in configure),
    "off_t" is always "int64_t", and we only need to consider:
    - ILP32_OFFBIG: "size_t" is "uint32_t".
      - before: int64_t += uint32_t. Page size converted to int64_t for
        the addition.
      - after:  int64_t += int32_t. No change.
    - LP64_OFF64: "size_t" is "uint64_t".
      - before: int64_t += uint64_t. Offset converted to uint64_t for the
        addition, then the uint64_t result is converted to int64_t for
        storage.
      - after:  int64_t += int32_t. Same as the ILP32_OFFBIG/after case.
        No visible change.

  - (size_out < s->page_size) comparisons, and (size_out = s->page_size)
    assignment:
    - before: "size_out" is of type "size_t", no implicit conversion for
              either operator.
    - after: TARGET_PAGE_SIZE (of type "int" and positive value) is
             converted to "size_t" (for the relop because the latter is
             one of "uint32_t" and "uint64_t"). No visible change.

- dump_init():
  - DIV_ROUND_UP(DIV_ROUND_UP(s->max_mapnr, CHAR_BIT), s->page_size): The
    innermost "DumpState.max_mapnr" field has type uint64_t, which
    propagates through all implicit conversions at hand:

    #define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))

    regardless of the page size macro argument's type. In the outer macro
    replacement, the page size is converted from uint32_t and int32_t
    alike to uint64_t.

  - (tmp * s->page_size) multiplication: "tmp" has size "uint64_t"; the
    RHS is converted to that type from uint32_t and int32_t just the same
    if it's not uint64_t to begin with.

Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-06-11 10:10:28 -04:00
Laszlo Ersek
22227f121b dump: eliminate DumpState.page_shift ("guest's page shift")
Just use TARGET_PAGE_BITS.

"DumpState.page_shift" used to have type "uint32_t", while the replacement
TARGET_PAGE_BITS has type "int". Since "DumpState.page_shift" was only
used as bit shift counts in the paddr_to_pfn() and pfn_to_paddr() macros,
this is safe.

Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-06-11 10:10:28 -04:00
Laszlo Ersek
92ba1401e0 dump: simplify write_start_flat_header()
Currently, the function
- defines and populates an auto variable of type MakedumpfileHeader
- allocates and zeroes a buffer of size MAX_SIZE_MDF_HEADER (4096)
- copies the former into the latter (covering an initial portion of the
  latter)

Fill in the MakedumpfileHeader structure in its final place (the alignment
is OK because the structure lives at the address returned by g_malloc0()).

Approximately-suggested-by: Luiz Capitulino <lcapitulino@redhat.com>
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-06-11 10:10:28 -04:00
Laszlo Ersek
ae3f88f60f dump: fill in the flat header signature more pleasingly to the eye
The "mh.signature" array field has size 16, and is zeroed by the preceding
memset(). MAKEDUMPFILE_SIGNATURE expands to a string literal with string
length 12 (size 13). There's no need to measure the length of
MAKEDUMPFILE_SIGNATURE at runtime, nor for the extra zero-filling of
"mh.signature" with strncpy().

Use memcpy() with MIN(sizeof, sizeof) for robustness (which is an integer
constant expression, evaluable at compile time.)

Approximately-suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
2014-06-11 10:10:28 -04:00
Gerd Hoffmann
fa7a1e5219 gtk: update window size after showing/hiding tabs
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-06-11 14:26:49 +02:00
Gerd Hoffmann
f50def915e gtk: factor out gtk3 grab into the new gd_grab_devices function
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-06-11 14:26:49 +02:00
Gerd Hoffmann
0a337ed067 gtk: cleanup backend dependencies
Make configure detect gtk x11 backend and link libX11 then.  Make
gtk backend specific code properly #ifdef'ed on the GTK_WINDOWING_*
backends at runtime).  Our gtk ui code should build and run fine on
any platform now.

This also fixes the linker failute due to the new XkbGetKeyboard call
added by commit 3158a3482b.

Cc: Richard Henderson <rth@twiddle.net>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Daniel P. Berrange <berrange@redhat.com>
2014-06-11 14:26:49 +02:00
Gerd Hoffmann
932f2d7e0f gtk: factor out keycode mapping
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-06-11 14:26:49 +02:00
Sean Bruno
c4af6d4b13 bsd-user: Fix syscall format, add strace support for more syscalls
Signed-off-by: Sean Bruno <sbruno@freebsd.org>
Message-id: 1402246651-71099-10-git-send-email-sbruno@freebsd.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-11 00:25:06 +01:00
Sean Bruno
f35f961ac9 bsd-user: Implement strace support for thr_* syscalls
Signed-off-by: Sean Bruno <sbruno@freebsd.org>
Message-id: 1402246651-71099-9-git-send-email-sbruno@freebsd.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-11 00:25:06 +01:00
Sean Bruno
1e501653ab bsd-user: Implement strace support for extattr_* syscalls
Signed-off-by: Sean Bruno <sbruno@freebsd.org>
Message-id: 1402246651-71099-8-git-send-email-sbruno@freebsd.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-11 00:25:06 +01:00
Sean Bruno
605474815d bsd-user: Implement strace support for __acl_* syscalls
Signed-off-by: Sean Bruno <sbruno@freebsd.org>
Message-id: 1402246651-71099-7-git-send-email-sbruno@freebsd.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-11 00:25:06 +01:00
Sean Bruno
b85159a3a3 bsd-user: Implement strace support for print_ioctl syscall
Signed-off-by: Sean Bruno <sbruno@freebsd.org>
Message-id: 1402246651-71099-5-git-send-email-sbruno@freebsd.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-11 00:25:06 +01:00
Sean Bruno
80b346040d bsd-user: Implement strace support for print_sysctl syscall
Signed-off-by: Sean Bruno <sbruno@freebsd.org>
Message-id: 1402246651-71099-4-git-send-email-sbruno@freebsd.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-11 00:25:06 +01:00
Sean Bruno
88dae46d18 bsd-user: GPL v2 attribution update and style
Signed-off-by: Sean Bruno <sbruno@freebsd.org>
Message-id: 1402246651-71099-3-git-send-email-sbruno@freebsd.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-11 00:25:06 +01:00
Stacey Son
adfc3e91e2 bsd-user: add HOST_VARIANT_DIR for various *BSD dependent code
This change adds HOST_VARIANT_DIR so the various BSD OS dependent
code can be separated into its own directories rather than
using #ifdef's.

This may also allow an BSD variant OS to host another BSD variant's
executable as a target.

Signed-off-by: Sean Bruno <sbruno@freebsd.org>
Message-id: 1402246651-71099-2-git-send-email-sbruno@freebsd.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-11 00:25:06 +01:00
Natanael Copa
7224f66ec3 exec: replace ffsl with ctzl
See commit fbeadf50 (bitops: unify bitops_ffsl with the one in
host-utils.h, call it bitops_ctzl) on why ctzl should be used instead
of ffsl.

This is also needed for musl libc which does not implement ffsl.

Signed-off-by: Natanael Copa <ncopa@alpinelinux.org>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-11 00:25:06 +01:00
Natanael Copa
747eb78baa vhost: replace ffsl with ctzl
Avoid using the GNU extesion ffsl which is not implemented in musl libc.

The atomic_xchg() means we know that vhost_log_chunk_t will never be
larger than the 'long' type, so ctzl() is always sufficient.

See also commit fbeadf50 (bitops: unify bitops_ffsl with the one in
host-utils.h, call it bitops_ctzl) on why ctzl should be used instead
of ffsl.

Signed-off-by: Natanael Copa <ncopa@alpinelinux.org>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-11 00:25:06 +01:00
Natanael Copa
adf9d70b0d xen: replace ffsl with ctzl
ffsl is a GNU extension and not available in musl libc.

See also commit fbeadf50 (bitops: unify bitops_ffsl with the one in
host-utils.h, call it bitops_ctzl) on why ctzl should be used instead
of ffsl.

Signed-off-by: Natanael Copa <ncopa@alpinelinux.org>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
[PMM: rebased to accommodate file rename to xen-hvm.c]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-11 00:25:06 +01:00
Natanael Copa
6ad3f09bd4 util/qemu-openpty: fix build with musl libc by include termios.h as fallback
Include termios.h as POSIX fallback when not glibc, bsd or solaris.
POSIX says that termios.h should define struct termios and TCAFLUSH.
http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/termios.h.html

This fixes the following compile errors with musl libc:

util/qemu-openpty.c: In function 'qemu_openpty_raw':
util/qemu-openpty.c:112:20: error: storage size of 'tty' isn't known
     struct termios tty;
                    ^
...
util/qemu-openpty.c:128:24: error: 'TCSAFLUSH' undeclared (first use in this function)
     tcsetattr(*aslave, TCSAFLUSH, &tty);
                        ^

Signed-off-by: Natanael Copa <ncopa@alpinelinux.org>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-11 00:25:06 +01:00
Peter Maydell
b7b5233ad7 bsd-user/mmap.c: Don't try to override g_malloc/g_free
Trying to override the implementations of g_malloc and g_free is
a really bad idea -- it means statically linked builds fail to
link (because of the multiple definitions provided by this file
and by glib), and non-statically linked builds segfault as soon
as they try to do anything more complicated than printing the
usage message. Remove these overridden versions and just use
the glib ones.

This is sufficient that bsd-user can run basic x86-64
binaries on OpenBSD again; FreeBSD and NetBSD seem to have
further issues.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Sean Bruno <sbruno@freebsd.org>
Reviewed-by: Ed Maste <emaste@freebsd.org>
2014-06-11 00:25:06 +01:00
Peter Maydell
591b320ad0 util/hbitmap.c: Use ctpopl rather than reimplementing a local equivalent
The function popcountl() in hbitmap.c is effectively a reimplementation
of what host-utils.h provides as ctpopl(). Use ctpopl() directly; this fixes
a failure to compile on NetBSD (whose strings.h erroneously exposes a
system popcountl() which clashes with this one).

Reported-by: Martin Husemann <martin@duskware.de>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-11 00:25:06 +01:00
Stacey Son
6b24119b7f bsd-user: refresh freebsd system call numbers
Update FreeBSD system call numbers in freebsd/syscall_nr.h.


Signed-off-by: Stacey Son <sson@FreeBSD.org>
Reviewed-by: Ed Maste <emaste@freebsd.org>
Signed-off-by: Sean Bruno <sbruno@freebsd.org>
Message-id: 1401220104-7147-2-git-send-email-sbruno@freebsd.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-11 00:25:06 +01:00
Peter Maydell
b780bf8eff Merge remote-tracking branch 'remotes/mjt/tags/trivial-patches-2014-06-10' into staging
trivial patches for 2014-06-10

# gpg: Signature made Tue 10 Jun 2014 17:07:19 BST using RSA key ID A4C3D7DB
# gpg: Good signature from "Michael Tokarev <mjt@tls.msk.ru>"
# gpg:                 aka "Michael Tokarev <mjt@corpit.ru>"
# gpg:                 aka "Michael Tokarev <mjt@debian.org>"
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg:          There is no indication that the signature belongs to the owner.
# Primary key fingerprint: 6EE1 95D1 886E 8FFB 810D  4324 457C E0A0 8044 65C5
#      Subkey fingerprint: 6F67 E18E 7C91 C5B1 5514  66A7 BEE5 9D74 A4C3 D7DB

* remotes/mjt/tags/trivial-patches-2014-06-10: (25 commits)
  virtio.c: fix error message
  hw: vmware_vga: don't return cursorx when the driver asks for cursory register
  migration: Plug memory leak in migrate-set-cache-size command
  libcacard: Clean up dead stores before g_free()
  libcacard: Drop superfluous conditionals around g_free()
  cpu/x86: correctly set errors in x86_cpu_parse_featurestr
  smbios: use g_free directly on NULL pointers
  vdi: remove double conversion
  apb: Fix compiler warnings (large constants)
  hw/net/ne2000-isa: Register vmstate struct
  target-microblaze: Delete unused sign_extend() function
  hw/misc/milkymist-softusb: Remove unused softusb_{read, write}_pmem()
  target-i386/translate.c: Remove unused tcg_gen_lshift()
  hw/isa/pc87312: Remove unused function is_parallel_epp()
  hw/intc/openpic: Remove unused function IRQ_testbit()
  hw/dma/xilinx_axidma: Remove unused stream_halted() function
  util/qemu-sockets.c: Avoid unused variable warnings
  hw/sd/sd.c: Drop unused sd_acmd_type[] array
  hw/i386/pc.c: Remove unused parallel_io and parallel_irq variables
  slirp: Remove unused zero_ethaddr[] variable
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-10 17:16:03 +01:00
Michael Tokarev
1a2858995d virtio.c: fix error message
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-06-10 20:07:01 +04:00
Nicolas Owens
e2bb4ae746 hw: vmware_vga: don't return cursorx when the driver asks for cursory register
hello qemu-*@nongnu.org, this is my first contribution. apologies if
something is incorrect.

this patch fixes vmware_vga.c so that it actually returns the cursory
register when asked for, instead of cursorx.

Signed-off-by: Nicolas Owens <mischief@offblast.org>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-06-10 20:06:48 +04:00
Chen Gang
4380be0e99 migration: Plug memory leak in migrate-set-cache-size command
We call g_free() after cache_fini() in migration_end(), but we don't
call it after cache_fini() in xbzrle_cache_resize(), leaking the
memory.

cache_init() and cache_fini() are a pair.  Since cache_init()
allocates the cache, let cache_fini() free it.  This plugs the leak.

Signed-off-by: Chen Gang <gang.chen.5i5j@gmail.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-06-10 19:54:43 +04:00
Markus Armbruster
fec0da9cbf libcacard: Clean up dead stores before g_free()
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-06-10 19:39:34 +04:00
Markus Armbruster
ec15993d9d libcacard: Drop superfluous conditionals around g_free()
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-06-10 19:39:34 +04:00
Paolo Bonzini
6b1dd54b6a cpu/x86: correctly set errors in x86_cpu_parse_featurestr
Because of the "goto out", the contents of local_err are leaked
and lost.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-06-10 19:39:34 +04:00
Paolo Bonzini
a10678b08e smbios: use g_free directly on NULL pointers
No need to wrap it with an if.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-06-10 19:39:34 +04:00
Paolo Bonzini
6998b6c11b vdi: remove double conversion
This should be a problem when running on big-endian machines.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
Reviewed-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-06-10 19:39:34 +04:00
Stefan Weil
d1180c1e57 apb: Fix compiler warnings (large constants)
Both constants need more than 32 bit.

Signed-off-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-06-10 19:39:34 +04:00
Peter Maydell
89218c218f hw/net/ne2000-isa: Register vmstate struct
The ne2000-isa device defines a VMState struct for migration, but
we forgot to actually register it. Correct this deficiency by
setting dc->vmsd.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-06-10 19:39:34 +04:00
Peter Maydell
fc4bde9025 target-microblaze: Delete unused sign_extend() function
The sign_extend() function is unused; delete it.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-06-10 19:39:34 +04:00
Peter Maydell
029ad4bcf3 hw/misc/milkymist-softusb: Remove unused softusb_{read, write}_pmem()
The functions softusb_read_pmem() and softusb_write_pmem() are unused;
remove them.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-06-10 19:39:34 +04:00
Peter Maydell
e3a17ef6cc target-i386/translate.c: Remove unused tcg_gen_lshift()
The function tcg_gen_lshift() is unused; remove it.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-06-10 19:39:34 +04:00
Peter Maydell
f46b9cc71c hw/isa/pc87312: Remove unused function is_parallel_epp()
The function is_parallel_epp() is unused; remove it.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-06-10 19:39:34 +04:00
Peter Maydell
c1d7572793 hw/intc/openpic: Remove unused function IRQ_testbit()
The IRQ_testbit() function is never used; remove it.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-06-10 19:39:34 +04:00
Peter Maydell
a1fa7992a9 hw/dma/xilinx_axidma: Remove unused stream_halted() function
The stream_halted() function is never used; remove it.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-06-10 19:39:34 +04:00
Peter Maydell
f9b5426fd5 util/qemu-sockets.c: Avoid unused variable warnings
The 'on' variable is never used, and 'off' is only used
if IPV6_V6ONLY is defined; delete 'on' and move 'off' to
the point where it is used. This avoids warnings from
clang 3.4.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-06-10 19:39:34 +04:00
Peter Maydell
7179585688 hw/sd/sd.c: Drop unused sd_acmd_type[] array
Drop the sd_acmd_type[] array: it is never used. (The equivalent
sd_cmd_type[] array for normal commands is used to identify
those commands whose argument includes the card address in the
top 16 bits; but for app commands the card address is passed
with the APP_CMD prefix, not with the argument to the app command
itself.)

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-06-10 19:39:34 +04:00
Peter Maydell
831f4d27b6 hw/i386/pc.c: Remove unused parallel_io and parallel_irq variables
The variables parallel_io and parallel_irq are unused; delete them.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-06-10 19:39:34 +04:00
Peter Maydell
49bba868df slirp: Remove unused zero_ethaddr[] variable
The zero_ethaddr[] array is never used; delete it.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-06-10 19:39:34 +04:00
Sergey Fedorov
2a802aaf63 qtest: fix hex2nib for capital characters
Signed-off-by: Sergey Fedorov <serge.fdrv@gmail.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-06-10 19:39:34 +04:00
Peter Crosthwaite
ef18c2f54e net: cadence_gem: Remove &desc[0] usages
Just use desc instead.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-06-10 19:39:34 +04:00
Peter Crosthwaite
3048ed6aac net: cadence_gem: Comment spelling sweep
Fix some typos in comments.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-06-10 19:39:34 +04:00
Peter Crosthwaite
fa15286a75 net: cadence_gem: Add Tx descriptor fetch printf
Add a debug printf for TX descriptor fetching. This is helpful to anyone
needing to debug TX ring buffer traversal. It is also now consistent with
the RX code which has a similar printf.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-06-10 19:39:34 +04:00
Peter Crosthwaite
6ab57a6b80 net: cadence_gem: Fix Tx descriptor update
The local variable "desc" was being used to read-modify-write the
first descriptor (of a multi-desc packet) upon packet completion.
desc however continues to be used by the code as the current
descriptor. Give this first desc RMW it's own local variable to
avoid trampling.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2014-06-10 19:39:34 +04:00
Fam Zheng
1c33ac5716 rules.mak: Rewrite unnest-vars
The macro unnest-vars is the most important, complicated but hard to
track magic in QEMU's build system.

Rewrite it in a (hopefully) clearer way, with more comments, to make it
easier to understand and maintain.

Remove DSO_CFLAGS and module-objs-m that are not used.

A bonus fix of this version is, per object variables are properly
protected in save-objs and load-objs, before including sub-dir
Makefile.objs, just as nested variables are. So the occasional same
object name from different directory levels won't step on each other's
foot.

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-10 13:59:02 +02:00
Peter Maydell
3334e929ae Merge remote-tracking branch 'remotes/kraxel/tags/pull-console-20140610-1' into staging
console: two little bugfixes.

# gpg: Signature made Tue 10 Jun 2014 12:01:07 BST using RSA key ID D3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>"
# gpg:                 aka "Gerd Hoffmann <gerd@kraxel.org>"
# gpg:                 aka "Gerd Hoffmann (private) <kraxel@gmail.com>"

* remotes/kraxel/tags/pull-console-20140610-1:
  console: fix -vga none -sdl crash
  console: kill MAX_CONSOLES, alloc consoles dynamically

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-10 12:06:17 +01:00
Gerd Hoffmann
333cb18ff4 console: fix -vga none -sdl crash
Call get_alloc_displaystate() for proper initialization
instead of allocating with g_new().

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-06-10 12:36:36 +02:00
Gerd Hoffmann
a1d2db08d8 console: kill MAX_CONSOLES, alloc consoles dynamically
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2014-06-10 12:36:36 +02:00
Cornelia Huck
99519e677b configure: unset interfering variables
The check for big or little endianness relies on grep reporting
match/non-match on the generated binary. If the user specified
--binary-files=without-match in their GREP_OPTIONS, this will fail.

Let's follow what autoconf does and unset GREP_OPTIONS and CLICOLOR_FORCE
at the beginning of the script.

Reported-by: Eugene (jno) Dvurechenski <jno@linux.vnet.ibm.com>
Suggested-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-10 12:34:37 +02:00
Rick Liu
18e588b197 configure: duplicate/incorrect order of -lrt
'-lrt' flag duplication/incorrect order
would cause 'undefined reference to clock_gettime' error during compilation time.

Before fix:
... -o qemu-bridge-helper qemu-bridge-helper.o    -lrt -pthread -lgthread-2.0 -lrt -lglib-2.0
After fix:
... -o qemu-bridge-helper qemu-bridge-helper.o    -pthread -lgthread-2.0 -lrt -lglib-2.0

Reference:
http://hi.baidu.com/sanitywolf/item/7a8b69c1e76dd220a0b50ab1

Signed-off-by: Rick Liu <yrliu.ca@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-10 12:34:37 +02:00
Peter Maydell
7b0140e49b Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20140610' into staging
Several patches for s390:

- bugfixes: A fix for a long-standing bug in the css code as well as
  a fixup for the recent I/O adapter support.
- Exploitation of the userspace cmma enablement/reset interface, if
  it is present.
- Some debuggability improvements by logging unmanageable conditions.
- virtio-ccw finally gets migration support for its structures.
- Some cleanup as to how floating interrupts are injected.

# gpg: Signature made Tue 10 Jun 2014 08:57:56 BST using RSA key ID C6F02FAF
# gpg: Can't check signature: public key not found

* remotes/cohuck/tags/s390x-20140610:
  s390x/kvm: inject via flic
  s390x: cleanup interrupt injection
  s390x/kvm: add alternative injection interface
  s390x: consolidate floating interrupts
  s390/virtio-ccw: migration support
  s390x/kvm: Log unmanageable program interruptions
  s390x/kvm: Log unmanageable external interruptions
  s390x/kvm: enable/reset cmma via vm attributes
  s390x/kvm: make flic play well with old kernels
  s390x/css: handle emw correctly for tsch

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-10 10:59:26 +01:00
Cornelia Huck
bbd8bb8e32 s390x/kvm: inject via flic
Try to inject floating interrupts via the flic if it is available.
This allows us to inject the full range of floating interrupts.

Reviewed-by: Jens Freimann <jfrei@linux.vnet.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
2014-06-10 09:50:27 +02:00
Cornelia Huck
de13d21614 s390x: cleanup interrupt injection
Remove the need for a cpu to inject a floating interrupt on kvm.

Acked-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
2014-06-10 09:50:27 +02:00
Cornelia Huck
66ad0893f0 s390x/kvm: add alternative injection interface
Add kvm_s390_{vcpu,floating}_interrupt, which offer the possibility
to inject interrupts with larger payloads (when a kvm backend becomes
available).

Moreover, kvm_s390_floating_interrupt() does no longer have the bogus
requirement for a vcpu.

Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
2014-06-10 09:50:27 +02:00
Cornelia Huck
79afc36d91 s390x: consolidate floating interrupts
Move the injection code for all floating interrupts to interrupt.c
and add a comment.

Also get rid of the #ifdef CONFIG_KVM for the service interrupt.

Reviewed-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
2014-06-10 09:50:27 +02:00
Jens Freimann
bcb2b582f3 s390/virtio-ccw: migration support
This patch adds live migration support for virtio-ccw devices.
It's not done with vmstate because virtio itself is not yet ported
to vmstate either.

Signed-off-by: Jens Freimann <jfrei@linux.vnet.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
2014-06-10 09:50:27 +02:00
Thomas Huth
6449a41a4d s390x/kvm: Log unmanageable program interruptions
The kernel only drops to userspace if an endless program interrupt loop
has been detected. Let's print an error message in this case to inform
the user about the crash and stop the affected CPU with a panic event,
just like it is already done for the external interruption loop detection.

Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Signed-off-by: Jens Freimann <jfrei@linux.vnet.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
2014-06-10 09:50:27 +02:00
Thomas Huth
a2689242b1 s390x/kvm: Log unmanageable external interruptions
Interception code 0x14 only drops to userspace when an unmanageable
external interruption interception occured (e.g. if the External New
PSW does not disable external interruptions). Instead of bailing out
via the default handler, it is better to inform the user with a
proper error message that also includes the bad PSW, and to stop
the affected CPU with a panic event instead.

Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Signed-off-by: Jens Freimann <jfrei@linux.vnet.ibm.com>
Reviewed-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
2014-06-10 09:50:27 +02:00
Dominik Dingel
4cb88c3c37 s390x/kvm: enable/reset cmma via vm attributes
Exploit the new api for userspace-controlled cmma. If supported, enable
cmma during kvm initialization and register a reset handler for cmma,
which is also called directly from the load IPL code.

The reset functionality is needed to reset the cmma state of the guest
pages, e.g. if a system reset is triggered via qemu monitor; otherwise
this could result in data corruption.

A guest triggered reboot may now lead to multiple cmma resets; this is
OK, however, as this is slowpath anyway and the simplest way to achieve
the intended effects.

Signed-off-by: Dominik Dingel <dingel@linux.vnet.ibm.com>
Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
Acked-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
2014-06-10 09:50:27 +02:00
Cornelia Huck
08da527fd0 s390x/kvm: make flic play well with old kernels
If we run with an old kernel that does not support KVM_CAP_IRQ_ROUTING,
we don't have to do anything in the ->register_io_adapter and
->io_adapter_map callbacks and therefore should return 0 instead of
-ENOSYS (just as the non-kvm flic does).

This fixes using adapter interrupts when running under an older kernel,
which broke with "s390x: add I/O adapter registration".

Reported-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
2014-06-10 09:50:26 +02:00
Cornelia Huck
f068d320de s390x/css: handle emw correctly for tsch
We should not try to store the emw portion of the irb if extended
measurements are not applicable. In particular, we should not surprise
the guest by storing a larger irb if it did not enable extended
measurements.

Cc: qemu-stable@nongnu.org
Reviewed-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
Tested-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
2014-06-10 09:50:26 +02:00
Paolo Bonzini
471f7e30a4 libcacard: improve documentation
Using the file-backed smartcard backend is black magic, but it can
be useful if your only smartcard bricks itself if it is accessed
the wrong way too many times.

Complete the documentation to include the art of creating certificates
and using them with QEMU, based on Ray Strode's useful tutorial at
https://blogs.gnome.org/halfline/2013/09/08/another-smartcard-post/
but with ccid-card-emulated or vscclient instead of SPICE.

Cc: Ray Strode <rstrode@redhat.com>
Reviewed-by: Alon Levy <alevy@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-10 07:44:01 +02:00
Michael Tokarev
ae9b65e873 libcacard: actually use symbols file
libtool has an argument for .syms file, which is -export-symbols.
There's no argument `-export-syms', and it looks like at least on
linux, -export-syms is just ignored.  Use the correct argument,
-export-symbols, to actually get the right export list.

Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Reviewed-by: Alon Levy <alevy@redhat.com>
Tested-by: Alon Levy <alevy@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-10 07:44:01 +02:00
Michael Tokarev
fd25c0e6dd libcacard: replace qemu thread primitives with glib ones
Replace QemuMutex with GMutex and QemuCond with GCond
(with corresponding function changes), to make libcacard
independent of qemu internal functions.

After this step, none of libcacard internals use any
qemu-provided symbols.  Maybe it's a good idea to
stop including qemu-common.h internally too.

Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Reviewed-by: Alon Levy <alevy@redhat.com>
Tested-by: Alon Levy <alevy@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-10 07:44:01 +02:00
Michael Tokarev
2a0c46da96 vscclient: use glib thread primitives not qemu
Use glib-provided thread primitives in vscclient instead of
qemu ones, and do not use qemu sockets in there (open-code
call to WSAStartup() for windows to initialize things).

This way, vscclient becomes more stand-alone, independent on
qemu internals.

Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Reviewed-by: Alon Levy <alevy@redhat.com>
Tested-by: Alon Levy <alevy@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-10 07:44:01 +02:00
Michael Tokarev
86946a2d83 glib-compat.h: add new thread API emulation on top of pre-2.31 API
Thread API changed in glib-2.31 significantly.  Before that version,
conditionals and mutexes were only allocated dynamically, using
_new()/_free() interface.  in 2.31 and up, they're allocated statically
as regular variables, and old interface is deprecated.

(Note: glib docs says the new interface is available since version
2.32, but it was actually introduced in version 2.31).

Create the new interface using old primitives, by providing non-opaque
definitions of the base types (GCond and GMutex) using GOnces.

Replace #ifdeffery around GCond and GMutex in trace/simple.c and
coroutine-gthread.c too because it does not work anymore with the new
glib-compat.h.

Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
[Use GOnce to support lazy initialization; introduce CompatGMutex
 and CompatGCond.  - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-10 07:44:01 +02:00
Peter Maydell
7721a30442 Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20140609-1' into staging
----------------------------------------------------------------
target-arm queue:
 * support -bios option in vexpress boards
 * register the Cortex-A57 impdef system registers
 * fix handling of UXN bit in ARMv8 page tables
 * complete support of crypto insns in A32/T32
 * implement CRC and crypto insns in A64
 * fix bugs in generic timer control register

----------------------------------------------------------------

# gpg: Signature made Mon 09 Jun 2014 16:08:26 BST using RSA key ID 14360CDE
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>"

* remotes/pmaydell/tags/pull-target-arm-20140609-1:
  target-arm: Delete unused iwmmxt_msadb helper
  target-arm: Fix errors in writes to generic timer control registers
  target-arm: A64: Implement two-register SHA instructions
  target-arm: A64: Implement 3-register SHA instructions
  target-arm: A64: Implement AES instructions
  target-arm: A32/T32: Mask CRC value in calling code, not helper
  target-arm: A64: Implement CRC instructions
  target-arm: VFPv4 implies half-precision extension
  target-arm: Clean up handling of ARMv8 optional feature bits
  target-arm: Remove unnecessary setting of feature bits
  target-arm: arm_any_initfn() should never set ARM_FEATURE_AARCH64
  target-arm: A64: Use PMULL feature bit for PMULL
  target-arm: add support for v8 VMULL.P64 instruction
  target-arm: Allow 3reg_wide undefreq to encode more bad size options
  target-arm: add support for v8 SHA1 and SHA256 instructions
  target-arm: Correct handling of UXN bit in ARMv8 LPAE page tables
  target-arm: Prepare cpreg writefns/readfns for EL3/SecExt
  target-arm/cpu64.c: Actually register Cortex-A57 impdef registers
  vexpress: Add support for the -bios flag to provide firmware

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-09 17:04:13 +01:00
Peter Maydell
14ac573392 Merge remote-tracking branch 'remotes/stefanha/tags/tracing-pull-request' into staging
Tracing pull request

# gpg: Signature made Mon 09 Jun 2014 14:44:18 BST using RSA key ID 81AB73C8
# gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>"
# gpg:                 aka "Stefan Hajnoczi <stefanha@gmail.com>"

* remotes/stefanha/tags/tracing-pull-request:
  trace: Replace fprintf with error_report and print location
  trace: Multi-backend tracing
  trace: Replace error with warning if event is not defined
  simpletrace: add support for trace record pid field
  trace: add pid field to simpletrace record

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-09 16:25:34 +01:00
Peter Maydell
3b1a413812 target-arm: Delete unused iwmmxt_msadb helper
The iwmmxt_msadb helper and its corresponding gen function are unused;
delete them. (This function appears to have never been used right back
to the initial implementation of iwMMXt; it is identical to iwmmxt_madduq,
and is presumably an accidental remnant from the initial development.)

Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1401822125-1822-1-git-send-email-peter.maydell@linaro.org
2014-06-09 16:06:12 +01:00
Peter Maydell
d3afacc726 target-arm: Fix errors in writes to generic timer control registers
The code for handling writes to the generic timer control registers
had several bugs:
 * ISTATUS (bit 2) is read-only but we forced it to zero on any write
 * the check for "was IMASK (bit 1) toggled?" incorrectly used '&' where
   it should be '^'
 * the handling of IMASK was inverted: we should set the IRQ if
   ISTATUS is set and IMASK is clear, not if both are set

The combination of these bugs meant that when running a Linux guest
that uses the generic timers we would fairly quickly end up either
forgetting that the timer output should be asserted, or failing to
set the IRQ when the timer was unmasked. The result is that the guest
never gets any more timer interrupts.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1401803208-1281-1-git-send-email-peter.maydell@linaro.org
Cc: qemu-stable@nongnu.org
2014-06-09 16:06:12 +01:00
Peter Maydell
f6fe04d566 target-arm: A64: Implement two-register SHA instructions
Implement the two-register SHA instruction group from the optional
Crypto Extensions.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1401458125-27977-10-git-send-email-peter.maydell@linaro.org
2014-06-09 16:06:12 +01:00
Peter Maydell
be56f04eea target-arm: A64: Implement 3-register SHA instructions
Implement the 3-register SHA instruction group from the optional
Crypto Extensions.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1401458125-27977-9-git-send-email-peter.maydell@linaro.org
2014-06-09 16:06:12 +01:00
Peter Maydell
5acc765c04 target-arm: A64: Implement AES instructions
Implement the AES instructions from the optional Crypto Extensions.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1401458125-27977-8-git-send-email-peter.maydell@linaro.org
2014-06-09 16:06:12 +01:00
Peter Maydell
aa633469ed target-arm: A32/T32: Mask CRC value in calling code, not helper
Bring the 32-bit CRC helper functions into line with the A64 ones,
by masking the high bytes of the value in the calling code rather
than the helper. This is more efficient since we can determine the
mask at translation time.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1401458125-27977-7-git-send-email-peter.maydell@linaro.org
2014-06-09 16:06:12 +01:00
Peter Maydell
130f2e7dcb target-arm: A64: Implement CRC instructions
Implement the optional A64 CRC instructions.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1401458125-27977-6-git-send-email-peter.maydell@linaro.org
2014-06-09 16:06:12 +01:00
Peter Maydell
da5141fc45 target-arm: VFPv4 implies half-precision extension
VFPv4 implies the presence of the half-precision floating point
extension (which is optional in VFPv3). Add this implied rule
to arm_cpu_realizefn() and remove some no-longer-needed explicit
setting of the bit in initfns.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1401458125-27977-5-git-send-email-peter.maydell@linaro.org
2014-06-09 16:06:11 +01:00
Peter Maydell
25f748e37a target-arm: Clean up handling of ARMv8 optional feature bits
CRC and crypto are both optional v8 extensions, so FEATURE_V8
should not imply them. Instead we should set these bits in the
initfns for the 32-bit and 64-bit "cpu any" and for the Cortex-A57.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1401458125-27977-4-git-send-email-peter.maydell@linaro.org
2014-06-09 16:06:11 +01:00
Peter Maydell
fb8ad9f2c1 target-arm: Remove unnecessary setting of feature bits
FEATURE_V8 implies both FEATURE_V7MP and FEATURE_ARM_DIV, so
we don't need to set them explicitly in initfns which set the
V8 feature bit.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1401458125-27977-3-git-send-email-peter.maydell@linaro.org
2014-06-09 16:06:11 +01:00
Peter Maydell
46d9dfdad6 target-arm: arm_any_initfn() should never set ARM_FEATURE_AARCH64
The arm_any_initfn() is used only for the 32-bit linux-user "cpu any",
so it only gets called in builds where TARGET_AARCH64 is not defined.
Remove the unreachable line which sets ARM_FEATURE_AARCH64.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1401458125-27977-2-git-send-email-peter.maydell@linaro.org
2014-06-09 16:06:11 +01:00
Peter Maydell
411bdc7837 target-arm: A64: Use PMULL feature bit for PMULL
Now that we have a separate ARM_FEATURE_V8_PMULL bit, use it for
the A64 PMULL, not the AES feature bit.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-09 16:06:11 +01:00
Peter Maydell
4e624edaeb target-arm: add support for v8 VMULL.P64 instruction
Add support for the VMULL.P64 polynomial 64x64 to 128 bit multiplication
instruction in the A32/T32 instruction sets; this is part of the v8
Crypto Extensions.

To do this we have to move the neon_pmull_64_{lo,hi} helpers from
helper-a64.c into neon_helper.c so they can be used by the AArch32
translator.

Inspired-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1401386724-26529-4-git-send-email-peter.maydell@linaro.org
2014-06-09 16:06:11 +01:00
Peter Maydell
526d0096e5 target-arm: Allow 3reg_wide undefreq to encode more bad size options
The current undefreq field in the neon_3reg_wide handling allows us
to encode "UNDEF if size != 0" and "UNDEF if size == 0". This is
no longer sufficient with the advent of 64-bit polynomial VMULL,
which means we want to UNDEF if size == 1. Change the undefreq
encoding to use separate bits for all of "UNDEF if size == 0",
"UNDEF if size == 1" and "UNDEF if size == 2".

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1401386724-26529-3-git-send-email-peter.maydell@linaro.org
2014-06-09 16:06:11 +01:00
Ard Biesheuvel
f1ecb913d8 target-arm: add support for v8 SHA1 and SHA256 instructions
This adds support for the SHA1 and SHA256 instructions that are available
on some v8 implementations of Aarch32.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 1401386724-26529-2-git-send-email-peter.maydell@linaro.org
[PMM:
 * rebase
 * fix bad indent
 * add a missing UNDEF check for Q!=1 in the 3-reg SHA1/SHA256 case
 * use g_assert_not_reached()
 * don't re-extract bit 6 for the 2-reg-misc encodings
 * set the ELF HWCAP2 bits for the new features
]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-09 16:06:11 +01:00
Ian Campbell
d615efac7c target-arm: Correct handling of UXN bit in ARMv8 LPAE page tables
In v8 page tables bit 54 in the PTE is UXN in the EL0/EL1 translation regimes
and XN elsewhere. In v7 the bit is always XN. Since we only emulate EL0/EL1 we
can just treat this bit as UXN whenever we are in v8 mode.

Also correctly extract the upper attributes from the PTE entry, the v8 version
tried to avoid extracting the CONTIG bit and ended up with the upper bits being
off-by-one. Instead behave the same as v7 and extract (but ignore) the CONTIG
bit.

This fixes "Bad mode in Synchronous Abort handler detected, code 0x8400000f"
seen when modprobing modules under Linux.

Signed-off-by: Ian Campbell <ijc@hellion.org.uk>
Cc: Peter Maydell <peter.maydell@linaro.org>
Cc: Claudio Fontana <claudio.fontana@huawei.com>
Cc: Rob Herring <robherring2@gmail.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-09 16:06:11 +01:00
Fabian Aggeler
8d5c773e32 target-arm: Prepare cpreg writefns/readfns for EL3/SecExt
This patch changes some readfns/writefns to use raw_write
and raw_read functions, which use the fieldoffset specified
in ARMCPRegInfo instead of directly accessing the field.
This will simplify patches for EL3 & Security Extensions.

Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Fabian Aggeler <aggelerf@ethz.ch>
Message-id: 1401962428-14749-1-git-send-email-aggelerf@ethz.ch
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-09 15:43:22 +01:00
Peter Maydell
bf01601764 target-arm/cpu64.c: Actually register Cortex-A57 impdef registers
cpu64.c contains a reginfo list for the impdef registers on
the Cortex-A57; however we forgot to actually call define_arm_cp_regs(),
so it was sitting there doing nothing. Remedy this omission.

Message-id: 1401226259-23121-1-git-send-email-peter.maydell@linaro.org
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Tested-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-09 15:43:22 +01:00
Grant Likely
61e9924149 vexpress: Add support for the -bios flag to provide firmware
Right now to run firmware inside the QEMU VExpress model requires
padding out the firmware image to the size of the virtual flash and
passing it in via the -pflash argument. If the firmware image is passed
without padding, then QEMU will fail. Also, when passed as a -pflash
argument, QEMU treats the file as persistent storage and will modify the
file.

The -bios flag provides the semantics that we want for providing a
firmware image. This patch maps the contents of the -bios file into the
address space at the boot flash location.

Tested with the vexpress-a15 model and the Tianocore port.

Signed-off-by: Grant Likely <grant.likely@linaro.org>
Tested-by: Roy Franz <roy.franz@linaro.org>
[PMM: folded long line, removed stray \n from error message,
 use correct variable for printing image name, exit(1) rather than 0]
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-09 15:43:22 +01:00
Peter Maydell
4a331bb33b Merge remote-tracking branch 'remotes/stefanha/tags/net-pull-request' into staging
Net patches

# gpg: Signature made Mon 09 Jun 2014 14:41:34 BST using RSA key ID 81AB73C8
# gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>"
# gpg:                 aka "Stefan Hajnoczi <stefanha@gmail.com>"

* remotes/stefanha/tags/net-pull-request:
  e1000: remove broken support for 82573L
  tests: e1000: test additional device IDs
  e1000: allow command-line selection of card model
  vmxnet3: fix msix vectors unuse
  net: xilinx_ethlite: Fix Rx-pong interrupt

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-09 15:00:21 +01:00
Alexey Kardashevskiy
a35d9be622 trace: Replace fprintf with error_report and print location
This replaces fprintf(stderr) with error_report.

This moves local variables to the beginning of the function to comply
with QEMU's coding style.

Suggested-by: Lluís Vilanova <vilanova@ac.upc.edu>
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-09 15:43:40 +02:00
Lluís Vilanova
5b808275f3 trace: Multi-backend tracing
Adds support to compile QEMU with multiple tracing backends at the same time.

For example, you can compile QEMU with:

  $ ./configure --enable-trace-backends=ftrace,dtrace

Where 'ftrace' can be handy for having an in-flight record of events, and 'dtrace' can be later used to extract more information from the system.

This patch allows having both available without recompiling QEMU.

Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-09 15:43:40 +02:00
Alexey Kardashevskiy
82432638eb trace: Replace error with warning if event is not defined
At the moment QEMU exits if trace point is not defined which makes
a developer life harder if he has to switch between branches with
different traces implemented.

This replaces error+exit wit WARNING if the tracepoint does not exist or
not traceable.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-09 15:43:40 +02:00
Stefan Hajnoczi
80ff35cd3f simpletrace: add support for trace record pid field
Extract the pid field from the trace record and print it.

Change the trace record tuple from:
  (event_num, timestamp, arg1, ..., arg6)
to:
  (event_num, timestamp, pid, arg1, ..., arg6)

Trace event methods now support 3 prototypes:
1. <event-name>(arg1, arg2, arg3)
2. <event-name>(timestamp, arg1, arg2, arg3)
3. <event-name>(timestamp, pid, arg1, arg2, arg3)

Existing script continue to work without changes, they only know about
prototypes 1 and 2.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-09 15:43:40 +02:00
Stefan Hajnoczi
26896cbf35 trace: add pid field to simpletrace record
It is useful to know the QEMU process ID when working with traces from
multiple VMs.  Although the trace filename may contain the pid, tools
that aggregate traces or even trace globally need somewhere to record
the pid.

There is a reserved field in the trace event header struct that we can
use.

It is not necessary to bump the simpletrace file format version number
because it has already been incremented for the QEMU 2.1 release cycle
in commit "trace: [simple] Bump up log version number".

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-09 15:43:40 +02:00
Gabriel L. Somlo
7efea76377 e1000: remove broken support for 82573L
Currently, e1000 support is based on the manual for the 8254xx
model series. 82573x models are documented in a separate manual
(see http://www.intel.com/content/dam/www/public/us/en/documents/manuals/pcie-gbe-controllers-open-source-manual.pdf)
and the 82573L device ID no longer works correctly on either Linux
(3.14.*) or Windows 7.

This patch removes stale code claiming to support 82573L, cleaning
up the code base for the remaining 8254xx model series.

Signed-off-by: Gabriel Somlo <somlo@cmu.edu>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-09 15:38:58 +02:00
Gabriel L. Somlo
b167383ffb tests: e1000: test additional device IDs
Update e1000-test.c to check all currently supported devices.

Suggested-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Gabriel Somlo <somlo@cmu.edu>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-09 15:38:58 +02:00
Gabriel L. Somlo
8597f2e19e e1000: allow command-line selection of card model
Allow selection of different card models from the qemu
command line, to better accomodate a wider range of guests.

Signed-off-by: Romain Dolbeau <romain@dolbeau.org>
Signed-off-by: Gabriel Somlo <somlo@cmu.edu>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-09 15:38:58 +02:00
Jiri Pirko
b44672849a vmxnet3: fix msix vectors unuse
In vmxnet3_cleanup_msix(), there is called msix_vector_unuse() with
VMXNET3_MAX_INTRS. That is not correct since vector of
value VMXNET3_MAX_INTRS was never used. Also all the used vectors
are not un-used. So call vmxnet3_unuse_msix_vectors() instead which
does the correct job.

Signed-off-by: Jiri Pirko <jiri@resnulli.us>
Acked-by: Dmitry Fleytman <dmitry@daynix.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-09 15:38:58 +02:00
Peter Crosthwaite
40e76f736d net: xilinx_ethlite: Fix Rx-pong interrupt
There is no CTRL_I bit in the pong buffer control register. The
CTRL_I bit from the ping buffer masks both ping and pong buffers.
Fix.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-09 15:38:58 +02:00
Peter Maydell
5dfc05cb1d Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging
Block pull request

# gpg: Signature made Fri 06 Jun 2014 17:08:50 BST using RSA key ID 81AB73C8
# gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>"
# gpg:                 aka "Stefan Hajnoczi <stefanha@gmail.com>"

* remotes/stefanha/tags/block-pull-request: (42 commits)
  qapi: Extract qapi/block.json definitions
  qapi: Extract qapi/block-core.json definitions
  qapi: create two block related json modules
  qapi: Extract qapi/common.json definitions
  sheepdog: reload only header in a case of live snapshot
  sheepdog: fix vdi object update after live snapshot
  rbd: Fix leaks in rbd_start_aio() error path
  qemu-img: Document check exit codes
  block: fix wrong order in live block migration setup
  blockdev: acquire AioContext in block_set_io_throttle
  throttle: add detach/attach test case
  throttle: add throttle_detach/attach_aio_context()
  dataplane: Support VIRTIO_BLK_T_SCSI_CMD
  virtio-blk: Factor out virtio_blk_handle_scsi_req from virtio_blk_handle_scsi
  virtio-blk: Allow config-wce in dataplane
  block: Move declaration of bdrv_get_aio_context to block.h
  raw-posix: drop raw_get_aio_fd() since it is no longer used
  dataplane: implement async flush
  dataplane: delete IOQueue since it is no longer used
  dataplane: use the QEMU block layer for I/O
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-09 11:54:22 +01:00
Samuel Thibault
959e41473f slirp/arp: do not special-case bogus IP addresses
Do not special-case addresses with zero host part, as we do not
necessarily know how big it is, and the guest can fake them anyway.
Silently avoid having 0.0.0.0 as a destination, however.

Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
[Edgar: Minor change to subject]
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
2014-06-09 01:49:28 +02:00
Peter Maydell
37654d9e6a target-cris/translate.c: Remove _t_gen_mov_TN_env and _t_gen_mov_env_TN
The wrapper functions _t_gen_mov_TN_env and _t_gen_mov_env_TN are only
used via their accompanying non-underscore macros. The check they add
on offset is thus pointless, since the compiler will complain if the
struct field passed to the macro is not part of the struct. Remove the
functions and make the macros directly expand to the appropriate
tcg_gen_{ld,st}_tl calls.

This conveniently avoids a warning due to _t_gen_mov_TN_env() being
unused.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
2014-06-09 01:04:44 +02:00
Peter Maydell
08397c4b29 target-cris/translate.c: Remove t_gen_mov_TN_reg and t_gen_mov_reg_TN
Remove the t_gen_mov_TN_reg and t_gen_mov_reg_TN wrappers: the
latter is completely unused, and the former only used in a few
places (which are thus inconsistent with the rest of the decoder
which directly accesses cpu_R[]).

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
2014-06-09 01:04:44 +02:00
Peter Crosthwaite
a373cdb5ce intc: xilinx_uartlite: Convert SBD::init -> instance_init
SysBusDevice::init is depracated. Convert to Object::init
as prescribed by QOM conventions.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
2014-06-09 00:33:03 +02:00
Peter Crosthwaite
aa0f607f61 char: xilinx_uartlite: Convert to realize()
SysBusDevice::init is depracated. Convert to Object::init and
Device::realize as prescribed by QOM conventions.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
2014-06-09 00:33:03 +02:00
Peter Crosthwaite
95faaa73df char: xilinx_uartlite: Don't reset from init
This refresh of the device state is intended to be a reset side
effect. Move it to a proper reset handler rather than do it at
init time.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
2014-06-09 00:33:03 +02:00
Peter Crosthwaite
e8198f6ea0 net: xilinx_ethlite: Convert to realize()
SysBusDevice::init is depracated. Convert to Object::init and
Device::realize as prescribed by QOM conventions.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
2014-06-09 00:33:03 +02:00
Peter Crosthwaite
8c6d96728d net: xilinx_ethlite: Don't reset from init
This zeroing-out of the rxbuf variable (ping pong state) is a reset
side effect. Extract into a proper reset.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
2014-06-09 00:33:03 +02:00
Peter Crosthwaite
04bb4d86f1 timer: xilinx_timer: Convert to realize()
SysBusDevice::init is depracated. Convert to Object::init and
Device::realize as prescribed by QOM conventions.

Signed-off-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
2014-06-09 00:33:02 +02:00
Benoît Canet
2e95fa1719 qapi: Extract qapi/block.json definitions
Signed-off-by: Benoit Canet <benoit@irqsave.net>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-06 16:25:48 +02:00
Benoît Canet
1ad166b612 qapi: Extract qapi/block-core.json definitions
Signed-off-by: Benoit Canet <benoit@irqsave.net
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-06 16:25:48 +02:00
Benoît Canet
5db15096d0 qapi: create two block related json modules
qapi/block-core.json contains block definitions unrelated to emulation.

qapi/block.json is a superset of the previous and contains definitions related
to emulation.

The purpose of these extractions is to be able to hook qapi/block-core.json
generated code on qemu-nbd.

Signed-off-by: Benoit Canet <benoit@irqsave.net>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-06 16:25:48 +02:00
Benoît Canet
d34bda716a qapi: Extract qapi/common.json definitions
Signed-off-by: Benoit Canet <benoit@irqsave.net>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-06 16:25:48 +02:00
Hitoshi Mitake
5d039baba4 sheepdog: reload only header in a case of live snapshot
sheepdog driver doesn't need to read data_vdi_id[] when a live snapshot is
created.

Cc: Kevin Wolf <kwolf@redhat.com>
Cc: Stefan Hajnoczi <stefanha@redhat.com>
Cc: Liu Yuan <namei.unix@gmail.com>
Cc: MORITA Kazutaka <morita.kazutaka@lab.ntt.co.jp>
Signed-off-by: Hitoshi Mitake <mitake.hitoshi@lab.ntt.co.jp>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-06 14:54:43 +02:00
Hitoshi Mitake
b544c1aba8 sheepdog: fix vdi object update after live snapshot
sheepdog driver should decide a write request is COW or not based on inode
object which is active when the write request is issued.

Example of wrong inode update path in the previous driver:
1. drier issues an ordinal write request to an existing object
2. user creates a snapshot of the VDI before the write request is completed
3. the respones for the request is RDONLY, because the VDI is already a snapshot
4. the driver reload an inode object of the new active VDI, then issues a write
   request again
5. the second write request can be completed
6. driver decide the request is COW or not with the below conditional branch:
   	  if (s->inode.data_vdi_id[idx] != s->inode.vdi_id) {
7. the ID of the written object and VID of the new active VDI is different, so
   the driver updates data_vdi_id[idx] and writes inode object
8. the existing object cannot be seen by the new active VDI, it results object
   leaking

Cc: Kevin Wolf <kwolf@redhat.com>
Cc: Stefan Hajnoczi <stefanha@redhat.com>
Cc: Liu Yuan <namei.unix@gmail.com>
Cc: MORITA Kazutaka <morita.kazutaka@lab.ntt.co.jp>
Signed-off-by: Hitoshi Mitake <mitake.hitoshi@lab.ntt.co.jp>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-06 14:53:55 +02:00
Kevin Wolf
405a27640b rbd: Fix leaks in rbd_start_aio() error path
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-06 11:05:04 +02:00
Peter Maydell
50809c8b92 Merge remote-tracking branch 'remotes/mcayland/qemu-sparc' into staging
* remotes/mcayland/qemu-sparc:
  apb: implement IOMMU translation for PCI host bridge
  apb: handle reading/writing of IOMMU control registers
  apb: fix IOMMU register sizes
  apb: Move IOMMU registers into a separate IOMMUState struct
  tcx: move initialisation from realizefn to initfn
  tcx: move initialisation from SysBusDevice class to TCX class realizefn
  cg3: add extra check to prevent CG3 register array overflow
  cg3: move initialisation from realizefn to initfn

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-05 23:05:07 +01:00
Peter Maydell
4e627aeef8 Merge remote-tracking branch 'remotes/mdroth/qga-pull-2014-06-05' into staging
* remotes/mdroth/qga-pull-2014-06-05:
  qga: Fix handle fd leak in acquire_privilege()

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-05 22:40:44 +01:00
Peter Maydell
26edf8cc08 Merge remote-tracking branch 'remotes/mst/tags/for_upstream' into staging
pc,pci,virtio,qdev fixes, tests

new tests for SMBIOS
SMBIOS fixes
pc, pci fixes
qdev patches stayed on list for a month with no review,
as I told people on KVM forum I'm merging stuch patches
if they look fine.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>

* remotes/mst/tags/for_upstream:
  qdev: Add test of qdev_prop_check_global
  qdev: Display warning about unused -global
  tests: add smbios testing
  tests: rename acpi-test to bios-tables-test
  virtio-balloon: return empty data when no stats are available
  pcie_host: Turn pcie_host_init() into an instance_init
  SMBIOS: Fix type 17 field sizes
  SMBIOS: Update Type 0 struct generator for machines >= 2.1
  SMBIOS: Fix endian-ness when populating multi-byte fields
  serial-pci: Set prog interface field of pci config to 16550 compatible

Conflicts:
	include/hw/i386/pc.h
[PMM: fixed trivial conflict in pc.h]
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-05 21:52:37 +01:00
Peter Maydell
31e25e3e57 Merge remote-tracking branch 'remotes/bonzini/softmmu-smap' into staging
* remotes/bonzini/softmmu-smap: (33 commits)
  target-i386: cleanup x86_cpu_get_phys_page_debug
  target-i386: fix protection bits in the TLB for SMEP
  target-i386: support long addresses for 4MB pages (PSE-36)
  target-i386: raise page fault for reserved bits in large pages
  target-i386: unify reserved bits and NX bit check
  target-i386: simplify pte/vaddr calculation
  target-i386: raise page fault for reserved physical address bits
  target-i386: test reserved PS bit on PML4Es
  target-i386: set correct error code for reserved bit access
  target-i386: introduce support for 1 GB pages
  target-i386: introduce do_check_protect label
  target-i386: tweak handling of PG_NX_MASK
  target-i386: commonize checks for PAE and non-PAE
  target-i386: commonize checks for 4MB and 4KB pages
  target-i386: commonize checks for 2MB and 4KB pages
  target-i386: fix coding standards in x86_cpu_handle_mmu_fault
  target-i386: simplify SMAP handling in MMU_KSMAP_IDX
  target-i386: fix kernel accesses with SMAP and CPL = 3
  target-i386: move check_io helpers to seg_helper.c
  target-i386: rename KSMAP to KNOSMAP
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-05 21:06:14 +01:00
Mark Cave-Ayland
ae74bbe7c5 apb: implement IOMMU translation for PCI host bridge
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
2014-06-05 21:00:22 +01:00
Mark Cave-Ayland
f38b161203 apb: handle reading/writing of IOMMU control registers
While the registers are documented as being 64-bit, Linux seems to access
them in two halves as 2 x 32-bit accesses. Make sure that we can correctly
handle this case.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
2014-06-05 21:00:12 +01:00
Mark Cave-Ayland
fd7fbc8ff7 apb: fix IOMMU register sizes
According to the referenced documentation, the IOMMU has 3 64-bit registers
consisting of a control register, base register and flush register.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
2014-06-05 21:00:03 +01:00
Mark Cave-Ayland
ea9a6606b1 apb: Move IOMMU registers into a separate IOMMUState struct
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
2014-06-05 20:59:53 +01:00
Mark Cave-Ayland
01b91ac2be tcx: move initialisation from realizefn to initfn
Initialisation cleanup as suggested by Andreas.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
CC: Andreas Färber <afaerber@suse.de>
2014-06-05 20:51:57 +01:00
Mark Cave-Ayland
d4ad9dec14 tcx: move initialisation from SysBusDevice class to TCX class realizefn
This is an intermediate step to bring TCX in line with CG3.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
CC: Andreas Färber <afaerber@suse.de>
2014-06-05 20:51:45 +01:00
Mark Cave-Ayland
366d4f7e00 cg3: add extra check to prevent CG3 register array overflow
The case statements in the CG3 read and write register routines have a maximum
value of CG3_REG_SIZE, so if a value were written to this offset then it
would overflow the register array.

Currently this cannot be exploited since the MemoryRegion restricts accesses
to the range 0 ... CG3_REG_SIZE - 1, but it seems worth clarifying this for
future review and/or static analysis.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
CC: Paolo Bonzini <pbonzini@redhat.com>
2014-06-05 20:51:30 +01:00
Mark Cave-Ayland
e09c49f40d cg3: move initialisation from realizefn to initfn
Initialisation cleanup as suggested by Andreas.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
CC: Andreas Färber <afaerber@suse.de>
2014-06-05 20:51:19 +01:00
Peter Maydell
9d48d3f01c Merge remote-tracking branch 'remotes/rth/tcg-next' into staging
* remotes/rth/tcg-next:
  TCG: Fix tcg_gen_extr_i64_tl for 32bit
  tcg: Remove TCG_TARGET_HAS_new_ldst
  tci: Convert to new ldst opcodes
  tcg-i386: Fix win64 qemu store

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-05 20:11:50 +01:00
Peter Maydell
9f0355b590 Merge remote-tracking branch 'remotes/kvm/uq/master' into staging
* remotes/kvm/uq/master:
  kvm: Fix eax for cpuid leaf 0x40000000
  kvmclock: Ensure proper env->tsc value for kvmclock_current_nsec calculation
  kvm: Enable -cpu option to hide KVM
  kvm: Ensure negative return value on kvm_init() error handling path
  target-i386: set CC_OP to CC_OP_EFLAGS in cpu_load_eflags
  target-i386: get CPL from SS.DPL
  target-i386: rework CPL checks during task switch, preparing for next patch
  target-i386: fix segment flags for SMM and VM86 mode
  target-i386: Fix vm86 mode regression introduced in fd460606fd.
  kvm_stat: allow choosing between tracepoints and old stats
  kvmclock: Ensure time in migration never goes backward

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-05 19:16:28 +01:00
Peter Maydell
d4f005db9b Merge remote-tracking branch 'remotes/kraxel/tags/pull-input-10' into staging
updates for docs/multiseat.txt
input: add support for kbd delays

# gpg: Signature made Wed 04 Jun 2014 08:22:39 BST using RSA key ID D3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>"
# gpg:                 aka "Gerd Hoffmann <gerd@kraxel.org>"
# gpg:                 aka "Gerd Hoffmann (private) <kraxel@gmail.com>"

* remotes/kraxel/tags/pull-input-10:
  docs/multiseat.txt: add note about spice
  docs/multiseat.txt: gtk joined the party
  docs/multiseat.txt: use autoseat
  input/vnc: use kbd delays in press_key
  input/curses: add kbd delay between keydown and keyup events
  input: use kbd delays for send_key monitor command
  input: add support for kbd delays

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
2014-06-05 18:58:53 +01:00
Don Slutz
711e2f1e9e qdev: Add test of qdev_prop_check_global
This will generate a warning from "make check":

...
GTESTER tests/test-qdev-global-props
Warning: "-global dynamic-prop-type-bad.prop3=103" not used
GTESTER tests/check-qom-interface
...

If the warning is not generated, the test will fail.

Signed-off-by: Don Slutz <dslutz@verizon.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
2014-06-05 19:20:38 +03:00
Don Slutz
9f9260a3be qdev: Display warning about unused -global
This can help a user understand why -global was ignored.

For example: with "-vga cirrus"; "-global vga.vgamem_mb=16" is just
ignored when "-global cirrus-vga.vgamem_mb=16" is not.

This is currently clear when the wrong property is provided:

out/x86_64-softmmu/qemu-system-x86_64 -global cirrus-vga.vram_size_mb=16 -monitor pty -vga cirrus
char device redirected to /dev/pts/20 (label compat_monitor0)
qemu-system-x86_64: Property '.vram_size_mb' not found
Aborted (core dumped)

vs

out/x86_64-softmmu/qemu-system-x86_64 -global vga.vram_size_mb=16 -monitor pty -vga cirrus
char device redirected to /dev/pts/20 (label compat_monitor0)
VNC server running on `::1:5900'
^Cqemu: terminating on signal 2

Signed-off-by: Don Slutz <dslutz@verizon.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
2014-06-05 19:20:37 +03:00
Paolo Bonzini
16b96f82cd target-i386: cleanup x86_cpu_get_phys_page_debug
Make the code a bit more similar to x86_cpu_handle_mmu_fault.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-05 16:10:35 +02:00
Paolo Bonzini
b09481de91 target-i386: fix protection bits in the TLB for SMEP
User pages must be marked as non-executable when running under SMEP;
otherwise, fetching the page first and then calling it will fail.

With this patch, all SMEP testcases in kvm-unit-tests now pass.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-05 16:10:35 +02:00
Paolo Bonzini
de431a655a target-i386: support long addresses for 4MB pages (PSE-36)
4MB pages can use 40-bit addresses by putting the higher 8 bits in bits
20-13 of the PDE.  Bit 21 is reserved.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-05 16:10:35 +02:00
Paolo Bonzini
eaad03e472 target-i386: raise page fault for reserved bits in large pages
In large pages, bit 12 is for PAT, but bits starting at 13 are reserved.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-05 16:10:35 +02:00
Paolo Bonzini
e2a32ebbfe target-i386: unify reserved bits and NX bit check
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-05 16:10:34 +02:00
Paolo Bonzini
e7e898a76a target-i386: simplify pte/vaddr calculation
They can moved to after the dirty bit processing, and unified between
CR0.PG=1 and CR0.PG=0.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-05 16:10:34 +02:00
Paolo Bonzini
e8f6d00c30 target-i386: raise page fault for reserved physical address bits
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-05 16:10:34 +02:00
Paolo Bonzini
b728464ae8 target-i386: test reserved PS bit on PML4Es
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-05 16:10:34 +02:00
Paolo Bonzini
c1eb2fa3fd target-i386: set correct error code for reserved bit access
The correct error code is 9 (present, reserved), not 8.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-05 16:10:34 +02:00
Paolo Bonzini
77549a7809 target-i386: introduce support for 1 GB pages
Given the simplifications to the code in the previous patches, this
is now very simple to do.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-05 16:10:34 +02:00
Paolo Bonzini
b052e4509b target-i386: introduce do_check_protect label
This will help adding 1GB page support in the next patch.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-05 16:10:34 +02:00
Paolo Bonzini
870a706735 target-i386: tweak handling of PG_NX_MASK
Remove the tail of the PAE case, so that we can use "goto" in the
next patch to jump to the protection checks.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-05 16:10:34 +02:00
Paolo Bonzini
7c82256006 target-i386: commonize checks for PAE and non-PAE
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-05 16:10:34 +02:00
Paolo Bonzini
487cad8853 target-i386: commonize checks for 4MB and 4KB pages
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-05 16:10:34 +02:00
Paolo Bonzini
00cc3e1d70 target-i386: commonize checks for 2MB and 4KB pages
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-05 16:10:34 +02:00
Paolo Bonzini
843408b3cf target-i386: fix coding standards in x86_cpu_handle_mmu_fault
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-05 16:10:34 +02:00
Paolo Bonzini
f57584dc87 target-i386: simplify SMAP handling in MMU_KSMAP_IDX
Do not use this MMU index at all if CR4.SMAP is false, and drop
the SMAP check from x86_cpu_handle_mmu_fault.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-05 16:10:34 +02:00
Paolo Bonzini
8a201bd47e target-i386: fix kernel accesses with SMAP and CPL = 3
With SMAP, implicit kernel accesses from user mode always behave as
if AC=0.  To do this, kernel mode is not anymore a separate MMU mode.
Instead, KERNEL_IDX is renamed to KSMAP_IDX and the kernel mode accessors
wrap KSMAP_IDX and KNOSMAP_IDX.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-05 16:10:34 +02:00
Paolo Bonzini
81cf8d8adc target-i386: move check_io helpers to seg_helper.c
Prepare for adding _kernel accessors there in the next patch.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-05 16:10:34 +02:00
Paolo Bonzini
43773ed369 target-i386: rename KSMAP to KNOSMAP
This is the mode where SMAP is overridden, put "NO" in its name.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-05 16:10:34 +02:00
Paolo Bonzini
c773828aa9 softmmu: move all load/store functions to cpu_ldst.h
Unify pieces of cpu-all.h, exec-all.h, softmmu_exec.h and tcg/tcg.h
into a single new header file with all helpers.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-05 16:10:33 +02:00
Paolo Bonzini
f08b617018 softmmu: introduce cpu_ldst.h
This will collect all load and store helpers soon.  For now
it is just a replacement for softmmu_exec.h, which this patch
stops including directly, but we also include it where this will
be necessary in order to simplify the next patch.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-05 16:10:33 +02:00
Paolo Bonzini
1d854765df target-arm: move arm_*_code to a separate file
These will soon require cpu_ldst.h, so move them out of cpu.h.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-05 16:10:33 +02:00
Paolo Bonzini
58ed270df9 softmmu: move softmmu_template.h out of include/
It is only included in cputlb.c now.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-05 16:10:33 +02:00
Paolo Bonzini
0f590e749f softmmu: commonize helper definitions
They do not need to be in op_helper.c.  Because cputlb.c now includes
softmmu_template.h twice for each size, io_readX must be elided the
second time through.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-05 16:10:33 +02:00
Paolo Bonzini
d94f0a8ecb softmmu: move ALIGNED_ONLY to cpu.h
Prepare for moving softmmu_header.h inclusion out of .c files

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-05 16:10:33 +02:00
Paolo Bonzini
93e22326d6 softmmu: make do_unaligned_access a method of CPU
We will reference it from more files in the next patch.  To avoid
ruining the small steps we're making towards multi-target, make
it a method of CPU rather than just a global.

Reviewed-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-05 16:10:31 +02:00
Paolo Bonzini
ca0aa40816 softmmu: move definition of CPU_MMU_INDEX to inclusion site, drop ACCESS_TYPE
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-05 16:05:52 +02:00
Paolo Bonzini
a6c9eac0d5 softmmu: move MMUSUFFIX under SOFTMMU_CODE_ACCESS
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-05 16:05:47 +02:00
Paolo Bonzini
859d76120b softmmu: start introducing SOFTMMU_CODE_ACCESS in softmmu_header.h
This preprocessor symbol is already used in softmmu_template.h.  We
will use it to distinguish the two "fake" ACCESS_TYPEs
NB_MMU_MODES and NB_MMU_MODES + 1.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-05 16:05:27 +02:00
Paolo Bonzini
0983979b3a hw: use ld_p/st_p instead of ld_raw/st_raw
The ld_raw and st_raw definitions are only needed in code that
must compile for both user-mode and softmmu emulation.  Device
models can use the equivalent ld_p/st_p which are simple
pointer accessors.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-05 16:04:17 +02:00
Paolo Bonzini
fddbd80cc9 nseries: clean up coding style
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-05 16:03:53 +02:00
Stefan Weil
7e4e88656c cputlb: Fix regression with TCG interpreter (bug 1310324)
Commit 0f842f8a24 replaced GETPC_EXT() which
was derived from GETPC() by GETRA_EXT() without fixing cputlb.c. A later
patch replaced GETRA_EXT() by GETRA() in exec/softmmu_template.h which
is included in cputlb.c.

The TCG interpreter failed because the values returned by GETRA() were no
longer explicitly set to 0. The redefinition of GETRA() introduced here
fixes this.

In addition, GETPC_ADJ which is also used in exec/softmmu_template.h is
set to 0. Both changes reduce the compiled code size for cputlb.c by more
than 100 bytes, so the normal TCG without interpreter also profits from
the reduced code size and slightly faster code.

Cc: qemu-stable@nongnu.org
Reported-by: Giovanni Mascellani <gio@debian.org>
Signed-off-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-05 16:03:37 +02:00
Alexander Graf
e3eb9806c7 TCG: Fix tcg_gen_extr_i64_tl for 32bit
We expose a generic helper "tcg_gen_extr_i64_tl" for 64bit targets, but the
same function for 32bit targets is a misnomer and refers to an invalid function
name.

Fix up the definition to point to the correct internal helper names instead.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-06-04 14:11:45 -07:00
Richard Henderson
3d1b2ff62c tcg: Remove TCG_TARGET_HAS_new_ldst
Since all backends have been converted, remove the compatibility code.

Acked-by: Claudio Fontana <claudio.fontana@huawei.com>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-06-04 14:10:26 -07:00
Richard Henderson
76782fab1c tci: Convert to new ldst opcodes
Tested-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-06-04 14:10:16 -07:00
Richard Henderson
0b91966730 tcg-i386: Fix win64 qemu store
The first non-register argument isn't placed at offset 0.

Cc: qemu-stable@nongnu.org
Reviewed-by: Stefan Weil <sw@weilnetz.de>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2014-06-04 13:58:39 -07:00
Max Reitz
d6635c4dbb qemu-img: Document check exit codes
The exit code 63 (check not supported by image format) was not even
documented in the comment above the check command in the source code;
add it, as it does indeed seem useful.

Also, document all of check's exit codes in the manpage.

Signed-off-by: Max Reitz <mreitz@redhat.com>
Reported-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-04 11:30:32 +02:00
chai wen
1ac362cdbd block: fix wrong order in live block migration setup
The function init_blk_migration is better to be called before
set_dirty_tracking as the reasons below.

If we want to track dirty blocks via dirty_maps on a BlockDriverState
when doing live block-migration, its correspoding 'BlkMigDevState' should be
added to block_mig_state.bmds_list first for subsequent processing.
Otherwise set_dirty_tracking will do nothing on an empty list than allocating
dirty_bitmaps for them. And bdrv_get_dirty_count will access the
bmds->dirty_maps directly, then there would be a segfault triggered.

If the set_dirty_tracking fails, qemu_savevm_state_cancel will handle
the cleanup of init_blk_migration automatically.

Reviewed-by: Fam Zheng <famz@redhat.com>
Signed-off-by: chai wen <chaiw.fnst@cn.fujitsu.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-04 11:22:39 +02:00
Stefan Hajnoczi
b15446fdbf blockdev: acquire AioContext in block_set_io_throttle
The block_set_io_throttle QMP and HMP commands modify I/O throttling
limits for block devices.

Acquire the BlockDriverState's AioContext to protect against race
conditions with an IOThread that is running I/O for this device.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
2014-06-04 09:56:12 +02:00
Stefan Hajnoczi
22524f7262 throttle: add detach/attach test case
Add a test case that checks the timer is really removed/added by the
detach/attach functions.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
2014-06-04 09:56:12 +02:00
Stefan Hajnoczi
13af91ebf0 throttle: add throttle_detach/attach_aio_context()
Block I/O throttling uses timers and currently always adds them to the
main loop.  Throttling will break if bdrv_set_aio_context() is used to
move a BlockDriverState to a different AioContext.

This patch adds throttle_detach/attach_aio_context() interfaces so the
throttling timers and uses them to move timers to the new AioContext.
Note that bdrv_set_aio_context() already drains all requests so we're
sure no throttled requests are pending.

The test cases need to be updated since the throttle_init() interface
has changed.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
2014-06-04 09:56:12 +02:00
Fam Zheng
c9f87b20b9 dataplane: Support VIRTIO_BLK_T_SCSI_CMD
Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-04 09:56:12 +02:00
Fam Zheng
5a05cbeeaa virtio-blk: Factor out virtio_blk_handle_scsi_req from virtio_blk_handle_scsi
The common logic to process a scsi request in a VirtQueueElement is
extracted to a function to share with dataplane.

This makes VirtIOBlockReq.scsi unused, so drop it.

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-04 09:56:12 +02:00
Fam Zheng
6d7e73d62f virtio-blk: Allow config-wce in dataplane
Dataplane now uses block layer. Protect bdrv_set_enable_write_cache with
aio_context_acquire and aio_context_release, so we can enable config-wce
to allow guest to modify the write cache online.

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-04 09:56:12 +02:00
Fam Zheng
db519cba87 block: Move declaration of bdrv_get_aio_context to block.h
block_int.h is for block layer and block drivers, other code shouldn't
include it. But similar to bdrv_set_aio_context, bdrv_get_aio_context
should also be accessible from outside of block layer.

Move it.

Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-04 09:56:12 +02:00
Stefan Hajnoczi
76ef2cf549 raw-posix: drop raw_get_aio_fd() since it is no longer used
virtio-blk data-plane now uses the QEMU block layer for I/O.  We do not
need raw_get_aio_fd() anymore.  It was a layering violation anyway, so
let's get rid of it.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-04 09:56:12 +02:00
Stefan Hajnoczi
8d242f0ed5 dataplane: implement async flush
Stop using the raw-posix file descriptor for synchronous
qemu_fdatasync().  Use bdrv_aio_flush() instead and drop the
VirtIOBlockDataPlane->fd field.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-04 09:56:12 +02:00
Stefan Hajnoczi
0d6ecec252 dataplane: delete IOQueue since it is no longer used
This custom Linux AIO request queue is no longer used by virtio-blk
data-plane.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-04 09:56:12 +02:00
Stefan Hajnoczi
580b6b2aa2 dataplane: use the QEMU block layer for I/O
Stop using a custom Linux AIO request queue from ioq.h and instead use
the QEMU block layer for I/O.

This patch adjusts the VirtIOBlockRequest struct with fields needed for
bdrv_aio_readv()/bdrv_aio_writev().  ioq.h used struct iovec and struct
iocb, which we don't need directly anymore.

Modify dataplane start/stop to set the AioContext on the
BlockDriverState.  We also no longer need to get the raw-posix file
descriptor.  This means image formats are now supported with dataplane!

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-04 09:56:12 +02:00
Stefan Hajnoczi
c75f3bdf46 vmdk: implement .bdrv_detach/attach_aio_context()
Implement .bdrv_detach/attach_aio_context() interfaces to propagate
detach/attach to BDRVVmdkState->extents[].file.  The block layer takes
care of ->file and ->backing_hd but doesn't know about our extents
BlockDriverStates, which is also part of the graph.

Reviewed-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-04 09:56:12 +02:00
Stefan Hajnoczi
2af0b20056 ssh: use BlockDriverState's AioContext
Drop the assumption that we're using the main AioContext.  Use
bdrv_get_aio_context() to register fd handlers in the right AioContext
for this BlockDriverState.

The .bdrv_detach_aio_context() and .bdrv_attach_aio_context() interfaces
are not needed since no fd handlers, timers, or BHs stay registered when
requests have been drained.

For now this doesn't make much difference but will allow ssh to work in
IOThread instances in the future.

Acked-by: Richard W.M. Jones <rjones@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-04 09:56:12 +02:00
Stefan Hajnoczi
84390bed59 sheepdog: implement .bdrv_detach/attach_aio_context()
Drop the assumption that we're using the main AioContext.  Convert
qemu_aio_set_fd_handler() to aio_set_fd_handler() and qemu_aio_wait() to
aio_poll().

The .bdrv_detach/attach_aio_context() interfaces also need to be
implemented to move the socket fd handler from the old to the new
AioContext.

Cc: MORITA Kazutaka <morita.kazutaka@lab.ntt.co.jp>
Acked-by: Liu Yuan <namei.unix@gmail.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-04 09:56:12 +02:00
Stefan Hajnoczi
ea80019149 rbd: use BlockDriverState's AioContext
Drop the assumption that we're using the main AioContext.  Convert
qemu_bh_new() to aio_bh_new() and qemu_aio_wait() to aio_poll().

The .bdrv_detach_aio_context() and .bdrv_attach_aio_context() interfaces
are not needed since no fd handlers, timers, or BHs stay registered when
requests have been drained.

Cc: Josh Durgin <josh.durgin@inktank.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Josh Durgin <josh.durgin@inktank.com>
2014-06-04 09:56:12 +02:00
Stefan Hajnoczi
85ebd381fd block/raw-win32: implement .bdrv_detach/attach_aio_context()
Drop the assumption that we're using the main AioContext for raw-win32.
Convert the aio-win32 code to support detach/attach and replace
qemu_aio_wait() with aio_poll().

The .bdrv_detach/attach_aio_context() interfaces move the aio-win32
event notifier from the old to the new AioContext.

Cc: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-04 09:56:12 +02:00
Stefan Hajnoczi
99cc598924 block/raw-win32: create one QEMUWin32AIOState per BDRVRawState
Each QEMUWin32AIOState event notifier is associated with an AioContext.
Since BlockDriverState instances can use different AioContexts we cannot
continue to use a global QEMUWin32AIOState.

Let each BDRVRawState have its own QEMUWin32AIOState and free it when
BDRVRawState is closed.

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-04 09:56:12 +02:00
Stefan Hajnoczi
abd269b7cf block/linux-aio: fix memory and fd leak
Hot unplugging -drive aio=native,file=test.img,format=raw images leaves
the Linux AIO event notifier and struct qemu_laio_state allocated.
Luckily nothing will use the event notifier after the BlockDriverState
has been closed so the handler function is never called.

It's still worth fixing this resource leak.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-04 09:56:11 +02:00
Stefan Hajnoczi
c2f3426c9b block/raw-posix: implement .bdrv_detach/attach_aio_context()
Drop the assumption that we're using the main AioContext for Linux AIO.
Convert the Linux AIO event notifier to use aio_set_event_notifier().

The .bdrv_detach/attach_aio_context() interfaces also need to be
implemented to move the event notifier handler from the old to the new
AioContext.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-04 09:56:11 +02:00
Stefan Hajnoczi
e3625d3d6a quorum: implement .bdrv_detach/attach_aio_context()
Implement .bdrv_detach/attach_aio_context() interfaces to propagate
detach/attach to BDRVQuorumState->bs[] children.  The block layer takes
care of ->file and ->backing_hd but doesn't know about our ->bs[]
BlockDriverStates, which is also part of the graph.

Reviewed-by: Benoît Canet <benoit.canet@irqsave.net>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-04 09:56:11 +02:00
Stefan Hajnoczi
a8c868c386 qed: use BlockDriverState's AioContext
Drop the assumption that we're using the main AioContext.  Convert
qemu_bh_new() to aio_bh_new() and qemu_aio_wait() to aio_poll() so we're
using the BlockDriverState's AioContext.

Implement .bdrv_detach/attach_aio_context() interfaces to move the
QED_F_NEED_CHECK timer from the old AioContext to the new one.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-04 09:56:11 +02:00
Stefan Hajnoczi
471799d135 nfs: implement .bdrv_detach/attach_aio_context()
Drop the assumption that we're using the main AioContext.  The following
functions need to be converted:
 * qemu_bh_new() -> aio_bh_new()
 * qemu_aio_set_fd_handler() -> aio_set_fd_handler()
 * qemu_aio_wait() -> aio_poll()

The .bdrv_detach/attach_aio_context() interfaces also need to be
implemented to move the fd handler from the old to the new AioContext.

Cc: Peter Lieven <pl@kamp.de>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Peter Lieven <pl@kamp.de>
2014-06-04 09:56:11 +02:00
Stefan Hajnoczi
69447cd8f3 nbd: implement .bdrv_detach/attach_aio_context()
Drop the assumption that we're using the main AioContext.  Convert
qemu_aio_set_fd_handler() calls to aio_set_fd_handler().

The .bdrv_detach/attach_aio_context() interfaces also need to be
implemented to move the socket fd handler from the old to the new
AioContext.

Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-04 09:56:11 +02:00
Stefan Hajnoczi
80cf625766 iscsi: implement .bdrv_detach/attach_aio_context()
Drop the assumption that we're using the main AioContext for Linux
AIO.  Convert qemu_aio_set_fd_handler() to aio_set_fd_handler() and
timer_new_ms() to aio_timer_new().

The .bdrv_detach/attach_aio_context() interfaces also need to be
implemented to move the fd and timer from the old to the new AioContext.

Cc: Peter Lieven <pl@kamp.de>
Cc: Ronnie Sahlberg <ronniesahlberg@gmail.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Peter Lieven <pl@kamp.de>
2014-06-04 09:56:11 +02:00
Stefan Hajnoczi
6ee50af24b gluster: use BlockDriverState's AioContext
Drop the assumption that we're using the main AioContext.  Use
aio_bh_new() instead of qemu_bh_new().

The .bdrv_detach_aio_context() and .bdrv_attach_aio_context() interfaces
are not needed since no fd handlers, timers, or BHs stay registered when
requests have been drained.

Cc: Bharata B Rao <bharata@linux.vnet.ibm.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-04 09:56:11 +02:00
Stefan Hajnoczi
63f0f45f2e curl: implement .bdrv_detach/attach_aio_context()
The curl block driver uses fd handlers, timers, and BHs.  The fd
handlers and timers are managed on behalf of libcurl, which controls
them using callback functions that the block driver implements.

The simplest way to implement .bdrv_detach/attach_aio_context() is to
clean up libcurl in the old event loop and initialize it again in the
new event loop.  We do not need to keep track of anything since there
are no pending requests when the AioContext is changed.

Also make sure to use aio_set_fd_handler() instead of
qemu_aio_set_fd_handler() and aio_bh_new() instead of qemu_bh_new() so
the current AioContext is passed in.

Cc: Alexander Graf <agraf@suse.de>
Cc: Fam Zheng <famz@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
2014-06-04 09:56:11 +02:00
Stefan Hajnoczi
9d94020bc6 blkverify: implement .bdrv_detach/attach_aio_context()
Drop the assumption that we're using the main AioContext.  Convert
qemu_bh_new() to aio_bh_new() and qemu_aio_wait() to aio_poll() so we
use the BlockDriverState's AioContext.

Implement .bdrv_detach/attach_aio_context() interfaces to propagate
detach/attach to BDRVBlkverifyState->test_file.  The block layer takes
care of ->file and ->backing_hd but doesn't know about our ->test_file
BlockDriverState, which is also part of the graph.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-04 09:56:11 +02:00
Stefan Hajnoczi
7e1efdf0a3 blkdebug: use BlockDriverState's AioContext
Drop the assumption that we're using the main AioContext.  Convert
qemu_bh_new() to aio_bh_new() so we use the BlockDriverState's
AioContext.

The .bdrv_detach_aio_context() and .bdrv_attach_aio_context() interfaces
are not needed since no fd handlers, timers, or BHs stay registered when
requests have been drained.

Cc: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-04 09:56:11 +02:00
Stefan Hajnoczi
dcd042282d block: add bdrv_set_aio_context()
Up until now all BlockDriverState instances have used the QEMU main loop
for fd handlers, timers, and BHs.  This is not scalable on SMP guests
and hosts so we need to move to a model with multiple event loops on
different host CPUs.

bdrv_set_aio_context() assigns the AioContext event loop to use for a
particular BlockDriverState.  It first detaches the entire
BlockDriverState graph from the current AioContext and then attaches to
the new AioContext.

This function will be used by virtio-blk data-plane to assign a
BlockDriverState to its IOThread AioContext.  Make
bdrv_aio_set_context() public since data-plane should not include
block_int.h.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-04 09:56:11 +02:00
Stefan Hajnoczi
9b536adcbe block: acquire AioContext in bdrv_drain_all()
Modify bdrv_drain_all() to take into account that BlockDriverState
instances may be running in different AioContexts.

This patch changes the implementation of bdrv_drain_all() while
preserving the semantics.  Previously kicking throttled requests and
checking for pending requests were done across all BlockDriverState
instances in sequence.  Now we process each BlockDriverState in turn,
making sure to acquire and release its AioContext.

This prevents race conditions between the thread executing
bdrv_drain_all() and the thread running the AioContext.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-04 09:56:11 +02:00
Stefan Hajnoczi
ed78cda3de block: acquire AioContext in bdrv_*_all()
bdrv_close_all(), bdrv_commit_all(), bdrv_flush_all(),
bdrv_invalidate_cache_all(), and bdrv_clear_incoming_migration_all() are
called by main loop code and touch all BlockDriverState instances.

Some BlockDriverState instances may be running in another AioContext.
Make sure to acquire the AioContext before closing the BlockDriverState.

This will protect against race conditions once virtio-blk data-plane is
using the BlockDriverState from another AioContext event loop.

Note that this patch does not convert bdrv_drain_all() yet since that
conversion is non-trivial.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-04 09:56:11 +02:00
Stefan Hajnoczi
2572b37a47 block: use BlockDriverState AioContext
Drop the assumption that we're using the main AioContext.  Convert
qemu_aio_wait() to aio_poll() and qemu_bh_new() to aio_bh_new() so the
BlockDriverState AioContext is used.

Note there is still one qemu_aio_wait() left in bdrv_create() but we do
not have a BlockDriverState there and only main loop code invokes this
function.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2014-06-04 09:56:11 +02:00
Stefan Hajnoczi
924fe1293c aio: fix qemu_bh_schedule() bh->ctx race condition
qemu_bh_schedule() is supposed to be thread-safe at least the first time
it is called.  Unfortunately this is not quite true:

  bh->scheduled = 1;
  aio_notify(bh->ctx);

Since another thread may run the BH callback once it has been scheduled,
there is a race condition if the callback frees the BH before
aio_notify(bh->ctx) has a chance to run.

Reported-by: Stefan Priebe <s.priebe@profihost.ag>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Tested-by: Stefan Priebe <s.priebe@profihost.ag>
2014-06-04 09:56:06 +02:00
Jidong Xiao
79b6f2f651 kvm: Fix eax for cpuid leaf 0x40000000
Since Linux kernel 3.5, KVM has documented eax for leaf 0x40000000
to be KVM_CPUID_FEATURES:

57c22e5f35

But qemu still tries to set it to 0. It would be better to make qemu
and kvm consistent. This patch just fixes this issue.

Signed-off-by: Jidong Xiao <jidong.xiao@gmail.com>
[Include kvm_base in the value. - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-04 09:12:04 +02:00
Gonglei
374044f08f qga: Fix handle fd leak in acquire_privilege()
token should be closed in all conditions.
So move CloseHandle(token) to "out" branch.

Signed-off-by: Wang Rui <moon.wangrui@huawei.com>
Signed-off-by: Gonglei <arei.gonglei@huawei.com>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
2014-06-03 15:07:59 -05:00
Marcelo Tosatti
9b1786829a kvmclock: Ensure proper env->tsc value for kvmclock_current_nsec calculation
Ensure proper env->tsc value for kvmclock_current_nsec calculation.

Reported-by: Marcin Gibuła <m.gibula@beyond.pl>
Cc: qemu-stable@nongnu.org
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-03 18:40:48 +02:00
Alex Williamson
f522d2acc5 kvm: Enable -cpu option to hide KVM
The latest Nvidia driver (337.88) specifically checks for KVM as the
hypervisor and reports Code 43 for the driver in a Windows guest when
found.  Removing or changing the KVM signature is sufficient for the
driver to load and work.  This patch adds an option to easily allow
the KVM hypervisor signature to be hidden using '-cpu kvm=off'.  We
continue to expose KVM via the cpuid value by default.  The state of
this option does not supercede or replace -enable-kvm or the accel=kvm
machine option.  This only changes the visibility of KVM to the guest
and paravirtual features specifically tied to the KVM cpuid.

Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-06-03 18:40:48 +02:00
Eduardo Habkost
0e1dac6c41 kvm: Ensure negative return value on kvm_init() error handling path
We need to ensure ret < 0 when going through the error path, or QEMU may
try to run the half-initialized VM and crash.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-05-30 22:28:55 +02:00
Gabriel L. Somlo
eb386aaccc tests: add smbios testing
Add tests to find and verify the smbios entry point structure,
and to walk and perform checks on the actual smbios tables.

Suggested-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Gabriel Somlo <somlo@cmu.edu>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2014-05-27 23:42:16 +03:00
Gabriel L. Somlo
501f28ca9d tests: rename acpi-test to bios-tables-test
The test harness for acpi (generating a boot disk, starting qemu,
waiting for the BIOS to finish booting before examining guest
memory, etc.) is perfectly suited for testing other bios tables
beside acpi, such as e.g., smbios.

This patch renames acpi-test to bios-tables-test to reflect that,
and in preparation for adding smbios tests.

Signed-off-by: Gabriel Somlo <somlo@cmu.edu>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2014-05-27 23:42:16 +03:00
Ján Tomko
38dbd48b24 virtio-balloon: return empty data when no stats are available
If the guest hasn't updated the stats yet, instead of returning
an error, return '-1' for the stats and '0' as 'last-update'.

This lets applications ignore this without parsing the error message.

Related libvirt patch and discussion:
https://www.redhat.com/archives/libvir-list/2014-May/msg00460.html

Tested against current upstream libvirt - stat reporting works and
it no longer logs errors when the stats are queried on domain startup.
(Note: libvirt doesn't use the last-update field for anything yet)

Signed-off-by: Ján Tomko <jtomko@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
2014-05-25 12:46:58 +03:00
Paolo Bonzini
28fb26f19f target-i386: set CC_OP to CC_OP_EFLAGS in cpu_load_eflags
There is no reason to keep that out of the function.  The comment refers
to the disassembler's cc_op state rather than the CPUState field.

Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-05-21 18:02:08 +02:00
Paolo Bonzini
7125c937c9 target-i386: get CPL from SS.DPL
CS.RPL is not equal to the CPL in the few instructions between
setting CR0.PE and reloading CS.  We get this right in the common
case, because writes to CR0 do not modify the CPL, but it would
not be enough if an SMI comes exactly during that brief period.
Were this to happen, the RSM instruction would erroneously set
CPL to the low two bits of the real-mode selector; and if they are
not 00, the next instruction fetch cannot access the code segment
and causes a triple fault.

However, SS.DPL *is* always equal to the CPL.  In real processors
(AMD only) there is a weird case of SYSRET setting SS.DPL=SS.RPL
from the STAR register while forcing CPL=3, but we do not emulate
that.

Tested-by: Kevin O'Connor <kevin@koconnor.net>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-05-21 18:02:08 +02:00
Paolo Bonzini
d3b5491897 target-i386: rework CPL checks during task switch, preparing for next patch
During task switch, all of CS.DPL, CS.RPL, SS.DPL must match (in addition
to all the other requirements) and will be the new CPL.  So far this worked
by carefully setting the CS selector and flags before doing the task
switch; but this will not work once we get the CPL from SS.DPL.

Temporarily assume that the CPL comes from CS.RPL during task switch
to a protected-mode task, until the descriptor of SS is loaded.

Tested-by: Kevin O'Connor <kevin@koconnor.net>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-05-21 18:02:08 +02:00
Paolo Bonzini
b98dbc9095 target-i386: fix segment flags for SMM and VM86 mode
With the next patch, these need to be correct or VM86 tasks
have the wrong CPL.  The flags are basically what the Intel VMX
documentation say is mandatory for entry into a VM86 guest.

For consistency, SMM ought to have the same flags except with
CPL=0.

Tested-by: Kevin O'Connor <kevin@koconnor.net>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-05-21 18:02:08 +02:00
Kevin O'Connor
87446327cc target-i386: Fix vm86 mode regression introduced in fd460606fd.
Commit fd460606fd moved setting of eflags above calls to
cpu_x86_load_seg_cache() in seg_helper.c.  Unfortunately, in
do_interrupt_protected() this moved the clearing of VM_MASK above a
test for it.

Fix this regression by storing the value of VM_MASK at the start of
do_interrupt_protected().

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-05-21 18:02:08 +02:00
Paolo Bonzini
b763adf1a6 kvm_stat: allow choosing between tracepoints and old stats
The old stats contain information not available in the tracepoints.
By default, keep the old behavior, but allow choosing which set of stats
to present, or even both.

Inspired by a patch from Marcelo Tosatti.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-05-21 17:56:37 +02:00
Andreas Färber
7c8b724826 pcie_host: Turn pcie_host_init() into an instance_init
This assures the trivial field initialization is applied for any derived
type - currently only Q35PCIHost.

Signed-off-by: Andreas Färber <afaerber@suse.de>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2014-05-21 15:47:50 +03:00
Gabriel L. Somlo
0d73394ad9 SMBIOS: Fix type 17 field sizes
Fields for configured_clock_speed and various voltage values
introduced in spec v2.7+ should be "word", i.e. 16 bits.

Reported-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Gabriel Somlo <somlo@cmu.edu>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2014-05-21 15:47:50 +03:00
Gabriel L. Somlo
84351843eb SMBIOS: Update Type 0 struct generator for machines >= 2.1
Update how type 0 (bios info) structures are generated, as follows:

  - convert bios_characteristics field to uin64_t (instead of
    uint8_t[8]), as described in the current smbios spec (v2.8)

  - enable "virtual machine" bit in bios_characteristics_extension_bits

  - add command line option to enable "uefi supported" bit in
    bios_characteristics_extension_bits

These updates should make this optional structure more useful when
used with edk2/ovmf. Only pc machines >= 2.1 are affected, and only
when a type 0 structure is explicitly specified on the command line.

Signed-off-by: Gabriel Somlo <somlo@cmu.edu>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2014-05-21 15:47:50 +03:00
Gabriel L. Somlo
fb5be2e833 SMBIOS: Fix endian-ness when populating multi-byte fields
When i386 guests are emulated on big endian hosts, make sure
multi-byte fields are populated safely via cpu_to_le*().

Signed-off-by: Gabriel Somlo <somlo@cmu.edu>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
2014-05-21 15:47:50 +03:00
BALATON Zoltan
13cc2c3e86 serial-pci: Set prog interface field of pci config to 16550 compatible
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
2014-05-21 15:47:50 +03:00
Alexander Graf
a096b3a673 kvmclock: Ensure time in migration never goes backward
When we migrate we ask the kernel about its current belief on what the guest
time would be. However, I've seen cases where the kvmclock guest structure
indicates a time more recent than the kvm returned time.

To make sure we never go backwards, calculate what the guest would have seen
as time at the point of migration and use that value instead of the kernel
returned one when it's more recent.  This bases the view of the kvmclock
after migration on the same foundation in host as well as guest.

Signed-off-by: Alexander Graf <agraf@suse.de>
Cc: qemu-stable@nongnu.org
Reviewed-by: Marcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2014-05-21 12:01:45 +02:00
467 changed files with 29756 additions and 10605 deletions

3
.gitmodules vendored
View File

@@ -28,3 +28,6 @@
[submodule "dtc"]
path = dtc
url = git://git.qemu-project.org/dtc.git
[submodule "roms/u-boot"]
path = roms/u-boot
url = git://git.qemu-project.org/u-boot.git

View File

@@ -66,16 +66,16 @@ matrix:
compiler: gcc
# All the trace backends (apart from dtrace)
- env: TARGETS=i386-softmmu,x86_64-softmmu
EXTRA_CONFIG="--enable-trace-backend=stderr"
EXTRA_CONFIG="--enable-trace-backends=stderr"
compiler: gcc
- env: TARGETS=i386-softmmu,x86_64-softmmu
EXTRA_CONFIG="--enable-trace-backend=simple"
EXTRA_CONFIG="--enable-trace-backends=simple"
compiler: gcc
- env: TARGETS=i386-softmmu,x86_64-softmmu
EXTRA_CONFIG="--enable-trace-backend=ftrace"
EXTRA_CONFIG="--enable-trace-backends=ftrace"
TEST_CMD=""
compiler: gcc
- env: TARGETS=i386-softmmu,x86_64-softmmu
EXTRA_PKGS="liblttng-ust-dev liburcu-dev"
EXTRA_CONFIG="--enable-trace-backend=ust"
EXTRA_CONFIG="--enable-trace-backends=ust"
compiler: gcc

View File

@@ -726,6 +726,16 @@ S: Odd Fixes
F: gdbstub*
F: gdb-xml/
Memory API
M: Paolo Bonzini <pbonzini@redhat.com>
S: Supported
F: include/exec/ioport.h
F: ioport.c
F: include/exec/memory.h
F: memory.c
F: include/exec/memory-internal.h
F: exec.c
SPICE
M: Gerd Hoffmann <kraxel@redhat.com>
S: Supported

View File

@@ -52,12 +52,12 @@ GENERATED_HEADERS += trace/generated-events.h
GENERATED_SOURCES += trace/generated-events.c
GENERATED_HEADERS += trace/generated-tracers.h
ifeq ($(TRACE_BACKEND),dtrace)
ifeq ($(findstring dtrace,$(TRACE_BACKENDS)),dtrace)
GENERATED_HEADERS += trace/generated-tracers-dtrace.h
endif
GENERATED_SOURCES += trace/generated-tracers.c
ifeq ($(TRACE_BACKEND),ust)
ifeq ($(findstring ust,$(TRACE_BACKENDS)),ust)
GENERATED_HEADERS += trace/generated-ust-provider.h
GENERATED_SOURCES += trace/generated-ust.c
endif

View File

@@ -49,7 +49,7 @@ endif
$(QEMU_PROG).stp-installed: $(SRC_PATH)/trace-events
$(call quiet-command,$(TRACETOOL) \
--format=stap \
--backend=$(TRACE_BACKEND) \
--backends=$(TRACE_BACKENDS) \
--binary=$(bindir)/$(QEMU_PROG) \
--target-name=$(TARGET_NAME) \
--target-type=$(TARGET_TYPE) \
@@ -58,7 +58,7 @@ $(QEMU_PROG).stp-installed: $(SRC_PATH)/trace-events
$(QEMU_PROG).stp: $(SRC_PATH)/trace-events
$(call quiet-command,$(TRACETOOL) \
--format=stap \
--backend=$(TRACE_BACKEND) \
--backends=$(TRACE_BACKENDS) \
--binary=$(realpath .)/$(QEMU_PROG) \
--target-name=$(TARGET_NAME) \
--target-type=$(TARGET_TYPE) \
@@ -85,6 +85,12 @@ obj-y += disas.o
obj-$(call notempty,$(TARGET_XML_FILES)) += gdbstub-xml.o
obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o
obj-$(CONFIG_LIBDECNUMBER) += libdecnumber/decContext.o
obj-$(CONFIG_LIBDECNUMBER) += libdecnumber/decNumber.o
obj-$(CONFIG_LIBDECNUMBER) += libdecnumber/dpd/decimal32.o
obj-$(CONFIG_LIBDECNUMBER) += libdecnumber/dpd/decimal64.o
obj-$(CONFIG_LIBDECNUMBER) += libdecnumber/dpd/decimal128.o
#########################################################
# Linux user emulator target
@@ -102,7 +108,8 @@ endif #CONFIG_LINUX_USER
ifdef CONFIG_BSD_USER
QEMU_CFLAGS+=-I$(SRC_PATH)/bsd-user -I$(SRC_PATH)/bsd-user/$(TARGET_ABI_DIR)
QEMU_CFLAGS+=-I$(SRC_PATH)/bsd-user -I$(SRC_PATH)/bsd-user/$(TARGET_ABI_DIR) \
-I$(SRC_PATH)/bsd-user/$(HOST_VARIANT_DIR)
obj-y += bsd-user/
obj-y += gdbstub.o user-exec.o

View File

@@ -739,7 +739,6 @@ static void migration_end(void)
XBZRLE_cache_lock();
if (XBZRLE.cache) {
cache_fini(XBZRLE.cache);
g_free(XBZRLE.cache);
g_free(XBZRLE.encoded_buf);
g_free(XBZRLE.current_buf);
XBZRLE.cache = NULL;
@@ -1041,17 +1040,15 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id)
{
ram_addr_t addr;
int flags, ret = 0;
int error;
static uint64_t seq_iter;
seq_iter++;
if (version_id != 4) {
ret = -EINVAL;
goto done;
}
do {
while (!ret) {
addr = qemu_get_be64(f);
flags = addr & ~TARGET_PAGE_MASK;
@@ -1079,7 +1076,6 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id)
" in != " RAM_ADDR_FMT, id, length,
block->length);
ret = -EINVAL;
goto done;
}
break;
}
@@ -1089,21 +1085,22 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id)
error_report("Unknown ramblock \"%s\", cannot "
"accept migration", id);
ret = -EINVAL;
goto done;
}
if (ret) {
break;
}
total_ram_bytes -= length;
}
}
if (flags & RAM_SAVE_FLAG_COMPRESS) {
} else if (flags & RAM_SAVE_FLAG_COMPRESS) {
void *host;
uint8_t ch;
host = host_from_stream_offset(f, addr, flags);
if (!host) {
error_report("Illegal RAM offset " RAM_ADDR_FMT, addr);
ret = -EINVAL;
goto done;
break;
}
ch = qemu_get_byte(f);
@@ -1113,33 +1110,39 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id)
host = host_from_stream_offset(f, addr, flags);
if (!host) {
error_report("Illegal RAM offset " RAM_ADDR_FMT, addr);
ret = -EINVAL;
goto done;
break;
}
qemu_get_buffer(f, host, TARGET_PAGE_SIZE);
} else if (flags & RAM_SAVE_FLAG_XBZRLE) {
void *host = host_from_stream_offset(f, addr, flags);
if (!host) {
error_report("Illegal RAM offset " RAM_ADDR_FMT, addr);
ret = -EINVAL;
goto done;
break;
}
if (load_xbzrle(f, addr, host) < 0) {
error_report("Failed to decompress XBZRLE page at "
RAM_ADDR_FMT, addr);
ret = -EINVAL;
goto done;
break;
}
} else if (flags & RAM_SAVE_FLAG_HOOK) {
ram_control_load_hook(f, flags);
} else if (flags & RAM_SAVE_FLAG_EOS) {
/* normal exit */
break;
} else {
error_report("Unknown migration flags: %#x", flags);
ret = -EINVAL;
break;
}
error = qemu_file_get_error(f);
if (error) {
ret = error;
goto done;
}
} while (!(flags & RAM_SAVE_FLAG_EOS));
ret = qemu_file_get_error(f);
}
done:
DPRINTF("Completed load of VM with exit code %d seq iteration "
"%" PRIu64 "\n", ret, seq_iter);
return ret;

14
async.c
View File

@@ -117,15 +117,21 @@ void qemu_bh_schedule_idle(QEMUBH *bh)
void qemu_bh_schedule(QEMUBH *bh)
{
AioContext *ctx;
if (bh->scheduled)
return;
ctx = bh->ctx;
bh->idle = 0;
/* Make sure that idle & any writes needed by the callback are done
* before the locations are read in the aio_bh_poll.
/* Make sure that:
* 1. idle & any writes needed by the callback are done before the
* locations are read in the aio_bh_poll.
* 2. ctx is loaded before scheduled is set and the callback has a chance
* to execute.
*/
smp_wmb();
smp_mb();
bh->scheduled = 1;
aio_notify(bh->ctx);
aio_notify(ctx);
}

View File

@@ -815,10 +815,8 @@ static void alsa_fini_out (HWVoiceOut *hw)
ldebug ("alsa_fini\n");
alsa_anal_close (&alsa->handle, &alsa->pollhlp);
if (alsa->pcm_buf) {
g_free (alsa->pcm_buf);
alsa->pcm_buf = NULL;
}
g_free(alsa->pcm_buf);
alsa->pcm_buf = NULL;
}
static int alsa_init_out (HWVoiceOut *hw, struct audsettings *as)
@@ -978,10 +976,8 @@ static void alsa_fini_in (HWVoiceIn *hw)
alsa_anal_close (&alsa->handle, &alsa->pollhlp);
if (alsa->pcm_buf) {
g_free (alsa->pcm_buf);
alsa->pcm_buf = NULL;
}
g_free(alsa->pcm_buf);
alsa->pcm_buf = NULL;
}
static int alsa_run_in (HWVoiceIn *hw)

View File

@@ -71,10 +71,7 @@ static void glue (audio_init_nb_voices_, TYPE) (struct audio_driver *drv)
static void glue (audio_pcm_hw_free_resources_, TYPE) (HW *hw)
{
if (HWBUF) {
g_free (HWBUF);
}
g_free (HWBUF);
HWBUF = NULL;
}
@@ -92,9 +89,7 @@ static int glue (audio_pcm_hw_alloc_resources_, TYPE) (HW *hw)
static void glue (audio_pcm_sw_free_resources_, TYPE) (SW *sw)
{
if (sw->buf) {
g_free (sw->buf);
}
g_free (sw->buf);
if (sw->rate) {
st_rate_stop (sw->rate);
@@ -172,10 +167,8 @@ static int glue (audio_pcm_sw_init_, TYPE) (
static void glue (audio_pcm_sw_fini_, TYPE) (SW *sw)
{
glue (audio_pcm_sw_free_resources_, TYPE) (sw);
if (sw->name) {
g_free (sw->name);
sw->name = NULL;
}
g_free (sw->name);
sw->name = NULL;
}
static void glue (audio_pcm_hw_add_sw_, TYPE) (HW *hw, SW *sw)

View File

@@ -736,10 +736,8 @@ static void oss_fini_in (HWVoiceIn *hw)
oss_anal_close (&oss->fd);
if (oss->pcm_buf) {
g_free (oss->pcm_buf);
oss->pcm_buf = NULL;
}
g_free(oss->pcm_buf);
oss->pcm_buf = NULL;
}
static int oss_run_in (HWVoiceIn *hw)

View File

@@ -629,6 +629,7 @@ static int block_save_setup(QEMUFile *f, void *opaque)
block_mig_state.submitted, block_mig_state.transferred);
qemu_mutex_lock_iothread();
init_blk_migration(f);
/* start track dirty blocks */
ret = set_dirty_tracking();
@@ -638,8 +639,6 @@ static int block_save_setup(QEMUFile *f, void *opaque)
return ret;
}
init_blk_migration(f);
qemu_mutex_unlock_iothread();
ret = flush_blks(f);

243
block.c
View File

@@ -179,6 +179,7 @@ void bdrv_io_limits_enable(BlockDriverState *bs)
{
assert(!bs->io_limits_enabled);
throttle_init(&bs->throttle_state,
bdrv_get_aio_context(bs),
QEMU_CLOCK_VIRTUAL,
bdrv_throttle_read_timer_cb,
bdrv_throttle_write_timer_cb,
@@ -363,6 +364,7 @@ BlockDriverState *bdrv_new(const char *device_name, Error **errp)
qemu_co_queue_init(&bs->throttled_reqs[0]);
qemu_co_queue_init(&bs->throttled_reqs[1]);
bs->refcnt = 1;
bs->aio_context = qemu_get_aio_context();
return bs;
}
@@ -422,7 +424,7 @@ BlockDriver *bdrv_find_whitelisted_format(const char *format_name,
typedef struct CreateCo {
BlockDriver *drv;
char *filename;
QEMUOptionParameter *options;
QemuOpts *opts;
int ret;
Error *err;
} CreateCo;
@@ -435,7 +437,7 @@ static void coroutine_fn bdrv_create_co_entry(void *opaque)
CreateCo *cco = opaque;
assert(cco->drv);
ret = cco->drv->bdrv_create(cco->filename, cco->options, &local_err);
ret = cco->drv->bdrv_create(cco->filename, cco->opts, &local_err);
if (local_err) {
error_propagate(&cco->err, local_err);
}
@@ -443,7 +445,7 @@ static void coroutine_fn bdrv_create_co_entry(void *opaque)
}
int bdrv_create(BlockDriver *drv, const char* filename,
QEMUOptionParameter *options, Error **errp)
QemuOpts *opts, Error **errp)
{
int ret;
@@ -451,7 +453,7 @@ int bdrv_create(BlockDriver *drv, const char* filename,
CreateCo cco = {
.drv = drv,
.filename = g_strdup(filename),
.options = options,
.opts = opts,
.ret = NOT_DONE,
.err = NULL,
};
@@ -487,8 +489,7 @@ out:
return ret;
}
int bdrv_create_file(const char* filename, QEMUOptionParameter *options,
Error **errp)
int bdrv_create_file(const char *filename, QemuOpts *opts, Error **errp)
{
BlockDriver *drv;
Error *local_err = NULL;
@@ -500,7 +501,7 @@ int bdrv_create_file(const char* filename, QEMUOptionParameter *options,
return -ENOENT;
}
ret = bdrv_create(drv, filename, options, &local_err);
ret = bdrv_create(drv, filename, opts, &local_err);
if (local_err) {
error_propagate(errp, local_err);
}
@@ -1245,7 +1246,7 @@ void bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, Error **errp)
char *tmp_filename = g_malloc0(PATH_MAX + 1);
int64_t total_size;
BlockDriver *bdrv_qcow2;
QEMUOptionParameter *create_options;
QemuOpts *opts = NULL;
QDict *snapshot_options;
BlockDriverState *bs_snapshot;
Error *local_err;
@@ -1270,13 +1271,11 @@ void bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, Error **errp)
}
bdrv_qcow2 = bdrv_find_format("qcow2");
create_options = parse_option_parameters("", bdrv_qcow2->create_options,
NULL);
set_option_parameter_int(create_options, BLOCK_OPT_SIZE, total_size);
ret = bdrv_create(bdrv_qcow2, tmp_filename, create_options, &local_err);
free_option_parameters(create_options);
opts = qemu_opts_create(bdrv_qcow2->create_opts, NULL, 0,
&error_abort);
qemu_opt_set_number(opts, BLOCK_OPT_SIZE, total_size);
ret = bdrv_create(bdrv_qcow2, tmp_filename, opts, &local_err);
qemu_opts_del(opts);
if (ret < 0) {
error_setg_errno(errp, -ret, "Could not create temporary overlay "
"'%s': %s", tmp_filename,
@@ -1856,7 +1855,11 @@ void bdrv_close_all(void)
BlockDriverState *bs;
QTAILQ_FOREACH(bs, &bdrv_states, device_list) {
AioContext *aio_context = bdrv_get_aio_context(bs);
aio_context_acquire(aio_context);
bdrv_close(bs);
aio_context_release(aio_context);
}
}
@@ -1881,17 +1884,6 @@ static bool bdrv_requests_pending(BlockDriverState *bs)
return false;
}
static bool bdrv_requests_pending_all(void)
{
BlockDriverState *bs;
QTAILQ_FOREACH(bs, &bdrv_states, device_list) {
if (bdrv_requests_pending(bs)) {
return true;
}
}
return false;
}
/*
* Wait for pending requests to complete across all BlockDriverStates
*
@@ -1911,12 +1903,20 @@ void bdrv_drain_all(void)
BlockDriverState *bs;
while (busy) {
QTAILQ_FOREACH(bs, &bdrv_states, device_list) {
bdrv_start_throttled_reqs(bs);
}
busy = false;
busy = bdrv_requests_pending_all();
busy |= aio_poll(qemu_get_aio_context(), busy);
QTAILQ_FOREACH(bs, &bdrv_states, device_list) {
AioContext *aio_context = bdrv_get_aio_context(bs);
bool bs_busy;
aio_context_acquire(aio_context);
bdrv_start_throttled_reqs(bs);
bs_busy = bdrv_requests_pending(bs);
bs_busy |= aio_poll(aio_context, bs_busy);
aio_context_release(aio_context);
busy |= bs_busy;
}
}
}
@@ -2352,12 +2352,17 @@ int bdrv_commit_all(void)
BlockDriverState *bs;
QTAILQ_FOREACH(bs, &bdrv_states, device_list) {
AioContext *aio_context = bdrv_get_aio_context(bs);
aio_context_acquire(aio_context);
if (bs->drv && bs->backing_hd) {
int ret = bdrv_commit(bs);
if (ret < 0) {
aio_context_release(aio_context);
return ret;
}
}
aio_context_release(aio_context);
}
return 0;
}
@@ -2775,10 +2780,12 @@ static int bdrv_prwv_co(BlockDriverState *bs, int64_t offset,
/* Fast-path if already in coroutine context */
bdrv_rw_co_entry(&rwco);
} else {
AioContext *aio_context = bdrv_get_aio_context(bs);
co = qemu_coroutine_create(bdrv_rw_co_entry);
qemu_coroutine_enter(co, &rwco);
while (rwco.ret == NOT_DONE) {
qemu_aio_wait();
aio_poll(aio_context, true);
}
}
return rwco.ret;
@@ -3831,10 +3838,15 @@ int bdrv_flush_all(void)
int result = 0;
QTAILQ_FOREACH(bs, &bdrv_states, device_list) {
int ret = bdrv_flush(bs);
AioContext *aio_context = bdrv_get_aio_context(bs);
int ret;
aio_context_acquire(aio_context);
ret = bdrv_flush(bs);
if (ret < 0 && !result) {
result = ret;
}
aio_context_release(aio_context);
}
return result;
@@ -4025,10 +4037,12 @@ int64_t bdrv_get_block_status(BlockDriverState *bs, int64_t sector_num,
/* Fast-path if already in coroutine context */
bdrv_get_block_status_co_entry(&data);
} else {
AioContext *aio_context = bdrv_get_aio_context(bs);
co = qemu_coroutine_create(bdrv_get_block_status_co_entry);
qemu_coroutine_enter(co, &data);
while (!data.done) {
qemu_aio_wait();
aio_poll(aio_context, true);
}
}
return data.ret;
@@ -4621,7 +4635,7 @@ static BlockDriverAIOCB *bdrv_aio_rw_vector(BlockDriverState *bs,
acb->is_write = is_write;
acb->qiov = qiov;
acb->bounce = qemu_blockalign(bs, qiov->size);
acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
acb->bh = aio_bh_new(bdrv_get_aio_context(bs), bdrv_aio_bh_cb, acb);
if (is_write) {
qemu_iovec_to_buf(acb->qiov, 0, acb->bounce, qiov->size);
@@ -4660,13 +4674,14 @@ typedef struct BlockDriverAIOCBCoroutine {
static void bdrv_aio_co_cancel_em(BlockDriverAIOCB *blockacb)
{
AioContext *aio_context = bdrv_get_aio_context(blockacb->bs);
BlockDriverAIOCBCoroutine *acb =
container_of(blockacb, BlockDriverAIOCBCoroutine, common);
bool done = false;
acb->done = &done;
while (!done) {
qemu_aio_wait();
aio_poll(aio_context, true);
}
}
@@ -4703,7 +4718,7 @@ static void coroutine_fn bdrv_co_do_rw(void *opaque)
acb->req.nb_sectors, acb->req.qiov, acb->req.flags);
}
acb->bh = qemu_bh_new(bdrv_co_em_bh, acb);
acb->bh = aio_bh_new(bdrv_get_aio_context(bs), bdrv_co_em_bh, acb);
qemu_bh_schedule(acb->bh);
}
@@ -4739,7 +4754,7 @@ static void coroutine_fn bdrv_aio_flush_co_entry(void *opaque)
BlockDriverState *bs = acb->common.bs;
acb->req.error = bdrv_co_flush(bs);
acb->bh = qemu_bh_new(bdrv_co_em_bh, acb);
acb->bh = aio_bh_new(bdrv_get_aio_context(bs), bdrv_co_em_bh, acb);
qemu_bh_schedule(acb->bh);
}
@@ -4766,7 +4781,7 @@ static void coroutine_fn bdrv_aio_discard_co_entry(void *opaque)
BlockDriverState *bs = acb->common.bs;
acb->req.error = bdrv_co_discard(bs, acb->req.sector, acb->req.nb_sectors);
acb->bh = qemu_bh_new(bdrv_co_em_bh, acb);
acb->bh = aio_bh_new(bdrv_get_aio_context(bs), bdrv_co_em_bh, acb);
qemu_bh_schedule(acb->bh);
}
@@ -4977,7 +4992,11 @@ void bdrv_invalidate_cache_all(Error **errp)
Error *local_err = NULL;
QTAILQ_FOREACH(bs, &bdrv_states, device_list) {
AioContext *aio_context = bdrv_get_aio_context(bs);
aio_context_acquire(aio_context);
bdrv_invalidate_cache(bs, &local_err);
aio_context_release(aio_context);
if (local_err) {
error_propagate(errp, local_err);
return;
@@ -4990,7 +5009,11 @@ void bdrv_clear_incoming_migration_all(void)
BlockDriverState *bs;
QTAILQ_FOREACH(bs, &bdrv_states, device_list) {
AioContext *aio_context = bdrv_get_aio_context(bs);
aio_context_acquire(aio_context);
bs->open_flags = bs->open_flags & ~(BDRV_O_INCOMING);
aio_context_release(aio_context);
}
}
@@ -5006,10 +5029,12 @@ int bdrv_flush(BlockDriverState *bs)
/* Fast-path if already in coroutine context */
bdrv_flush_co_entry(&rwco);
} else {
AioContext *aio_context = bdrv_get_aio_context(bs);
co = qemu_coroutine_create(bdrv_flush_co_entry);
qemu_coroutine_enter(co, &rwco);
while (rwco.ret == NOT_DONE) {
qemu_aio_wait();
aio_poll(aio_context, true);
}
}
@@ -5119,10 +5144,12 @@ int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors)
/* Fast-path if already in coroutine context */
bdrv_discard_co_entry(&rwco);
} else {
AioContext *aio_context = bdrv_get_aio_context(bs);
co = qemu_coroutine_create(bdrv_discard_co_entry);
qemu_coroutine_enter(co, &rwco);
while (rwco.ret == NOT_DONE) {
qemu_aio_wait();
aio_poll(aio_context, true);
}
}
@@ -5489,8 +5516,10 @@ void bdrv_img_create(const char *filename, const char *fmt,
char *options, uint64_t img_size, int flags,
Error **errp, bool quiet)
{
QEMUOptionParameter *param = NULL, *create_options = NULL;
QEMUOptionParameter *backing_fmt, *backing_file, *size;
QemuOptsList *create_opts = NULL;
QemuOpts *opts = NULL;
const char *backing_fmt, *backing_file;
int64_t size;
BlockDriver *drv, *proto_drv;
BlockDriver *backing_drv = NULL;
Error *local_err = NULL;
@@ -5509,28 +5538,23 @@ void bdrv_img_create(const char *filename, const char *fmt,
return;
}
create_options = append_option_parameters(create_options,
drv->create_options);
create_options = append_option_parameters(create_options,
proto_drv->create_options);
create_opts = qemu_opts_append(create_opts, drv->create_opts);
create_opts = qemu_opts_append(create_opts, proto_drv->create_opts);
/* Create parameter list with default values */
param = parse_option_parameters("", create_options, param);
set_option_parameter_int(param, BLOCK_OPT_SIZE, img_size);
opts = qemu_opts_create(create_opts, NULL, 0, &error_abort);
qemu_opt_set_number(opts, BLOCK_OPT_SIZE, img_size);
/* Parse -o options */
if (options) {
param = parse_option_parameters(options, create_options, param);
if (param == NULL) {
error_setg(errp, "Invalid options for file format '%s'.", fmt);
if (qemu_opts_do_parse(opts, options, NULL) != 0) {
error_setg(errp, "Invalid options for file format '%s'", fmt);
goto out;
}
}
if (base_filename) {
if (set_option_parameter(param, BLOCK_OPT_BACKING_FILE,
base_filename)) {
if (qemu_opt_set(opts, BLOCK_OPT_BACKING_FILE, base_filename)) {
error_setg(errp, "Backing file not supported for file format '%s'",
fmt);
goto out;
@@ -5538,37 +5562,37 @@ void bdrv_img_create(const char *filename, const char *fmt,
}
if (base_fmt) {
if (set_option_parameter(param, BLOCK_OPT_BACKING_FMT, base_fmt)) {
if (qemu_opt_set(opts, BLOCK_OPT_BACKING_FMT, base_fmt)) {
error_setg(errp, "Backing file format not supported for file "
"format '%s'", fmt);
goto out;
}
}
backing_file = get_option_parameter(param, BLOCK_OPT_BACKING_FILE);
if (backing_file && backing_file->value.s) {
if (!strcmp(filename, backing_file->value.s)) {
backing_file = qemu_opt_get(opts, BLOCK_OPT_BACKING_FILE);
if (backing_file) {
if (!strcmp(filename, backing_file)) {
error_setg(errp, "Error: Trying to create an image with the "
"same filename as the backing file");
goto out;
}
}
backing_fmt = get_option_parameter(param, BLOCK_OPT_BACKING_FMT);
if (backing_fmt && backing_fmt->value.s) {
backing_drv = bdrv_find_format(backing_fmt->value.s);
backing_fmt = qemu_opt_get(opts, BLOCK_OPT_BACKING_FMT);
if (backing_fmt) {
backing_drv = bdrv_find_format(backing_fmt);
if (!backing_drv) {
error_setg(errp, "Unknown backing file format '%s'",
backing_fmt->value.s);
backing_fmt);
goto out;
}
}
// The size for the image must always be specified, with one exception:
// If we are using a backing file, we can obtain the size from there
size = get_option_parameter(param, BLOCK_OPT_SIZE);
if (size && size->value.n == -1) {
if (backing_file && backing_file->value.s) {
size = qemu_opt_get_size(opts, BLOCK_OPT_SIZE, 0);
if (size == -1) {
if (backing_file) {
BlockDriverState *bs;
uint64_t size;
char buf[32];
@@ -5579,11 +5603,11 @@ void bdrv_img_create(const char *filename, const char *fmt,
flags & ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING);
bs = NULL;
ret = bdrv_open(&bs, backing_file->value.s, NULL, NULL, back_flags,
ret = bdrv_open(&bs, backing_file, NULL, NULL, back_flags,
backing_drv, &local_err);
if (ret < 0) {
error_setg_errno(errp, -ret, "Could not open '%s': %s",
backing_file->value.s,
backing_file,
error_get_pretty(local_err));
error_free(local_err);
local_err = NULL;
@@ -5593,7 +5617,7 @@ void bdrv_img_create(const char *filename, const char *fmt,
size *= 512;
snprintf(buf, sizeof(buf), "%" PRId64, size);
set_option_parameter(param, BLOCK_OPT_SIZE, buf);
qemu_opt_set_number(opts, BLOCK_OPT_SIZE, size);
bdrv_unref(bs);
} else {
@@ -5604,16 +5628,18 @@ void bdrv_img_create(const char *filename, const char *fmt,
if (!quiet) {
printf("Formatting '%s', fmt=%s ", filename, fmt);
print_option_parameters(param);
qemu_opts_print(opts);
puts("");
}
ret = bdrv_create(drv, filename, param, &local_err);
ret = bdrv_create(drv, filename, opts, &local_err);
if (ret == -EFBIG) {
/* This is generally a better message than whatever the driver would
* deliver (especially because of the cluster_size_hint), since that
* is most probably not much different from "image too large". */
const char *cluster_size_hint = "";
if (get_option_parameter(create_options, BLOCK_OPT_CLUSTER_SIZE)) {
if (qemu_opt_get_size(opts, BLOCK_OPT_CLUSTER_SIZE, 0)) {
cluster_size_hint = " (try using a larger cluster size)";
}
error_setg(errp, "The image size is too large for file format '%s'"
@@ -5623,9 +5649,8 @@ void bdrv_img_create(const char *filename, const char *fmt,
}
out:
free_option_parameters(create_options);
free_option_parameters(param);
qemu_opts_del(opts);
qemu_opts_free(create_opts);
if (local_err) {
error_propagate(errp, local_err);
}
@@ -5633,8 +5658,66 @@ out:
AioContext *bdrv_get_aio_context(BlockDriverState *bs)
{
/* Currently BlockDriverState always uses the main loop AioContext */
return qemu_get_aio_context();
return bs->aio_context;
}
void bdrv_detach_aio_context(BlockDriverState *bs)
{
if (!bs->drv) {
return;
}
if (bs->io_limits_enabled) {
throttle_detach_aio_context(&bs->throttle_state);
}
if (bs->drv->bdrv_detach_aio_context) {
bs->drv->bdrv_detach_aio_context(bs);
}
if (bs->file) {
bdrv_detach_aio_context(bs->file);
}
if (bs->backing_hd) {
bdrv_detach_aio_context(bs->backing_hd);
}
bs->aio_context = NULL;
}
void bdrv_attach_aio_context(BlockDriverState *bs,
AioContext *new_context)
{
if (!bs->drv) {
return;
}
bs->aio_context = new_context;
if (bs->backing_hd) {
bdrv_attach_aio_context(bs->backing_hd, new_context);
}
if (bs->file) {
bdrv_attach_aio_context(bs->file, new_context);
}
if (bs->drv->bdrv_attach_aio_context) {
bs->drv->bdrv_attach_aio_context(bs, new_context);
}
if (bs->io_limits_enabled) {
throttle_attach_aio_context(&bs->throttle_state, new_context);
}
}
void bdrv_set_aio_context(BlockDriverState *bs, AioContext *new_context)
{
bdrv_drain_all(); /* ensure there are no in-flight requests */
bdrv_detach_aio_context(bs);
/* This function executes in the old AioContext so acquire the new one in
* case it runs in a different thread.
*/
aio_context_acquire(new_context);
bdrv_attach_aio_context(bs, new_context);
aio_context_release(new_context);
}
void bdrv_add_before_write_notifier(BlockDriverState *bs,
@@ -5643,12 +5726,12 @@ void bdrv_add_before_write_notifier(BlockDriverState *bs,
notifier_with_return_list_add(&bs->before_write_notifiers, notifier);
}
int bdrv_amend_options(BlockDriverState *bs, QEMUOptionParameter *options)
int bdrv_amend_options(BlockDriverState *bs, QemuOpts *opts)
{
if (bs->drv->bdrv_amend_options == NULL) {
if (!bs->drv->bdrv_amend_options) {
return -ENOTSUP;
}
return bs->drv->bdrv_amend_options(bs, options);
return bs->drv->bdrv_amend_options(bs, opts);
}
/* This function will be called by the bdrv_recurse_is_first_non_filter method

View File

@@ -471,7 +471,7 @@ static BlockDriverAIOCB *inject_error(BlockDriverState *bs,
acb = qemu_aio_get(&blkdebug_aiocb_info, bs, cb, opaque);
acb->ret = -error;
bh = qemu_bh_new(error_callback_bh, acb);
bh = aio_bh_new(bdrv_get_aio_context(bs), error_callback_bh, acb);
acb->bh = bh;
qemu_bh_schedule(bh);

View File

@@ -39,12 +39,13 @@ struct BlkverifyAIOCB {
static void blkverify_aio_cancel(BlockDriverAIOCB *blockacb)
{
BlkverifyAIOCB *acb = (BlkverifyAIOCB *)blockacb;
AioContext *aio_context = bdrv_get_aio_context(blockacb->bs);
bool finished = false;
/* Wait until request completes, invokes its callback, and frees itself */
acb->finished = &finished;
while (!finished) {
qemu_aio_wait();
aio_poll(aio_context, true);
}
}
@@ -228,7 +229,8 @@ static void blkverify_aio_cb(void *opaque, int ret)
acb->verify(acb);
}
acb->bh = qemu_bh_new(blkverify_aio_bh, acb);
acb->bh = aio_bh_new(bdrv_get_aio_context(acb->common.bs),
blkverify_aio_bh, acb);
qemu_bh_schedule(acb->bh);
break;
}
@@ -302,21 +304,40 @@ static bool blkverify_recurse_is_first_non_filter(BlockDriverState *bs,
return bdrv_recurse_is_first_non_filter(s->test_file, candidate);
}
/* Propagate AioContext changes to ->test_file */
static void blkverify_detach_aio_context(BlockDriverState *bs)
{
BDRVBlkverifyState *s = bs->opaque;
bdrv_detach_aio_context(s->test_file);
}
static void blkverify_attach_aio_context(BlockDriverState *bs,
AioContext *new_context)
{
BDRVBlkverifyState *s = bs->opaque;
bdrv_attach_aio_context(s->test_file, new_context);
}
static BlockDriver bdrv_blkverify = {
.format_name = "blkverify",
.protocol_name = "blkverify",
.instance_size = sizeof(BDRVBlkverifyState),
.format_name = "blkverify",
.protocol_name = "blkverify",
.instance_size = sizeof(BDRVBlkverifyState),
.bdrv_parse_filename = blkverify_parse_filename,
.bdrv_file_open = blkverify_open,
.bdrv_close = blkverify_close,
.bdrv_getlength = blkverify_getlength,
.bdrv_parse_filename = blkverify_parse_filename,
.bdrv_file_open = blkverify_open,
.bdrv_close = blkverify_close,
.bdrv_getlength = blkverify_getlength,
.bdrv_aio_readv = blkverify_aio_readv,
.bdrv_aio_writev = blkverify_aio_writev,
.bdrv_aio_flush = blkverify_aio_flush,
.bdrv_aio_readv = blkverify_aio_readv,
.bdrv_aio_writev = blkverify_aio_writev,
.bdrv_aio_flush = blkverify_aio_flush,
.is_filter = true,
.bdrv_attach_aio_context = blkverify_attach_aio_context,
.bdrv_detach_aio_context = blkverify_detach_aio_context,
.is_filter = true,
.bdrv_recurse_is_first_non_filter = blkverify_recurse_is_first_non_filter,
};

View File

@@ -324,31 +324,24 @@ static void cow_close(BlockDriverState *bs)
{
}
static int cow_create(const char *filename, QEMUOptionParameter *options,
Error **errp)
static int cow_create(const char *filename, QemuOpts *opts, Error **errp)
{
struct cow_header_v2 cow_header;
struct stat st;
int64_t image_sectors = 0;
const char *image_filename = NULL;
char *image_filename = NULL;
Error *local_err = NULL;
int ret;
BlockDriverState *cow_bs;
/* Read out options */
while (options && options->name) {
if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
image_sectors = options->value.n / 512;
} else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
image_filename = options->value.s;
}
options++;
}
image_sectors = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / 512;
image_filename = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
ret = bdrv_create_file(filename, options, &local_err);
ret = bdrv_create_file(filename, opts, &local_err);
if (ret < 0) {
error_propagate(errp, local_err);
return ret;
goto exit;
}
cow_bs = NULL;
@@ -356,7 +349,7 @@ static int cow_create(const char *filename, QEMUOptionParameter *options,
BDRV_O_RDWR | BDRV_O_PROTOCOL, NULL, &local_err);
if (ret < 0) {
error_propagate(errp, local_err);
return ret;
goto exit;
}
memset(&cow_header, 0, sizeof(cow_header));
@@ -389,22 +382,27 @@ static int cow_create(const char *filename, QEMUOptionParameter *options,
}
exit:
g_free(image_filename);
bdrv_unref(cow_bs);
return ret;
}
static QEMUOptionParameter cow_create_options[] = {
{
.name = BLOCK_OPT_SIZE,
.type = OPT_SIZE,
.help = "Virtual disk size"
},
{
.name = BLOCK_OPT_BACKING_FILE,
.type = OPT_STRING,
.help = "File name of a base image"
},
{ NULL }
static QemuOptsList cow_create_opts = {
.name = "cow-create-opts",
.head = QTAILQ_HEAD_INITIALIZER(cow_create_opts.head),
.desc = {
{
.name = BLOCK_OPT_SIZE,
.type = QEMU_OPT_SIZE,
.help = "Virtual disk size"
},
{
.name = BLOCK_OPT_BACKING_FILE,
.type = QEMU_OPT_STRING,
.help = "File name of a base image"
},
{ /* end of list */ }
}
};
static BlockDriver bdrv_cow = {
@@ -421,7 +419,7 @@ static BlockDriver bdrv_cow = {
.bdrv_write = cow_co_write,
.bdrv_co_get_block_status = cow_co_get_block_status,
.create_options = cow_create_options,
.create_opts = &cow_create_opts,
};
static void bdrv_cow_init(void)

View File

@@ -110,6 +110,7 @@ typedef struct BDRVCURLState {
size_t readahead_size;
bool sslverify;
bool accept_range;
AioContext *aio_context;
} BDRVCURLState;
static void curl_clean_state(CURLState *s);
@@ -134,25 +135,29 @@ static int curl_timer_cb(CURLM *multi, long timeout_ms, void *opaque)
#endif
static int curl_sock_cb(CURL *curl, curl_socket_t fd, int action,
void *s, void *sp)
void *userp, void *sp)
{
BDRVCURLState *s;
CURLState *state = NULL;
curl_easy_getinfo(curl, CURLINFO_PRIVATE, (char **)&state);
state->sock_fd = fd;
s = state->s;
DPRINTF("CURL (AIO): Sock action %d on fd %d\n", action, fd);
switch (action) {
case CURL_POLL_IN:
qemu_aio_set_fd_handler(fd, curl_multi_read, NULL, state);
aio_set_fd_handler(s->aio_context, fd, curl_multi_read,
NULL, state);
break;
case CURL_POLL_OUT:
qemu_aio_set_fd_handler(fd, NULL, curl_multi_do, state);
aio_set_fd_handler(s->aio_context, fd, NULL, curl_multi_do, state);
break;
case CURL_POLL_INOUT:
qemu_aio_set_fd_handler(fd, curl_multi_read, curl_multi_do, state);
aio_set_fd_handler(s->aio_context, fd, curl_multi_read,
curl_multi_do, state);
break;
case CURL_POLL_REMOVE:
qemu_aio_set_fd_handler(fd, NULL, NULL, NULL);
aio_set_fd_handler(s->aio_context, fd, NULL, NULL, NULL);
break;
}
@@ -365,7 +370,7 @@ static CURLState *curl_init_state(BDRVCURLState *s)
break;
}
if (!state) {
qemu_aio_wait();
aio_poll(state->s->aio_context, true);
}
} while(!state);
@@ -422,6 +427,49 @@ static void curl_parse_filename(const char *filename, QDict *options,
qdict_put(options, CURL_BLOCK_OPT_URL, qstring_from_str(filename));
}
static void curl_detach_aio_context(BlockDriverState *bs)
{
BDRVCURLState *s = bs->opaque;
int i;
for (i = 0; i < CURL_NUM_STATES; i++) {
if (s->states[i].in_use) {
curl_clean_state(&s->states[i]);
}
if (s->states[i].curl) {
curl_easy_cleanup(s->states[i].curl);
s->states[i].curl = NULL;
}
g_free(s->states[i].orig_buf);
s->states[i].orig_buf = NULL;
}
if (s->multi) {
curl_multi_cleanup(s->multi);
s->multi = NULL;
}
timer_del(&s->timer);
}
static void curl_attach_aio_context(BlockDriverState *bs,
AioContext *new_context)
{
BDRVCURLState *s = bs->opaque;
aio_timer_init(new_context, &s->timer,
QEMU_CLOCK_REALTIME, SCALE_NS,
curl_multi_timeout_do, s);
assert(!s->multi);
s->multi = curl_multi_init();
s->aio_context = new_context;
curl_multi_setopt(s->multi, CURLMOPT_SOCKETFUNCTION, curl_sock_cb);
#ifdef NEED_CURL_TIMER_CALLBACK
curl_multi_setopt(s->multi, CURLMOPT_TIMERDATA, s);
curl_multi_setopt(s->multi, CURLMOPT_TIMERFUNCTION, curl_timer_cb);
#endif
}
static QemuOptsList runtime_opts = {
.name = "curl",
.head = QTAILQ_HEAD_INITIALIZER(runtime_opts.head),
@@ -491,6 +539,7 @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags,
}
DPRINTF("CURL: Opening %s\n", file);
s->aio_context = bdrv_get_aio_context(bs);
s->url = g_strdup(file);
state = curl_init_state(s);
if (!state)
@@ -523,19 +572,7 @@ static int curl_open(BlockDriverState *bs, QDict *options, int flags,
curl_easy_cleanup(state->curl);
state->curl = NULL;
aio_timer_init(bdrv_get_aio_context(bs), &s->timer,
QEMU_CLOCK_REALTIME, SCALE_NS,
curl_multi_timeout_do, s);
// Now we know the file exists and its size, so let's
// initialize the multi interface!
s->multi = curl_multi_init();
curl_multi_setopt(s->multi, CURLMOPT_SOCKETFUNCTION, curl_sock_cb);
#ifdef NEED_CURL_TIMER_CALLBACK
curl_multi_setopt(s->multi, CURLMOPT_TIMERDATA, s);
curl_multi_setopt(s->multi, CURLMOPT_TIMERFUNCTION, curl_timer_cb);
#endif
curl_attach_aio_context(bs, bdrv_get_aio_context(bs));
qemu_opts_del(opts);
return 0;
@@ -599,8 +636,7 @@ static void curl_readv_bh_cb(void *p)
acb->end = (acb->nb_sectors * SECTOR_SIZE);
state->buf_off = 0;
if (state->orig_buf)
g_free(state->orig_buf);
g_free(state->orig_buf);
state->buf_start = start;
state->buf_len = acb->end + s->readahead_size;
end = MIN(start + state->buf_len, s->len) - 1;
@@ -630,7 +666,7 @@ static BlockDriverAIOCB *curl_aio_readv(BlockDriverState *bs,
acb->sector_num = sector_num;
acb->nb_sectors = nb_sectors;
acb->bh = qemu_bh_new(curl_readv_bh_cb, acb);
acb->bh = aio_bh_new(bdrv_get_aio_context(bs), curl_readv_bh_cb, acb);
qemu_bh_schedule(acb->bh);
return &acb->common;
}
@@ -638,25 +674,9 @@ static BlockDriverAIOCB *curl_aio_readv(BlockDriverState *bs,
static void curl_close(BlockDriverState *bs)
{
BDRVCURLState *s = bs->opaque;
int i;
DPRINTF("CURL: Close\n");
for (i=0; i<CURL_NUM_STATES; i++) {
if (s->states[i].in_use)
curl_clean_state(&s->states[i]);
if (s->states[i].curl) {
curl_easy_cleanup(s->states[i].curl);
s->states[i].curl = NULL;
}
if (s->states[i].orig_buf) {
g_free(s->states[i].orig_buf);
s->states[i].orig_buf = NULL;
}
}
if (s->multi)
curl_multi_cleanup(s->multi);
timer_del(&s->timer);
curl_detach_aio_context(bs);
g_free(s->url);
}
@@ -668,68 +688,83 @@ static int64_t curl_getlength(BlockDriverState *bs)
}
static BlockDriver bdrv_http = {
.format_name = "http",
.protocol_name = "http",
.format_name = "http",
.protocol_name = "http",
.instance_size = sizeof(BDRVCURLState),
.bdrv_parse_filename = curl_parse_filename,
.bdrv_file_open = curl_open,
.bdrv_close = curl_close,
.bdrv_getlength = curl_getlength,
.instance_size = sizeof(BDRVCURLState),
.bdrv_parse_filename = curl_parse_filename,
.bdrv_file_open = curl_open,
.bdrv_close = curl_close,
.bdrv_getlength = curl_getlength,
.bdrv_aio_readv = curl_aio_readv,
.bdrv_aio_readv = curl_aio_readv,
.bdrv_detach_aio_context = curl_detach_aio_context,
.bdrv_attach_aio_context = curl_attach_aio_context,
};
static BlockDriver bdrv_https = {
.format_name = "https",
.protocol_name = "https",
.format_name = "https",
.protocol_name = "https",
.instance_size = sizeof(BDRVCURLState),
.bdrv_parse_filename = curl_parse_filename,
.bdrv_file_open = curl_open,
.bdrv_close = curl_close,
.bdrv_getlength = curl_getlength,
.instance_size = sizeof(BDRVCURLState),
.bdrv_parse_filename = curl_parse_filename,
.bdrv_file_open = curl_open,
.bdrv_close = curl_close,
.bdrv_getlength = curl_getlength,
.bdrv_aio_readv = curl_aio_readv,
.bdrv_aio_readv = curl_aio_readv,
.bdrv_detach_aio_context = curl_detach_aio_context,
.bdrv_attach_aio_context = curl_attach_aio_context,
};
static BlockDriver bdrv_ftp = {
.format_name = "ftp",
.protocol_name = "ftp",
.format_name = "ftp",
.protocol_name = "ftp",
.instance_size = sizeof(BDRVCURLState),
.bdrv_parse_filename = curl_parse_filename,
.bdrv_file_open = curl_open,
.bdrv_close = curl_close,
.bdrv_getlength = curl_getlength,
.instance_size = sizeof(BDRVCURLState),
.bdrv_parse_filename = curl_parse_filename,
.bdrv_file_open = curl_open,
.bdrv_close = curl_close,
.bdrv_getlength = curl_getlength,
.bdrv_aio_readv = curl_aio_readv,
.bdrv_aio_readv = curl_aio_readv,
.bdrv_detach_aio_context = curl_detach_aio_context,
.bdrv_attach_aio_context = curl_attach_aio_context,
};
static BlockDriver bdrv_ftps = {
.format_name = "ftps",
.protocol_name = "ftps",
.format_name = "ftps",
.protocol_name = "ftps",
.instance_size = sizeof(BDRVCURLState),
.bdrv_parse_filename = curl_parse_filename,
.bdrv_file_open = curl_open,
.bdrv_close = curl_close,
.bdrv_getlength = curl_getlength,
.instance_size = sizeof(BDRVCURLState),
.bdrv_parse_filename = curl_parse_filename,
.bdrv_file_open = curl_open,
.bdrv_close = curl_close,
.bdrv_getlength = curl_getlength,
.bdrv_aio_readv = curl_aio_readv,
.bdrv_aio_readv = curl_aio_readv,
.bdrv_detach_aio_context = curl_detach_aio_context,
.bdrv_attach_aio_context = curl_attach_aio_context,
};
static BlockDriver bdrv_tftp = {
.format_name = "tftp",
.protocol_name = "tftp",
.format_name = "tftp",
.protocol_name = "tftp",
.instance_size = sizeof(BDRVCURLState),
.bdrv_parse_filename = curl_parse_filename,
.bdrv_file_open = curl_open,
.bdrv_close = curl_close,
.bdrv_getlength = curl_getlength,
.instance_size = sizeof(BDRVCURLState),
.bdrv_parse_filename = curl_parse_filename,
.bdrv_file_open = curl_open,
.bdrv_close = curl_close,
.bdrv_getlength = curl_getlength,
.bdrv_aio_readv = curl_aio_readv,
.bdrv_aio_readv = curl_aio_readv,
.bdrv_detach_aio_context = curl_detach_aio_context,
.bdrv_attach_aio_context = curl_attach_aio_context,
};
static void curl_block_init(void)

View File

@@ -16,6 +16,7 @@ typedef struct GlusterAIOCB {
int ret;
QEMUBH *bh;
Coroutine *coroutine;
AioContext *aio_context;
} GlusterAIOCB;
typedef struct BDRVGlusterState {
@@ -249,7 +250,7 @@ static void gluster_finish_aiocb(struct glfs_fd *fd, ssize_t ret, void *arg)
acb->ret = -EIO; /* Partial read/write - fail it */
}
acb->bh = qemu_bh_new(qemu_gluster_complete_aio, acb);
acb->bh = aio_bh_new(acb->aio_context, qemu_gluster_complete_aio, acb);
qemu_bh_schedule(acb->bh);
}
@@ -436,6 +437,7 @@ static coroutine_fn int qemu_gluster_co_write_zeroes(BlockDriverState *bs,
acb->size = size;
acb->ret = 0;
acb->coroutine = qemu_coroutine_self();
acb->aio_context = bdrv_get_aio_context(bs);
ret = glfs_zerofill_async(s->fd, offset, size, &gluster_finish_aiocb, acb);
if (ret < 0) {
@@ -476,13 +478,14 @@ static inline int qemu_gluster_zerofill(struct glfs_fd *fd, int64_t offset,
#endif
static int qemu_gluster_create(const char *filename,
QEMUOptionParameter *options, Error **errp)
QemuOpts *opts, Error **errp)
{
struct glfs *glfs;
struct glfs_fd *fd;
int ret = 0;
int prealloc = 0;
int64_t total_size = 0;
char *tmp = NULL;
GlusterConf *gconf = g_malloc0(sizeof(GlusterConf));
glfs = qemu_gluster_init(gconf, filename, errp);
@@ -491,24 +494,21 @@ static int qemu_gluster_create(const char *filename,
goto out;
}
while (options && options->name) {
if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
total_size = options->value.n / BDRV_SECTOR_SIZE;
} else if (!strcmp(options->name, BLOCK_OPT_PREALLOC)) {
if (!options->value.s || !strcmp(options->value.s, "off")) {
prealloc = 0;
} else if (!strcmp(options->value.s, "full") &&
gluster_supports_zerofill()) {
prealloc = 1;
} else {
error_setg(errp, "Invalid preallocation mode: '%s'"
" or GlusterFS doesn't support zerofill API",
options->value.s);
ret = -EINVAL;
goto out;
}
}
options++;
total_size =
qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / BDRV_SECTOR_SIZE;
tmp = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
if (!tmp || !strcmp(tmp, "off")) {
prealloc = 0;
} else if (!strcmp(tmp, "full") &&
gluster_supports_zerofill()) {
prealloc = 1;
} else {
error_setg(errp, "Invalid preallocation mode: '%s'"
" or GlusterFS doesn't support zerofill API",
tmp);
ret = -EINVAL;
goto out;
}
fd = glfs_creat(glfs, gconf->image,
@@ -530,6 +530,7 @@ static int qemu_gluster_create(const char *filename,
}
}
out:
g_free(tmp);
qemu_gluster_gconf_free(gconf);
if (glfs) {
glfs_fini(glfs);
@@ -549,6 +550,7 @@ static coroutine_fn int qemu_gluster_co_rw(BlockDriverState *bs,
acb->size = size;
acb->ret = 0;
acb->coroutine = qemu_coroutine_self();
acb->aio_context = bdrv_get_aio_context(bs);
if (write) {
ret = glfs_pwritev_async(s->fd, qiov->iov, qiov->niov, offset, 0,
@@ -605,6 +607,7 @@ static coroutine_fn int qemu_gluster_co_flush_to_disk(BlockDriverState *bs)
acb->size = 0;
acb->ret = 0;
acb->coroutine = qemu_coroutine_self();
acb->aio_context = bdrv_get_aio_context(bs);
ret = glfs_fsync_async(s->fd, &gluster_finish_aiocb, acb);
if (ret < 0) {
@@ -633,6 +636,7 @@ static coroutine_fn int qemu_gluster_co_discard(BlockDriverState *bs,
acb->size = 0;
acb->ret = 0;
acb->coroutine = qemu_coroutine_self();
acb->aio_context = bdrv_get_aio_context(bs);
ret = glfs_discard_async(s->fd, offset, size, &gluster_finish_aiocb, acb);
if (ret < 0) {
@@ -693,18 +697,22 @@ static int qemu_gluster_has_zero_init(BlockDriverState *bs)
return 0;
}
static QEMUOptionParameter qemu_gluster_create_options[] = {
{
.name = BLOCK_OPT_SIZE,
.type = OPT_SIZE,
.help = "Virtual disk size"
},
{
.name = BLOCK_OPT_PREALLOC,
.type = OPT_STRING,
.help = "Preallocation mode (allowed values: off, full)"
},
{ NULL }
static QemuOptsList qemu_gluster_create_opts = {
.name = "qemu-gluster-create-opts",
.head = QTAILQ_HEAD_INITIALIZER(qemu_gluster_create_opts.head),
.desc = {
{
.name = BLOCK_OPT_SIZE,
.type = QEMU_OPT_SIZE,
.help = "Virtual disk size"
},
{
.name = BLOCK_OPT_PREALLOC,
.type = QEMU_OPT_STRING,
.help = "Preallocation mode (allowed values: off, full)"
},
{ /* end of list */ }
}
};
static BlockDriver bdrv_gluster = {
@@ -731,7 +739,7 @@ static BlockDriver bdrv_gluster = {
#ifdef CONFIG_GLUSTERFS_ZEROFILL
.bdrv_co_write_zeroes = qemu_gluster_co_write_zeroes,
#endif
.create_options = qemu_gluster_create_options,
.create_opts = &qemu_gluster_create_opts,
};
static BlockDriver bdrv_gluster_tcp = {
@@ -758,7 +766,7 @@ static BlockDriver bdrv_gluster_tcp = {
#ifdef CONFIG_GLUSTERFS_ZEROFILL
.bdrv_co_write_zeroes = qemu_gluster_co_write_zeroes,
#endif
.create_options = qemu_gluster_create_options,
.create_opts = &qemu_gluster_create_opts,
};
static BlockDriver bdrv_gluster_unix = {
@@ -785,7 +793,7 @@ static BlockDriver bdrv_gluster_unix = {
#ifdef CONFIG_GLUSTERFS_ZEROFILL
.bdrv_co_write_zeroes = qemu_gluster_co_write_zeroes,
#endif
.create_options = qemu_gluster_create_options,
.create_opts = &qemu_gluster_create_opts,
};
static BlockDriver bdrv_gluster_rdma = {
@@ -812,7 +820,7 @@ static BlockDriver bdrv_gluster_rdma = {
#ifdef CONFIG_GLUSTERFS_ZEROFILL
.bdrv_co_write_zeroes = qemu_gluster_co_write_zeroes,
#endif
.create_options = qemu_gluster_create_options,
.create_opts = &qemu_gluster_create_opts,
};
static void bdrv_gluster_init(void)

View File

@@ -49,6 +49,7 @@
typedef struct IscsiLun {
struct iscsi_context *iscsi;
AioContext *aio_context;
int lun;
enum scsi_inquiry_peripheral_device_type type;
int block_size;
@@ -73,6 +74,7 @@ typedef struct IscsiTask {
struct scsi_task *task;
Coroutine *co;
QEMUBH *bh;
IscsiLun *iscsilun;
} IscsiTask;
typedef struct IscsiAIOCB {
@@ -133,7 +135,7 @@ iscsi_schedule_bh(IscsiAIOCB *acb)
if (acb->bh) {
return;
}
acb->bh = qemu_bh_new(iscsi_bh_cb, acb);
acb->bh = aio_bh_new(acb->iscsilun->aio_context, iscsi_bh_cb, acb);
qemu_bh_schedule(acb->bh);
}
@@ -169,7 +171,8 @@ iscsi_co_generic_cb(struct iscsi_context *iscsi, int status,
out:
if (iTask->co) {
iTask->bh = qemu_bh_new(iscsi_co_generic_bh_cb, iTask);
iTask->bh = aio_bh_new(iTask->iscsilun->aio_context,
iscsi_co_generic_bh_cb, iTask);
qemu_bh_schedule(iTask->bh);
}
}
@@ -177,8 +180,9 @@ out:
static void iscsi_co_init_iscsitask(IscsiLun *iscsilun, struct IscsiTask *iTask)
{
*iTask = (struct IscsiTask) {
.co = qemu_coroutine_self(),
.retries = ISCSI_CMD_RETRIES,
.co = qemu_coroutine_self(),
.retries = ISCSI_CMD_RETRIES,
.iscsilun = iscsilun,
};
}
@@ -209,7 +213,7 @@ iscsi_aio_cancel(BlockDriverAIOCB *blockacb)
iscsi_abort_task_cb, acb);
while (acb->status == -EINPROGRESS) {
qemu_aio_wait();
aio_poll(iscsilun->aio_context, true);
}
}
@@ -232,10 +236,11 @@ iscsi_set_events(IscsiLun *iscsilun)
ev = POLLIN;
ev |= iscsi_which_events(iscsi);
if (ev != iscsilun->events) {
qemu_aio_set_fd_handler(iscsi_get_fd(iscsi),
iscsi_process_read,
(ev & POLLOUT) ? iscsi_process_write : NULL,
iscsilun);
aio_set_fd_handler(iscsilun->aio_context,
iscsi_get_fd(iscsi),
iscsi_process_read,
(ev & POLLOUT) ? iscsi_process_write : NULL,
iscsilun);
}
@@ -791,7 +796,7 @@ static int iscsi_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
iscsi_aio_ioctl(bs, req, buf, ioctl_cb, &status);
while (status == -EINPROGRESS) {
qemu_aio_wait();
aio_poll(iscsilun->aio_context, true);
}
return 0;
@@ -1195,6 +1200,40 @@ fail_with_err:
return NULL;
}
static void iscsi_detach_aio_context(BlockDriverState *bs)
{
IscsiLun *iscsilun = bs->opaque;
aio_set_fd_handler(iscsilun->aio_context,
iscsi_get_fd(iscsilun->iscsi),
NULL, NULL, NULL);
iscsilun->events = 0;
if (iscsilun->nop_timer) {
timer_del(iscsilun->nop_timer);
timer_free(iscsilun->nop_timer);
iscsilun->nop_timer = NULL;
}
}
static void iscsi_attach_aio_context(BlockDriverState *bs,
AioContext *new_context)
{
IscsiLun *iscsilun = bs->opaque;
iscsilun->aio_context = new_context;
iscsi_set_events(iscsilun);
#if defined(LIBISCSI_FEATURE_NOP_COUNTER)
/* Set up a timer for sending out iSCSI NOPs */
iscsilun->nop_timer = aio_timer_new(iscsilun->aio_context,
QEMU_CLOCK_REALTIME, SCALE_MS,
iscsi_nop_timed_event, iscsilun);
timer_mod(iscsilun->nop_timer,
qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + NOP_INTERVAL);
#endif
}
/*
* We support iscsi url's on the form
* iscsi://[<username>%<password>@]<host>[:<port>]/<targetname>/<lun>
@@ -1301,6 +1340,7 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
}
iscsilun->iscsi = iscsi;
iscsilun->aio_context = bdrv_get_aio_context(bs);
iscsilun->lun = iscsi_url->lun;
iscsilun->has_write_same = true;
@@ -1374,11 +1414,7 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
scsi_free_scsi_task(task);
task = NULL;
#if defined(LIBISCSI_FEATURE_NOP_COUNTER)
/* Set up a timer for sending out iSCSI NOPs */
iscsilun->nop_timer = timer_new_ms(QEMU_CLOCK_REALTIME, iscsi_nop_timed_event, iscsilun);
timer_mod(iscsilun->nop_timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + NOP_INTERVAL);
#endif
iscsi_attach_aio_context(bs, iscsilun->aio_context);
/* Guess the internal cluster (page) size of the iscsi target by the means
* of opt_unmap_gran. Transfer the unmap granularity only if it has a
@@ -1398,9 +1434,7 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
out:
qemu_opts_del(opts);
if (initiator_name != NULL) {
g_free(initiator_name);
}
g_free(initiator_name);
if (iscsi_url != NULL) {
iscsi_destroy_url(iscsi_url);
}
@@ -1422,11 +1456,7 @@ static void iscsi_close(BlockDriverState *bs)
IscsiLun *iscsilun = bs->opaque;
struct iscsi_context *iscsi = iscsilun->iscsi;
if (iscsilun->nop_timer) {
timer_del(iscsilun->nop_timer);
timer_free(iscsilun->nop_timer);
}
qemu_aio_set_fd_handler(iscsi_get_fd(iscsi), NULL, NULL, NULL);
iscsi_detach_aio_context(bs);
iscsi_destroy_context(iscsi);
g_free(iscsilun->zeroblock);
g_free(iscsilun->allocationmap);
@@ -1500,8 +1530,7 @@ static int iscsi_truncate(BlockDriverState *bs, int64_t offset)
return 0;
}
static int iscsi_create(const char *filename, QEMUOptionParameter *options,
Error **errp)
static int iscsi_create(const char *filename, QemuOpts *opts, Error **errp)
{
int ret = 0;
int64_t total_size = 0;
@@ -1512,13 +1541,8 @@ static int iscsi_create(const char *filename, QEMUOptionParameter *options,
bs = bdrv_new("", &error_abort);
/* Read out options */
while (options && options->name) {
if (!strcmp(options->name, "size")) {
total_size = options->value.n / BDRV_SECTOR_SIZE;
}
options++;
}
total_size =
qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / BDRV_SECTOR_SIZE;
bs->opaque = g_malloc0(sizeof(struct IscsiLun));
iscsilun = bs->opaque;
@@ -1530,10 +1554,7 @@ static int iscsi_create(const char *filename, QEMUOptionParameter *options,
if (ret != 0) {
goto out;
}
if (iscsilun->nop_timer) {
timer_del(iscsilun->nop_timer);
timer_free(iscsilun->nop_timer);
}
iscsi_detach_aio_context(bs);
if (iscsilun->type != TYPE_DISK) {
ret = -ENODEV;
goto out;
@@ -1563,13 +1584,17 @@ static int iscsi_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
return 0;
}
static QEMUOptionParameter iscsi_create_options[] = {
{
.name = BLOCK_OPT_SIZE,
.type = OPT_SIZE,
.help = "Virtual disk size"
},
{ NULL }
static QemuOptsList iscsi_create_opts = {
.name = "iscsi-create-opts",
.head = QTAILQ_HEAD_INITIALIZER(iscsi_create_opts.head),
.desc = {
{
.name = BLOCK_OPT_SIZE,
.type = QEMU_OPT_SIZE,
.help = "Virtual disk size"
},
{ /* end of list */ }
}
};
static BlockDriver bdrv_iscsi = {
@@ -1581,7 +1606,7 @@ static BlockDriver bdrv_iscsi = {
.bdrv_file_open = iscsi_open,
.bdrv_close = iscsi_close,
.bdrv_create = iscsi_create,
.create_options = iscsi_create_options,
.create_opts = &iscsi_create_opts,
.bdrv_reopen_prepare = iscsi_reopen_prepare,
.bdrv_getlength = iscsi_getlength,
@@ -1604,6 +1629,9 @@ static BlockDriver bdrv_iscsi = {
.bdrv_ioctl = iscsi_ioctl,
.bdrv_aio_ioctl = iscsi_aio_ioctl,
#endif
.bdrv_detach_aio_context = iscsi_detach_aio_context,
.bdrv_attach_aio_context = iscsi_attach_aio_context,
};
static QemuOptsList qemu_iscsi_opts = {

View File

@@ -177,6 +177,20 @@ out_free_aiocb:
return NULL;
}
void laio_detach_aio_context(void *s_, AioContext *old_context)
{
struct qemu_laio_state *s = s_;
aio_set_event_notifier(old_context, &s->e, NULL);
}
void laio_attach_aio_context(void *s_, AioContext *new_context)
{
struct qemu_laio_state *s = s_;
aio_set_event_notifier(new_context, &s->e, qemu_laio_completion_cb);
}
void *laio_init(void)
{
struct qemu_laio_state *s;
@@ -190,8 +204,6 @@ void *laio_init(void)
goto out_close_efd;
}
qemu_aio_set_event_notifier(&s->e, qemu_laio_completion_cb);
return s;
out_close_efd:
@@ -200,3 +212,11 @@ out_free_state:
g_free(s);
return NULL;
}
void laio_cleanup(void *s_)
{
struct qemu_laio_state *s = s_;
event_notifier_cleanup(&s->e);
g_free(s);
}

View File

@@ -49,7 +49,7 @@ static void nbd_teardown_connection(NbdClientSession *client)
shutdown(client->sock, 2);
nbd_recv_coroutines_enter_all(client);
qemu_aio_set_fd_handler(client->sock, NULL, NULL, NULL);
nbd_client_session_detach_aio_context(client);
closesocket(client->sock);
client->sock = -1;
}
@@ -103,11 +103,14 @@ static int nbd_co_send_request(NbdClientSession *s,
struct nbd_request *request,
QEMUIOVector *qiov, int offset)
{
AioContext *aio_context;
int rc, ret;
qemu_co_mutex_lock(&s->send_mutex);
s->send_coroutine = qemu_coroutine_self();
qemu_aio_set_fd_handler(s->sock, nbd_reply_ready, nbd_restart_write, s);
aio_context = bdrv_get_aio_context(s->bs);
aio_set_fd_handler(aio_context, s->sock,
nbd_reply_ready, nbd_restart_write, s);
if (qiov) {
if (!s->is_unix) {
socket_set_cork(s->sock, 1);
@@ -126,7 +129,7 @@ static int nbd_co_send_request(NbdClientSession *s,
} else {
rc = nbd_send_request(s->sock, request);
}
qemu_aio_set_fd_handler(s->sock, nbd_reply_ready, NULL, s);
aio_set_fd_handler(aio_context, s->sock, nbd_reply_ready, NULL, s);
s->send_coroutine = NULL;
qemu_co_mutex_unlock(&s->send_mutex);
return rc;
@@ -335,6 +338,19 @@ int nbd_client_session_co_discard(NbdClientSession *client, int64_t sector_num,
}
void nbd_client_session_detach_aio_context(NbdClientSession *client)
{
aio_set_fd_handler(bdrv_get_aio_context(client->bs), client->sock,
NULL, NULL, NULL);
}
void nbd_client_session_attach_aio_context(NbdClientSession *client,
AioContext *new_context)
{
aio_set_fd_handler(new_context, client->sock,
nbd_reply_ready, NULL, client);
}
void nbd_client_session_close(NbdClientSession *client)
{
struct nbd_request request = {
@@ -381,7 +397,7 @@ int nbd_client_session_init(NbdClientSession *client, BlockDriverState *bs,
/* Now that we're connected, set the socket to be non-blocking and
* kick the reply mechanism. */
qemu_set_nonblock(sock);
qemu_aio_set_fd_handler(sock, nbd_reply_ready, NULL, client);
nbd_client_session_attach_aio_context(client, bdrv_get_aio_context(bs));
logout("Established connection with NBD server\n");
return 0;

View File

@@ -47,4 +47,8 @@ int nbd_client_session_co_writev(NbdClientSession *client, int64_t sector_num,
int nbd_client_session_co_readv(NbdClientSession *client, int64_t sector_num,
int nb_sectors, QEMUIOVector *qiov);
void nbd_client_session_detach_aio_context(NbdClientSession *client);
void nbd_client_session_attach_aio_context(NbdClientSession *client,
AioContext *new_context);
#endif /* NBD_CLIENT_H */

View File

@@ -323,46 +323,67 @@ static int64_t nbd_getlength(BlockDriverState *bs)
return s->client.size;
}
static void nbd_detach_aio_context(BlockDriverState *bs)
{
BDRVNBDState *s = bs->opaque;
nbd_client_session_detach_aio_context(&s->client);
}
static void nbd_attach_aio_context(BlockDriverState *bs,
AioContext *new_context)
{
BDRVNBDState *s = bs->opaque;
nbd_client_session_attach_aio_context(&s->client, new_context);
}
static BlockDriver bdrv_nbd = {
.format_name = "nbd",
.protocol_name = "nbd",
.instance_size = sizeof(BDRVNBDState),
.bdrv_parse_filename = nbd_parse_filename,
.bdrv_file_open = nbd_open,
.bdrv_co_readv = nbd_co_readv,
.bdrv_co_writev = nbd_co_writev,
.bdrv_close = nbd_close,
.bdrv_co_flush_to_os = nbd_co_flush,
.bdrv_co_discard = nbd_co_discard,
.bdrv_getlength = nbd_getlength,
.format_name = "nbd",
.protocol_name = "nbd",
.instance_size = sizeof(BDRVNBDState),
.bdrv_parse_filename = nbd_parse_filename,
.bdrv_file_open = nbd_open,
.bdrv_co_readv = nbd_co_readv,
.bdrv_co_writev = nbd_co_writev,
.bdrv_close = nbd_close,
.bdrv_co_flush_to_os = nbd_co_flush,
.bdrv_co_discard = nbd_co_discard,
.bdrv_getlength = nbd_getlength,
.bdrv_detach_aio_context = nbd_detach_aio_context,
.bdrv_attach_aio_context = nbd_attach_aio_context,
};
static BlockDriver bdrv_nbd_tcp = {
.format_name = "nbd",
.protocol_name = "nbd+tcp",
.instance_size = sizeof(BDRVNBDState),
.bdrv_parse_filename = nbd_parse_filename,
.bdrv_file_open = nbd_open,
.bdrv_co_readv = nbd_co_readv,
.bdrv_co_writev = nbd_co_writev,
.bdrv_close = nbd_close,
.bdrv_co_flush_to_os = nbd_co_flush,
.bdrv_co_discard = nbd_co_discard,
.bdrv_getlength = nbd_getlength,
.format_name = "nbd",
.protocol_name = "nbd+tcp",
.instance_size = sizeof(BDRVNBDState),
.bdrv_parse_filename = nbd_parse_filename,
.bdrv_file_open = nbd_open,
.bdrv_co_readv = nbd_co_readv,
.bdrv_co_writev = nbd_co_writev,
.bdrv_close = nbd_close,
.bdrv_co_flush_to_os = nbd_co_flush,
.bdrv_co_discard = nbd_co_discard,
.bdrv_getlength = nbd_getlength,
.bdrv_detach_aio_context = nbd_detach_aio_context,
.bdrv_attach_aio_context = nbd_attach_aio_context,
};
static BlockDriver bdrv_nbd_unix = {
.format_name = "nbd",
.protocol_name = "nbd+unix",
.instance_size = sizeof(BDRVNBDState),
.bdrv_parse_filename = nbd_parse_filename,
.bdrv_file_open = nbd_open,
.bdrv_co_readv = nbd_co_readv,
.bdrv_co_writev = nbd_co_writev,
.bdrv_close = nbd_close,
.bdrv_co_flush_to_os = nbd_co_flush,
.bdrv_co_discard = nbd_co_discard,
.bdrv_getlength = nbd_getlength,
.format_name = "nbd",
.protocol_name = "nbd+unix",
.instance_size = sizeof(BDRVNBDState),
.bdrv_parse_filename = nbd_parse_filename,
.bdrv_file_open = nbd_open,
.bdrv_co_readv = nbd_co_readv,
.bdrv_co_writev = nbd_co_writev,
.bdrv_close = nbd_close,
.bdrv_co_flush_to_os = nbd_co_flush,
.bdrv_co_discard = nbd_co_discard,
.bdrv_getlength = nbd_getlength,
.bdrv_detach_aio_context = nbd_detach_aio_context,
.bdrv_attach_aio_context = nbd_attach_aio_context,
};
static void bdrv_nbd_init(void)

View File

@@ -40,6 +40,7 @@ typedef struct NFSClient {
struct nfsfh *fh;
int events;
bool has_zero_init;
AioContext *aio_context;
} NFSClient;
typedef struct NFSRPC {
@@ -49,6 +50,7 @@ typedef struct NFSRPC {
struct stat *st;
Coroutine *co;
QEMUBH *bh;
NFSClient *client;
} NFSRPC;
static void nfs_process_read(void *arg);
@@ -58,10 +60,11 @@ static void nfs_set_events(NFSClient *client)
{
int ev = nfs_which_events(client->context);
if (ev != client->events) {
qemu_aio_set_fd_handler(nfs_get_fd(client->context),
(ev & POLLIN) ? nfs_process_read : NULL,
(ev & POLLOUT) ? nfs_process_write : NULL,
client);
aio_set_fd_handler(client->aio_context,
nfs_get_fd(client->context),
(ev & POLLIN) ? nfs_process_read : NULL,
(ev & POLLOUT) ? nfs_process_write : NULL,
client);
}
client->events = ev;
@@ -84,13 +87,15 @@ static void nfs_process_write(void *arg)
static void nfs_co_init_task(NFSClient *client, NFSRPC *task)
{
*task = (NFSRPC) {
.co = qemu_coroutine_self(),
.co = qemu_coroutine_self(),
.client = client,
};
}
static void nfs_co_generic_bh_cb(void *opaque)
{
NFSRPC *task = opaque;
task->complete = 1;
qemu_bh_delete(task->bh);
qemu_coroutine_enter(task->co, NULL);
}
@@ -100,7 +105,6 @@ nfs_co_generic_cb(int ret, struct nfs_context *nfs, void *data,
void *private_data)
{
NFSRPC *task = private_data;
task->complete = 1;
task->ret = ret;
if (task->ret > 0 && task->iov) {
if (task->ret <= task->iov->size) {
@@ -116,8 +120,11 @@ nfs_co_generic_cb(int ret, struct nfs_context *nfs, void *data,
error_report("NFS Error: %s", nfs_get_error(nfs));
}
if (task->co) {
task->bh = qemu_bh_new(nfs_co_generic_bh_cb, task);
task->bh = aio_bh_new(task->client->aio_context,
nfs_co_generic_bh_cb, task);
qemu_bh_schedule(task->bh);
} else {
task->complete = 1;
}
}
@@ -224,13 +231,34 @@ static QemuOptsList runtime_opts = {
},
};
static void nfs_detach_aio_context(BlockDriverState *bs)
{
NFSClient *client = bs->opaque;
aio_set_fd_handler(client->aio_context,
nfs_get_fd(client->context),
NULL, NULL, NULL);
client->events = 0;
}
static void nfs_attach_aio_context(BlockDriverState *bs,
AioContext *new_context)
{
NFSClient *client = bs->opaque;
client->aio_context = new_context;
nfs_set_events(client);
}
static void nfs_client_close(NFSClient *client)
{
if (client->context) {
if (client->fh) {
nfs_close(client->context, client->fh);
}
qemu_aio_set_fd_handler(nfs_get_fd(client->context), NULL, NULL, NULL);
aio_set_fd_handler(client->aio_context,
nfs_get_fd(client->context),
NULL, NULL, NULL);
nfs_destroy_context(client->context);
}
memset(client, 0, sizeof(NFSClient));
@@ -345,6 +373,8 @@ static int nfs_file_open(BlockDriverState *bs, QDict *options, int flags,
QemuOpts *opts;
Error *local_err = NULL;
client->aio_context = bdrv_get_aio_context(bs);
opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err);
if (local_err) {
@@ -361,20 +391,16 @@ static int nfs_file_open(BlockDriverState *bs, QDict *options, int flags,
return 0;
}
static int nfs_file_create(const char *url, QEMUOptionParameter *options,
Error **errp)
static int nfs_file_create(const char *url, QemuOpts *opts, Error **errp)
{
int ret = 0;
int64_t total_size = 0;
NFSClient *client = g_malloc0(sizeof(NFSClient));
client->aio_context = qemu_get_aio_context();
/* Read out options */
while (options && options->name) {
if (!strcmp(options->name, "size")) {
total_size = options->value.n;
}
options++;
}
total_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
ret = nfs_client_open(client, url, O_CREAT, errp);
if (ret < 0) {
@@ -407,7 +433,7 @@ static int64_t nfs_get_allocated_file_size(BlockDriverState *bs)
while (!task.complete) {
nfs_set_events(client);
qemu_aio_wait();
aio_poll(client->aio_context, true);
}
return (task.ret < 0 ? task.ret : st.st_blocks * st.st_blksize);
@@ -420,22 +446,25 @@ static int nfs_file_truncate(BlockDriverState *bs, int64_t offset)
}
static BlockDriver bdrv_nfs = {
.format_name = "nfs",
.protocol_name = "nfs",
.format_name = "nfs",
.protocol_name = "nfs",
.instance_size = sizeof(NFSClient),
.bdrv_needs_filename = true,
.bdrv_has_zero_init = nfs_has_zero_init,
.bdrv_get_allocated_file_size = nfs_get_allocated_file_size,
.bdrv_truncate = nfs_file_truncate,
.instance_size = sizeof(NFSClient),
.bdrv_needs_filename = true,
.bdrv_has_zero_init = nfs_has_zero_init,
.bdrv_get_allocated_file_size = nfs_get_allocated_file_size,
.bdrv_truncate = nfs_file_truncate,
.bdrv_file_open = nfs_file_open,
.bdrv_close = nfs_file_close,
.bdrv_create = nfs_file_create,
.bdrv_file_open = nfs_file_open,
.bdrv_close = nfs_file_close,
.bdrv_create = nfs_file_create,
.bdrv_co_readv = nfs_co_readv,
.bdrv_co_writev = nfs_co_writev,
.bdrv_co_flush_to_disk = nfs_co_flush,
.bdrv_co_readv = nfs_co_readv,
.bdrv_co_writev = nfs_co_writev,
.bdrv_co_flush_to_disk = nfs_co_flush,
.bdrv_detach_aio_context = nfs_detach_aio_context,
.bdrv_attach_aio_context = nfs_attach_aio_context,
};
static void nfs_block_init(void)

View File

@@ -693,35 +693,29 @@ static void qcow_close(BlockDriverState *bs)
error_free(s->migration_blocker);
}
static int qcow_create(const char *filename, QEMUOptionParameter *options,
Error **errp)
static int qcow_create(const char *filename, QemuOpts *opts, Error **errp)
{
int header_size, backing_filename_len, l1_size, shift, i;
QCowHeader header;
uint8_t *tmp;
int64_t total_size = 0;
const char *backing_file = NULL;
char *backing_file = NULL;
int flags = 0;
Error *local_err = NULL;
int ret;
BlockDriverState *qcow_bs;
/* Read out options */
while (options && options->name) {
if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
total_size = options->value.n / 512;
} else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
backing_file = options->value.s;
} else if (!strcmp(options->name, BLOCK_OPT_ENCRYPT)) {
flags |= options->value.n ? BLOCK_FLAG_ENCRYPT : 0;
}
options++;
total_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / 512;
backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ENCRYPT, false)) {
flags |= BLOCK_FLAG_ENCRYPT;
}
ret = bdrv_create_file(filename, options, &local_err);
ret = bdrv_create_file(filename, opts, &local_err);
if (ret < 0) {
error_propagate(errp, local_err);
return ret;
goto cleanup;
}
qcow_bs = NULL;
@@ -729,7 +723,7 @@ static int qcow_create(const char *filename, QEMUOptionParameter *options,
BDRV_O_RDWR | BDRV_O_PROTOCOL, NULL, &local_err);
if (ret < 0) {
error_propagate(errp, local_err);
return ret;
goto cleanup;
}
ret = bdrv_truncate(qcow_bs, 0);
@@ -800,6 +794,8 @@ static int qcow_create(const char *filename, QEMUOptionParameter *options,
ret = 0;
exit:
bdrv_unref(qcow_bs);
cleanup:
g_free(backing_file);
return ret;
}
@@ -912,24 +908,28 @@ static int qcow_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
return 0;
}
static QEMUOptionParameter qcow_create_options[] = {
{
.name = BLOCK_OPT_SIZE,
.type = OPT_SIZE,
.help = "Virtual disk size"
},
{
.name = BLOCK_OPT_BACKING_FILE,
.type = OPT_STRING,
.help = "File name of a base image"
},
{
.name = BLOCK_OPT_ENCRYPT,
.type = OPT_FLAG,
.help = "Encrypt the image"
},
{ NULL }
static QemuOptsList qcow_create_opts = {
.name = "qcow-create-opts",
.head = QTAILQ_HEAD_INITIALIZER(qcow_create_opts.head),
.desc = {
{
.name = BLOCK_OPT_SIZE,
.type = QEMU_OPT_SIZE,
.help = "Virtual disk size"
},
{
.name = BLOCK_OPT_BACKING_FILE,
.type = QEMU_OPT_STRING,
.help = "File name of a base image"
},
{
.name = BLOCK_OPT_ENCRYPT,
.type = QEMU_OPT_BOOL,
.help = "Encrypt the image",
.def_value_str = "off"
},
{ /* end of list */ }
}
};
static BlockDriver bdrv_qcow = {
@@ -938,8 +938,8 @@ static BlockDriver bdrv_qcow = {
.bdrv_probe = qcow_probe,
.bdrv_open = qcow_open,
.bdrv_close = qcow_close,
.bdrv_reopen_prepare = qcow_reopen_prepare,
.bdrv_create = qcow_create,
.bdrv_reopen_prepare = qcow_reopen_prepare,
.bdrv_create = qcow_create,
.bdrv_has_zero_init = bdrv_has_zero_init_1,
.bdrv_co_readv = qcow_co_readv,
@@ -951,7 +951,7 @@ static BlockDriver bdrv_qcow = {
.bdrv_write_compressed = qcow_write_compressed,
.bdrv_get_info = qcow_get_info,
.create_options = qcow_create_options,
.create_opts = &qcow_create_opts,
};
static void bdrv_qcow_init(void)

View File

@@ -31,6 +31,7 @@
#include "qapi/qmp/qerror.h"
#include "qapi/qmp/qbool.h"
#include "trace.h"
#include "qemu/option_int.h"
/*
Differences with QCOW:
@@ -1594,7 +1595,7 @@ static int preallocate(BlockDriverState *bs)
static int qcow2_create2(const char *filename, int64_t total_size,
const char *backing_file, const char *backing_format,
int flags, size_t cluster_size, int prealloc,
QEMUOptionParameter *options, int version,
QemuOpts *opts, int version,
Error **errp)
{
/* Calculate cluster_bits */
@@ -1626,7 +1627,7 @@ static int qcow2_create2(const char *filename, int64_t total_size,
Error *local_err = NULL;
int ret;
ret = bdrv_create_file(filename, options, &local_err);
ret = bdrv_create_file(filename, opts, &local_err);
if (ret < 0) {
error_propagate(errp, local_err);
return ret;
@@ -1762,11 +1763,11 @@ out:
return ret;
}
static int qcow2_create(const char *filename, QEMUOptionParameter *options,
Error **errp)
static int qcow2_create(const char *filename, QemuOpts *opts, Error **errp)
{
const char *backing_file = NULL;
const char *backing_fmt = NULL;
char *backing_file = NULL;
char *backing_fmt = NULL;
char *buf = NULL;
uint64_t sectors = 0;
int flags = 0;
size_t cluster_size = DEFAULT_CLUSTER_SIZE;
@@ -1776,64 +1777,66 @@ static int qcow2_create(const char *filename, QEMUOptionParameter *options,
int ret;
/* Read out options */
while (options && options->name) {
if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
sectors = options->value.n / 512;
} else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
backing_file = options->value.s;
} else if (!strcmp(options->name, BLOCK_OPT_BACKING_FMT)) {
backing_fmt = options->value.s;
} else if (!strcmp(options->name, BLOCK_OPT_ENCRYPT)) {
flags |= options->value.n ? BLOCK_FLAG_ENCRYPT : 0;
} else if (!strcmp(options->name, BLOCK_OPT_CLUSTER_SIZE)) {
if (options->value.n) {
cluster_size = options->value.n;
}
} else if (!strcmp(options->name, BLOCK_OPT_PREALLOC)) {
if (!options->value.s || !strcmp(options->value.s, "off")) {
prealloc = 0;
} else if (!strcmp(options->value.s, "metadata")) {
prealloc = 1;
} else {
error_setg(errp, "Invalid preallocation mode: '%s'",
options->value.s);
return -EINVAL;
}
} else if (!strcmp(options->name, BLOCK_OPT_COMPAT_LEVEL)) {
if (!options->value.s) {
/* keep the default */
} else if (!strcmp(options->value.s, "0.10")) {
version = 2;
} else if (!strcmp(options->value.s, "1.1")) {
version = 3;
} else {
error_setg(errp, "Invalid compatibility level: '%s'",
options->value.s);
return -EINVAL;
}
} else if (!strcmp(options->name, BLOCK_OPT_LAZY_REFCOUNTS)) {
flags |= options->value.n ? BLOCK_FLAG_LAZY_REFCOUNTS : 0;
}
options++;
sectors = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / 512;
backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
backing_fmt = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FMT);
if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ENCRYPT, false)) {
flags |= BLOCK_FLAG_ENCRYPT;
}
cluster_size = qemu_opt_get_size_del(opts, BLOCK_OPT_CLUSTER_SIZE,
DEFAULT_CLUSTER_SIZE);
buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
if (!buf || !strcmp(buf, "off")) {
prealloc = 0;
} else if (!strcmp(buf, "metadata")) {
prealloc = 1;
} else {
error_setg(errp, "Invalid preallocation mode: '%s'", buf);
ret = -EINVAL;
goto finish;
}
g_free(buf);
buf = qemu_opt_get_del(opts, BLOCK_OPT_COMPAT_LEVEL);
if (!buf) {
/* keep the default */
} else if (!strcmp(buf, "0.10")) {
version = 2;
} else if (!strcmp(buf, "1.1")) {
version = 3;
} else {
error_setg(errp, "Invalid compatibility level: '%s'", buf);
ret = -EINVAL;
goto finish;
}
if (qemu_opt_get_bool_del(opts, BLOCK_OPT_LAZY_REFCOUNTS, false)) {
flags |= BLOCK_FLAG_LAZY_REFCOUNTS;
}
if (backing_file && prealloc) {
error_setg(errp, "Backing file and preallocation cannot be used at "
"the same time");
return -EINVAL;
ret = -EINVAL;
goto finish;
}
if (version < 3 && (flags & BLOCK_FLAG_LAZY_REFCOUNTS)) {
error_setg(errp, "Lazy refcounts only supported with compatibility "
"level 1.1 and above (use compat=1.1 or greater)");
return -EINVAL;
ret = -EINVAL;
goto finish;
}
ret = qcow2_create2(filename, sectors, backing_file, backing_fmt, flags,
cluster_size, prealloc, options, version, &local_err);
cluster_size, prealloc, opts, version, &local_err);
if (local_err) {
error_propagate(errp, local_err);
}
finish:
g_free(backing_file);
g_free(backing_fmt);
g_free(buf);
return ret;
}
@@ -2198,64 +2201,72 @@ static int qcow2_downgrade(BlockDriverState *bs, int target_version)
return 0;
}
static int qcow2_amend_options(BlockDriverState *bs,
QEMUOptionParameter *options)
static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts)
{
BDRVQcowState *s = bs->opaque;
int old_version = s->qcow_version, new_version = old_version;
uint64_t new_size = 0;
const char *backing_file = NULL, *backing_format = NULL;
bool lazy_refcounts = s->use_lazy_refcounts;
const char *compat = NULL;
uint64_t cluster_size = s->cluster_size;
bool encrypt;
int ret;
int i;
QemuOptDesc *desc = opts->list->desc;
for (i = 0; options[i].name; i++)
{
if (!options[i].assigned) {
while (desc && desc->name) {
if (!qemu_opt_find(opts, desc->name)) {
/* only change explicitly defined options */
desc++;
continue;
}
if (!strcmp(options[i].name, "compat")) {
if (!options[i].value.s) {
if (!strcmp(desc->name, "compat")) {
compat = qemu_opt_get(opts, "compat");
if (!compat) {
/* preserve default */
} else if (!strcmp(options[i].value.s, "0.10")) {
} else if (!strcmp(compat, "0.10")) {
new_version = 2;
} else if (!strcmp(options[i].value.s, "1.1")) {
} else if (!strcmp(compat, "1.1")) {
new_version = 3;
} else {
fprintf(stderr, "Unknown compatibility level %s.\n",
options[i].value.s);
fprintf(stderr, "Unknown compatibility level %s.\n", compat);
return -EINVAL;
}
} else if (!strcmp(options[i].name, "preallocation")) {
} else if (!strcmp(desc->name, "preallocation")) {
fprintf(stderr, "Cannot change preallocation mode.\n");
return -ENOTSUP;
} else if (!strcmp(options[i].name, "size")) {
new_size = options[i].value.n;
} else if (!strcmp(options[i].name, "backing_file")) {
backing_file = options[i].value.s;
} else if (!strcmp(options[i].name, "backing_fmt")) {
backing_format = options[i].value.s;
} else if (!strcmp(options[i].name, "encryption")) {
if ((options[i].value.n != !!s->crypt_method)) {
} else if (!strcmp(desc->name, "size")) {
new_size = qemu_opt_get_size(opts, "size", 0);
} else if (!strcmp(desc->name, "backing_file")) {
backing_file = qemu_opt_get(opts, "backing_file");
} else if (!strcmp(desc->name, "backing_fmt")) {
backing_format = qemu_opt_get(opts, "backing_fmt");
} else if (!strcmp(desc->name, "encryption")) {
encrypt = qemu_opt_get_bool(opts, "encryption", s->crypt_method);
if (encrypt != !!s->crypt_method) {
fprintf(stderr, "Changing the encryption flag is not "
"supported.\n");
return -ENOTSUP;
}
} else if (!strcmp(options[i].name, "cluster_size")) {
if (options[i].value.n != s->cluster_size) {
} else if (!strcmp(desc->name, "cluster_size")) {
cluster_size = qemu_opt_get_size(opts, "cluster_size",
cluster_size);
if (cluster_size != s->cluster_size) {
fprintf(stderr, "Changing the cluster size is not "
"supported.\n");
return -ENOTSUP;
}
} else if (!strcmp(options[i].name, "lazy_refcounts")) {
lazy_refcounts = options[i].value.n;
} else if (!strcmp(desc->name, "lazy_refcounts")) {
lazy_refcounts = qemu_opt_get_bool(opts, "lazy_refcounts",
lazy_refcounts);
} else {
/* if this assertion fails, this probably means a new option was
* added without having it covered here */
assert(false);
}
desc++;
}
if (new_version != old_version) {
@@ -2324,49 +2335,55 @@ static int qcow2_amend_options(BlockDriverState *bs,
return 0;
}
static QEMUOptionParameter qcow2_create_options[] = {
{
.name = BLOCK_OPT_SIZE,
.type = OPT_SIZE,
.help = "Virtual disk size"
},
{
.name = BLOCK_OPT_COMPAT_LEVEL,
.type = OPT_STRING,
.help = "Compatibility level (0.10 or 1.1)"
},
{
.name = BLOCK_OPT_BACKING_FILE,
.type = OPT_STRING,
.help = "File name of a base image"
},
{
.name = BLOCK_OPT_BACKING_FMT,
.type = OPT_STRING,
.help = "Image format of the base image"
},
{
.name = BLOCK_OPT_ENCRYPT,
.type = OPT_FLAG,
.help = "Encrypt the image"
},
{
.name = BLOCK_OPT_CLUSTER_SIZE,
.type = OPT_SIZE,
.help = "qcow2 cluster size",
.value = { .n = DEFAULT_CLUSTER_SIZE },
},
{
.name = BLOCK_OPT_PREALLOC,
.type = OPT_STRING,
.help = "Preallocation mode (allowed values: off, metadata)"
},
{
.name = BLOCK_OPT_LAZY_REFCOUNTS,
.type = OPT_FLAG,
.help = "Postpone refcount updates",
},
{ NULL }
static QemuOptsList qcow2_create_opts = {
.name = "qcow2-create-opts",
.head = QTAILQ_HEAD_INITIALIZER(qcow2_create_opts.head),
.desc = {
{
.name = BLOCK_OPT_SIZE,
.type = QEMU_OPT_SIZE,
.help = "Virtual disk size"
},
{
.name = BLOCK_OPT_COMPAT_LEVEL,
.type = QEMU_OPT_STRING,
.help = "Compatibility level (0.10 or 1.1)"
},
{
.name = BLOCK_OPT_BACKING_FILE,
.type = QEMU_OPT_STRING,
.help = "File name of a base image"
},
{
.name = BLOCK_OPT_BACKING_FMT,
.type = QEMU_OPT_STRING,
.help = "Image format of the base image"
},
{
.name = BLOCK_OPT_ENCRYPT,
.type = QEMU_OPT_BOOL,
.help = "Encrypt the image",
.def_value_str = "off"
},
{
.name = BLOCK_OPT_CLUSTER_SIZE,
.type = QEMU_OPT_SIZE,
.help = "qcow2 cluster size",
.def_value_str = stringify(DEFAULT_CLUSTER_SIZE)
},
{
.name = BLOCK_OPT_PREALLOC,
.type = QEMU_OPT_STRING,
.help = "Preallocation mode (allowed values: off, metadata)"
},
{
.name = BLOCK_OPT_LAZY_REFCOUNTS,
.type = QEMU_OPT_BOOL,
.help = "Postpone refcount updates",
.def_value_str = "off"
},
{ /* end of list */ }
}
};
static BlockDriver bdrv_qcow2 = {
@@ -2394,8 +2411,8 @@ static BlockDriver bdrv_qcow2 = {
.bdrv_snapshot_goto = qcow2_snapshot_goto,
.bdrv_snapshot_delete = qcow2_snapshot_delete,
.bdrv_snapshot_list = qcow2_snapshot_list,
.bdrv_snapshot_load_tmp = qcow2_snapshot_load_tmp,
.bdrv_get_info = qcow2_get_info,
.bdrv_snapshot_load_tmp = qcow2_snapshot_load_tmp,
.bdrv_get_info = qcow2_get_info,
.bdrv_get_specific_info = qcow2_get_specific_info,
.bdrv_save_vmstate = qcow2_save_vmstate,
@@ -2406,9 +2423,9 @@ static BlockDriver bdrv_qcow2 = {
.bdrv_refresh_limits = qcow2_refresh_limits,
.bdrv_invalidate_cache = qcow2_invalidate_cache,
.create_options = qcow2_create_options,
.bdrv_check = qcow2_check,
.bdrv_amend_options = qcow2_amend_options,
.create_opts = &qcow2_create_opts,
.bdrv_check = qcow2_check,
.bdrv_amend_options = qcow2_amend_options,
};
static void bdrv_qcow2_init(void)

View File

@@ -173,7 +173,7 @@ int qed_read_l1_table_sync(BDRVQEDState *s)
qed_read_table(s, s->header.l1_table_offset,
s->l1_table, qed_sync_cb, &ret);
while (ret == -EINPROGRESS) {
qemu_aio_wait();
aio_poll(bdrv_get_aio_context(s->bs), true);
}
return ret;
@@ -194,7 +194,7 @@ int qed_write_l1_table_sync(BDRVQEDState *s, unsigned int index,
qed_write_l1_table(s, index, n, qed_sync_cb, &ret);
while (ret == -EINPROGRESS) {
qemu_aio_wait();
aio_poll(bdrv_get_aio_context(s->bs), true);
}
return ret;
@@ -267,7 +267,7 @@ int qed_read_l2_table_sync(BDRVQEDState *s, QEDRequest *request, uint64_t offset
qed_read_l2_table(s, request, offset, qed_sync_cb, &ret);
while (ret == -EINPROGRESS) {
qemu_aio_wait();
aio_poll(bdrv_get_aio_context(s->bs), true);
}
return ret;
@@ -289,7 +289,7 @@ int qed_write_l2_table_sync(BDRVQEDState *s, QEDRequest *request,
qed_write_l2_table(s, request, index, n, flush, qed_sync_cb, &ret);
while (ret == -EINPROGRESS) {
qemu_aio_wait();
aio_poll(bdrv_get_aio_context(s->bs), true);
}
return ret;

View File

@@ -21,12 +21,13 @@
static void qed_aio_cancel(BlockDriverAIOCB *blockacb)
{
QEDAIOCB *acb = (QEDAIOCB *)blockacb;
AioContext *aio_context = bdrv_get_aio_context(blockacb->bs);
bool finished = false;
/* Wait for the request to finish */
acb->finished = &finished;
while (!finished) {
qemu_aio_wait();
aio_poll(aio_context, true);
}
}
@@ -373,6 +374,27 @@ static void bdrv_qed_rebind(BlockDriverState *bs)
s->bs = bs;
}
static void bdrv_qed_detach_aio_context(BlockDriverState *bs)
{
BDRVQEDState *s = bs->opaque;
qed_cancel_need_check_timer(s);
timer_free(s->need_check_timer);
}
static void bdrv_qed_attach_aio_context(BlockDriverState *bs,
AioContext *new_context)
{
BDRVQEDState *s = bs->opaque;
s->need_check_timer = aio_timer_new(new_context,
QEMU_CLOCK_VIRTUAL, SCALE_NS,
qed_need_check_timer_cb, s);
if (s->header.features & QED_F_NEED_CHECK) {
qed_start_need_check_timer(s);
}
}
static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags,
Error **errp)
{
@@ -496,8 +518,7 @@ static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags,
}
}
s->need_check_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
qed_need_check_timer_cb, s);
bdrv_qed_attach_aio_context(bs, bdrv_get_aio_context(bs));
out:
if (ret) {
@@ -528,8 +549,7 @@ static void bdrv_qed_close(BlockDriverState *bs)
{
BDRVQEDState *s = bs->opaque;
qed_cancel_need_check_timer(s);
timer_free(s->need_check_timer);
bdrv_qed_detach_aio_context(bs);
/* Ensure writes reach stable storage */
bdrv_flush(bs->file);
@@ -621,55 +641,53 @@ out:
return ret;
}
static int bdrv_qed_create(const char *filename, QEMUOptionParameter *options,
Error **errp)
static int bdrv_qed_create(const char *filename, QemuOpts *opts, Error **errp)
{
uint64_t image_size = 0;
uint32_t cluster_size = QED_DEFAULT_CLUSTER_SIZE;
uint32_t table_size = QED_DEFAULT_TABLE_SIZE;
const char *backing_file = NULL;
const char *backing_fmt = NULL;
char *backing_file = NULL;
char *backing_fmt = NULL;
int ret;
while (options && options->name) {
if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
image_size = options->value.n;
} else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
backing_file = options->value.s;
} else if (!strcmp(options->name, BLOCK_OPT_BACKING_FMT)) {
backing_fmt = options->value.s;
} else if (!strcmp(options->name, BLOCK_OPT_CLUSTER_SIZE)) {
if (options->value.n) {
cluster_size = options->value.n;
}
} else if (!strcmp(options->name, BLOCK_OPT_TABLE_SIZE)) {
if (options->value.n) {
table_size = options->value.n;
}
}
options++;
}
image_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
backing_fmt = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FMT);
cluster_size = qemu_opt_get_size_del(opts,
BLOCK_OPT_CLUSTER_SIZE,
QED_DEFAULT_CLUSTER_SIZE);
table_size = qemu_opt_get_size_del(opts, BLOCK_OPT_TABLE_SIZE,
QED_DEFAULT_TABLE_SIZE);
if (!qed_is_cluster_size_valid(cluster_size)) {
error_setg(errp, "QED cluster size must be within range [%u, %u] "
"and power of 2",
QED_MIN_CLUSTER_SIZE, QED_MAX_CLUSTER_SIZE);
return -EINVAL;
ret = -EINVAL;
goto finish;
}
if (!qed_is_table_size_valid(table_size)) {
error_setg(errp, "QED table size must be within range [%u, %u] "
"and power of 2",
QED_MIN_TABLE_SIZE, QED_MAX_TABLE_SIZE);
return -EINVAL;
ret = -EINVAL;
goto finish;
}
if (!qed_is_image_size_valid(image_size, cluster_size, table_size)) {
error_setg(errp, "QED image size must be a non-zero multiple of "
"cluster size and less than %" PRIu64 " bytes",
qed_max_image_size(cluster_size, table_size));
return -EINVAL;
ret = -EINVAL;
goto finish;
}
return qed_create(filename, cluster_size, image_size, table_size,
backing_file, backing_fmt, errp);
ret = qed_create(filename, cluster_size, image_size, table_size,
backing_file, backing_fmt, errp);
finish:
g_free(backing_file);
g_free(backing_fmt);
return ret;
}
typedef struct {
@@ -919,7 +937,8 @@ static void qed_aio_complete(QEDAIOCB *acb, int ret)
/* Arrange for a bh to invoke the completion function */
acb->bh_ret = ret;
acb->bh = qemu_bh_new(qed_aio_complete_bh, acb);
acb->bh = aio_bh_new(bdrv_get_aio_context(acb->common.bs),
qed_aio_complete_bh, acb);
qemu_bh_schedule(acb->bh);
/* Start next allocating write request waiting behind this one. Note that
@@ -1595,36 +1614,44 @@ static int bdrv_qed_check(BlockDriverState *bs, BdrvCheckResult *result,
return qed_check(s, result, !!fix);
}
static QEMUOptionParameter qed_create_options[] = {
{
.name = BLOCK_OPT_SIZE,
.type = OPT_SIZE,
.help = "Virtual disk size (in bytes)"
}, {
.name = BLOCK_OPT_BACKING_FILE,
.type = OPT_STRING,
.help = "File name of a base image"
}, {
.name = BLOCK_OPT_BACKING_FMT,
.type = OPT_STRING,
.help = "Image format of the base image"
}, {
.name = BLOCK_OPT_CLUSTER_SIZE,
.type = OPT_SIZE,
.help = "Cluster size (in bytes)",
.value = { .n = QED_DEFAULT_CLUSTER_SIZE },
}, {
.name = BLOCK_OPT_TABLE_SIZE,
.type = OPT_SIZE,
.help = "L1/L2 table size (in clusters)"
},
{ /* end of list */ }
static QemuOptsList qed_create_opts = {
.name = "qed-create-opts",
.head = QTAILQ_HEAD_INITIALIZER(qed_create_opts.head),
.desc = {
{
.name = BLOCK_OPT_SIZE,
.type = QEMU_OPT_SIZE,
.help = "Virtual disk size"
},
{
.name = BLOCK_OPT_BACKING_FILE,
.type = QEMU_OPT_STRING,
.help = "File name of a base image"
},
{
.name = BLOCK_OPT_BACKING_FMT,
.type = QEMU_OPT_STRING,
.help = "Image format of the base image"
},
{
.name = BLOCK_OPT_CLUSTER_SIZE,
.type = QEMU_OPT_SIZE,
.help = "Cluster size (in bytes)",
.def_value_str = stringify(QED_DEFAULT_CLUSTER_SIZE)
},
{
.name = BLOCK_OPT_TABLE_SIZE,
.type = QEMU_OPT_SIZE,
.help = "L1/L2 table size (in clusters)"
},
{ /* end of list */ }
}
};
static BlockDriver bdrv_qed = {
.format_name = "qed",
.instance_size = sizeof(BDRVQEDState),
.create_options = qed_create_options,
.create_opts = &qed_create_opts,
.bdrv_probe = bdrv_qed_probe,
.bdrv_rebind = bdrv_qed_rebind,
@@ -1644,6 +1671,8 @@ static BlockDriver bdrv_qed = {
.bdrv_change_backing_file = bdrv_qed_change_backing_file,
.bdrv_invalidate_cache = bdrv_qed_invalidate_cache,
.bdrv_check = bdrv_qed_check,
.bdrv_detach_aio_context = bdrv_qed_detach_aio_context,
.bdrv_attach_aio_context = bdrv_qed_attach_aio_context,
};
static void bdrv_qed_init(void)

View File

@@ -43,7 +43,7 @@
*
* All fields are little-endian on disk.
*/
#define QED_DEFAULT_CLUSTER_SIZE 65536
enum {
QED_MAGIC = 'Q' | 'E' << 8 | 'D' << 16 | '\0' << 24,
@@ -69,7 +69,6 @@ enum {
*/
QED_MIN_CLUSTER_SIZE = 4 * 1024, /* in bytes */
QED_MAX_CLUSTER_SIZE = 64 * 1024 * 1024,
QED_DEFAULT_CLUSTER_SIZE = 64 * 1024,
/* Allocated clusters are tracked using a 2-level pagetable. Table size is
* a multiple of clusters so large maximum image sizes can be supported

View File

@@ -848,25 +848,49 @@ static void quorum_close(BlockDriverState *bs)
g_free(s->bs);
}
static void quorum_detach_aio_context(BlockDriverState *bs)
{
BDRVQuorumState *s = bs->opaque;
int i;
for (i = 0; i < s->num_children; i++) {
bdrv_detach_aio_context(s->bs[i]);
}
}
static void quorum_attach_aio_context(BlockDriverState *bs,
AioContext *new_context)
{
BDRVQuorumState *s = bs->opaque;
int i;
for (i = 0; i < s->num_children; i++) {
bdrv_attach_aio_context(s->bs[i], new_context);
}
}
static BlockDriver bdrv_quorum = {
.format_name = "quorum",
.protocol_name = "quorum",
.format_name = "quorum",
.protocol_name = "quorum",
.instance_size = sizeof(BDRVQuorumState),
.instance_size = sizeof(BDRVQuorumState),
.bdrv_file_open = quorum_open,
.bdrv_close = quorum_close,
.bdrv_file_open = quorum_open,
.bdrv_close = quorum_close,
.bdrv_co_flush_to_disk = quorum_co_flush,
.bdrv_co_flush_to_disk = quorum_co_flush,
.bdrv_getlength = quorum_getlength,
.bdrv_getlength = quorum_getlength,
.bdrv_aio_readv = quorum_aio_readv,
.bdrv_aio_writev = quorum_aio_writev,
.bdrv_invalidate_cache = quorum_invalidate_cache,
.bdrv_aio_readv = quorum_aio_readv,
.bdrv_aio_writev = quorum_aio_writev,
.bdrv_invalidate_cache = quorum_invalidate_cache,
.is_filter = true,
.bdrv_recurse_is_first_non_filter = quorum_recurse_is_first_non_filter,
.bdrv_detach_aio_context = quorum_detach_aio_context,
.bdrv_attach_aio_context = quorum_attach_aio_context,
.is_filter = true,
.bdrv_recurse_is_first_non_filter = quorum_recurse_is_first_non_filter,
};
static void bdrv_quorum_init(void)

View File

@@ -34,19 +34,27 @@
/* linux-aio.c - Linux native implementation */
#ifdef CONFIG_LINUX_AIO
void *laio_init(void);
void laio_cleanup(void *s);
BlockDriverAIOCB *laio_submit(BlockDriverState *bs, void *aio_ctx, int fd,
int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
BlockDriverCompletionFunc *cb, void *opaque, int type);
void laio_detach_aio_context(void *s, AioContext *old_context);
void laio_attach_aio_context(void *s, AioContext *new_context);
#endif
#ifdef _WIN32
typedef struct QEMUWin32AIOState QEMUWin32AIOState;
QEMUWin32AIOState *win32_aio_init(void);
void win32_aio_cleanup(QEMUWin32AIOState *aio);
int win32_aio_attach(QEMUWin32AIOState *aio, HANDLE hfile);
BlockDriverAIOCB *win32_aio_submit(BlockDriverState *bs,
QEMUWin32AIOState *aio, HANDLE hfile,
int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
BlockDriverCompletionFunc *cb, void *opaque, int type);
void win32_aio_detach_aio_context(QEMUWin32AIOState *aio,
AioContext *old_context);
void win32_aio_attach_aio_context(QEMUWin32AIOState *aio,
AioContext *new_context);
#endif
#endif /* QEMU_RAW_AIO_H */

View File

@@ -307,6 +307,29 @@ static void raw_parse_flags(int bdrv_flags, int *open_flags)
}
}
static void raw_detach_aio_context(BlockDriverState *bs)
{
#ifdef CONFIG_LINUX_AIO
BDRVRawState *s = bs->opaque;
if (s->use_aio) {
laio_detach_aio_context(s->aio_ctx, bdrv_get_aio_context(bs));
}
#endif
}
static void raw_attach_aio_context(BlockDriverState *bs,
AioContext *new_context)
{
#ifdef CONFIG_LINUX_AIO
BDRVRawState *s = bs->opaque;
if (s->use_aio) {
laio_attach_aio_context(s->aio_ctx, new_context);
}
#endif
}
#ifdef CONFIG_LINUX_AIO
static int raw_set_aio(void **aio_ctx, int *use_aio, int bdrv_flags)
{
@@ -447,6 +470,8 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
}
#endif
raw_attach_aio_context(bs, bdrv_get_aio_context(bs));
ret = 0;
fail:
if (filename && (bdrv_flags & BDRV_O_TEMPORARY)) {
@@ -1059,6 +1084,14 @@ static BlockDriverAIOCB *raw_aio_flush(BlockDriverState *bs,
static void raw_close(BlockDriverState *bs)
{
BDRVRawState *s = bs->opaque;
raw_detach_aio_context(bs);
#ifdef CONFIG_LINUX_AIO
if (s->use_aio) {
laio_cleanup(s->aio_ctx);
}
#endif
if (s->fd >= 0) {
qemu_close(s->fd);
s->fd = -1;
@@ -1240,8 +1273,7 @@ static int64_t raw_get_allocated_file_size(BlockDriverState *bs)
return (int64_t)st.st_blocks * 512;
}
static int raw_create(const char *filename, QEMUOptionParameter *options,
Error **errp)
static int raw_create(const char *filename, QemuOpts *opts, Error **errp)
{
int fd;
int result = 0;
@@ -1250,12 +1282,8 @@ static int raw_create(const char *filename, QEMUOptionParameter *options,
strstart(filename, "file:", &filename);
/* Read out options */
while (options && options->name) {
if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
total_size = options->value.n / BDRV_SECTOR_SIZE;
}
options++;
}
total_size =
qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / BDRV_SECTOR_SIZE;
fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
0644);
@@ -1440,13 +1468,17 @@ static int raw_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
return 0;
}
static QEMUOptionParameter raw_create_options[] = {
{
.name = BLOCK_OPT_SIZE,
.type = OPT_SIZE,
.help = "Virtual disk size"
},
{ NULL }
static QemuOptsList raw_create_opts = {
.name = "raw-create-opts",
.head = QTAILQ_HEAD_INITIALIZER(raw_create_opts.head),
.desc = {
{
.name = BLOCK_OPT_SIZE,
.type = QEMU_OPT_SIZE,
.help = "Virtual disk size"
},
{ /* end of list */ }
}
};
static BlockDriver bdrv_file = {
@@ -1478,7 +1510,10 @@ static BlockDriver bdrv_file = {
.bdrv_get_allocated_file_size
= raw_get_allocated_file_size,
.create_options = raw_create_options,
.bdrv_detach_aio_context = raw_detach_aio_context,
.bdrv_attach_aio_context = raw_attach_aio_context,
.create_opts = &raw_create_opts,
};
/***********************************************/
@@ -1799,7 +1834,7 @@ static coroutine_fn int hdev_co_write_zeroes(BlockDriverState *bs,
return -ENOTSUP;
}
static int hdev_create(const char *filename, QEMUOptionParameter *options,
static int hdev_create(const char *filename, QemuOpts *opts,
Error **errp)
{
int fd;
@@ -1820,12 +1855,8 @@ static int hdev_create(const char *filename, QEMUOptionParameter *options,
(void)has_prefix;
/* Read out options */
while (options && options->name) {
if (!strcmp(options->name, "size")) {
total_size = options->value.n / BDRV_SECTOR_SIZE;
}
options++;
}
total_size =
qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / BDRV_SECTOR_SIZE;
fd = qemu_open(filename, O_WRONLY | O_BINARY);
if (fd < 0) {
@@ -1862,8 +1893,8 @@ static BlockDriver bdrv_host_device = {
.bdrv_reopen_prepare = raw_reopen_prepare,
.bdrv_reopen_commit = raw_reopen_commit,
.bdrv_reopen_abort = raw_reopen_abort,
.bdrv_create = hdev_create,
.create_options = raw_create_options,
.bdrv_create = hdev_create,
.create_opts = &raw_create_opts,
.bdrv_co_write_zeroes = hdev_co_write_zeroes,
.bdrv_aio_readv = raw_aio_readv,
@@ -1878,6 +1909,9 @@ static BlockDriver bdrv_host_device = {
.bdrv_get_allocated_file_size
= raw_get_allocated_file_size,
.bdrv_detach_aio_context = raw_detach_aio_context,
.bdrv_attach_aio_context = raw_attach_aio_context,
/* generic scsi device */
#ifdef __linux__
.bdrv_ioctl = hdev_ioctl,
@@ -2006,8 +2040,8 @@ static BlockDriver bdrv_host_floppy = {
.bdrv_reopen_prepare = raw_reopen_prepare,
.bdrv_reopen_commit = raw_reopen_commit,
.bdrv_reopen_abort = raw_reopen_abort,
.bdrv_create = hdev_create,
.create_options = raw_create_options,
.bdrv_create = hdev_create,
.create_opts = &raw_create_opts,
.bdrv_aio_readv = raw_aio_readv,
.bdrv_aio_writev = raw_aio_writev,
@@ -2020,6 +2054,9 @@ static BlockDriver bdrv_host_floppy = {
.bdrv_get_allocated_file_size
= raw_get_allocated_file_size,
.bdrv_detach_aio_context = raw_detach_aio_context,
.bdrv_attach_aio_context = raw_attach_aio_context,
/* removable device support */
.bdrv_is_inserted = floppy_is_inserted,
.bdrv_media_changed = floppy_media_changed,
@@ -2131,8 +2168,8 @@ static BlockDriver bdrv_host_cdrom = {
.bdrv_reopen_prepare = raw_reopen_prepare,
.bdrv_reopen_commit = raw_reopen_commit,
.bdrv_reopen_abort = raw_reopen_abort,
.bdrv_create = hdev_create,
.create_options = raw_create_options,
.bdrv_create = hdev_create,
.create_opts = &raw_create_opts,
.bdrv_aio_readv = raw_aio_readv,
.bdrv_aio_writev = raw_aio_writev,
@@ -2145,6 +2182,9 @@ static BlockDriver bdrv_host_cdrom = {
.bdrv_get_allocated_file_size
= raw_get_allocated_file_size,
.bdrv_detach_aio_context = raw_detach_aio_context,
.bdrv_attach_aio_context = raw_attach_aio_context,
/* removable device support */
.bdrv_is_inserted = cdrom_is_inserted,
.bdrv_eject = cdrom_eject,
@@ -2263,7 +2303,7 @@ static BlockDriver bdrv_host_cdrom = {
.bdrv_reopen_commit = raw_reopen_commit,
.bdrv_reopen_abort = raw_reopen_abort,
.bdrv_create = hdev_create,
.create_options = raw_create_options,
.create_opts = &raw_create_opts,
.bdrv_aio_readv = raw_aio_readv,
.bdrv_aio_writev = raw_aio_writev,
@@ -2276,6 +2316,9 @@ static BlockDriver bdrv_host_cdrom = {
.bdrv_get_allocated_file_size
= raw_get_allocated_file_size,
.bdrv_detach_aio_context = raw_detach_aio_context,
.bdrv_attach_aio_context = raw_attach_aio_context,
/* removable device support */
.bdrv_is_inserted = cdrom_is_inserted,
.bdrv_eject = cdrom_eject,
@@ -2283,40 +2326,6 @@ static BlockDriver bdrv_host_cdrom = {
};
#endif /* __FreeBSD__ */
#ifdef CONFIG_LINUX_AIO
/**
* Return the file descriptor for Linux AIO
*
* This function is a layering violation and should be removed when it becomes
* possible to call the block layer outside the global mutex. It allows the
* caller to hijack the file descriptor so I/O can be performed outside the
* block layer.
*/
int raw_get_aio_fd(BlockDriverState *bs)
{
BDRVRawState *s;
if (!bs->drv) {
return -ENOMEDIUM;
}
if (bs->drv == bdrv_find_format("raw")) {
bs = bs->file;
}
/* raw-posix has several protocols so just check for raw_aio_readv */
if (bs->drv->bdrv_aio_readv != raw_aio_readv) {
return -ENOTSUP;
}
s = bs->opaque;
if (!s->use_aio) {
return -ENOTSUP;
}
return s->fd;
}
#endif /* CONFIG_LINUX_AIO */
static void bdrv_file_init(void)
{
/*

View File

@@ -36,8 +36,6 @@
#define FTYPE_CD 1
#define FTYPE_HARDDISK 2
static QEMUWin32AIOState *aio;
typedef struct RawWin32AIOData {
BlockDriverState *bs;
HANDLE hfile;
@@ -202,6 +200,25 @@ static int set_sparse(int fd)
NULL, 0, NULL, 0, &returned, NULL);
}
static void raw_detach_aio_context(BlockDriverState *bs)
{
BDRVRawState *s = bs->opaque;
if (s->aio) {
win32_aio_detach_aio_context(s->aio, bdrv_get_aio_context(bs));
}
}
static void raw_attach_aio_context(BlockDriverState *bs,
AioContext *new_context)
{
BDRVRawState *s = bs->opaque;
if (s->aio) {
win32_aio_attach_aio_context(s->aio, new_context);
}
}
static void raw_probe_alignment(BlockDriverState *bs)
{
BDRVRawState *s = bs->opaque;
@@ -300,15 +317,6 @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags,
raw_parse_flags(flags, &access_flags, &overlapped);
if ((flags & BDRV_O_NATIVE_AIO) && aio == NULL) {
aio = win32_aio_init();
if (aio == NULL) {
error_setg(errp, "Could not initialize AIO");
ret = -EINVAL;
goto fail;
}
}
if (filename[0] && filename[1] == ':') {
snprintf(s->drive_path, sizeof(s->drive_path), "%c:\\", filename[0]);
} else if (filename[0] == '\\' && filename[1] == '\\') {
@@ -335,13 +343,23 @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags,
}
if (flags & BDRV_O_NATIVE_AIO) {
ret = win32_aio_attach(aio, s->hfile);
s->aio = win32_aio_init();
if (s->aio == NULL) {
CloseHandle(s->hfile);
error_setg(errp, "Could not initialize AIO");
ret = -EINVAL;
goto fail;
}
ret = win32_aio_attach(s->aio, s->hfile);
if (ret < 0) {
win32_aio_cleanup(s->aio);
CloseHandle(s->hfile);
error_setg_errno(errp, -ret, "Could not enable AIO");
goto fail;
}
s->aio = aio;
win32_aio_attach_aio_context(s->aio, bdrv_get_aio_context(bs));
}
raw_probe_alignment(bs);
@@ -389,6 +407,13 @@ static BlockDriverAIOCB *raw_aio_flush(BlockDriverState *bs,
static void raw_close(BlockDriverState *bs)
{
BDRVRawState *s = bs->opaque;
if (s->aio) {
win32_aio_detach_aio_context(s->aio, bdrv_get_aio_context(bs));
win32_aio_cleanup(s->aio);
s->aio = NULL;
}
CloseHandle(s->hfile);
if (bs->open_flags & BDRV_O_TEMPORARY) {
unlink(bs->filename);
@@ -478,8 +503,7 @@ static int64_t raw_get_allocated_file_size(BlockDriverState *bs)
return st.st_size;
}
static int raw_create(const char *filename, QEMUOptionParameter *options,
Error **errp)
static int raw_create(const char *filename, QemuOpts *opts, Error **errp)
{
int fd;
int64_t total_size = 0;
@@ -487,12 +511,8 @@ static int raw_create(const char *filename, QEMUOptionParameter *options,
strstart(filename, "file:", &filename);
/* Read out options */
while (options && options->name) {
if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
total_size = options->value.n / 512;
}
options++;
}
total_size =
qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0) / 512;
fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
0644);
@@ -506,13 +526,18 @@ static int raw_create(const char *filename, QEMUOptionParameter *options,
return 0;
}
static QEMUOptionParameter raw_create_options[] = {
{
.name = BLOCK_OPT_SIZE,
.type = OPT_SIZE,
.help = "Virtual disk size"
},
{ NULL }
static QemuOptsList raw_create_opts = {
.name = "raw-create-opts",
.head = QTAILQ_HEAD_INITIALIZER(raw_create_opts.head),
.desc = {
{
.name = BLOCK_OPT_SIZE,
.type = QEMU_OPT_SIZE,
.help = "Virtual disk size"
},
{ /* end of list */ }
}
};
static BlockDriver bdrv_file = {
@@ -521,9 +546,9 @@ static BlockDriver bdrv_file = {
.instance_size = sizeof(BDRVRawState),
.bdrv_needs_filename = true,
.bdrv_parse_filename = raw_parse_filename,
.bdrv_file_open = raw_open,
.bdrv_close = raw_close,
.bdrv_create = raw_create,
.bdrv_file_open = raw_open,
.bdrv_close = raw_close,
.bdrv_create = raw_create,
.bdrv_has_zero_init = bdrv_has_zero_init_1,
.bdrv_aio_readv = raw_aio_readv,
@@ -535,7 +560,7 @@ static BlockDriver bdrv_file = {
.bdrv_get_allocated_file_size
= raw_get_allocated_file_size,
.create_options = raw_create_options,
.create_opts = &raw_create_opts,
};
/***********************************************/
@@ -684,6 +709,9 @@ static BlockDriver bdrv_host_device = {
.bdrv_aio_writev = raw_aio_writev,
.bdrv_aio_flush = raw_aio_flush,
.bdrv_detach_aio_context = raw_detach_aio_context,
.bdrv_attach_aio_context = raw_attach_aio_context,
.bdrv_getlength = raw_getlength,
.has_variable_length = true,

View File

@@ -29,13 +29,17 @@
#include "block/block_int.h"
#include "qemu/option.h"
static QEMUOptionParameter raw_create_options[] = {
{
.name = BLOCK_OPT_SIZE,
.type = OPT_SIZE,
.help = "Virtual disk size"
},
{ 0 }
static QemuOptsList raw_create_opts = {
.name = "raw-create-opts",
.head = QTAILQ_HEAD_INITIALIZER(raw_create_opts.head),
.desc = {
{
.name = BLOCK_OPT_SIZE,
.type = QEMU_OPT_SIZE,
.help = "Virtual disk size"
},
{ /* end of list */ }
}
};
static int raw_reopen_prepare(BDRVReopenState *reopen_state,
@@ -139,13 +143,12 @@ static int raw_has_zero_init(BlockDriverState *bs)
return bdrv_has_zero_init(bs->file);
}
static int raw_create(const char *filename, QEMUOptionParameter *options,
Error **errp)
static int raw_create(const char *filename, QemuOpts *opts, Error **errp)
{
Error *local_err = NULL;
int ret;
ret = bdrv_create_file(filename, options, &local_err);
ret = bdrv_create_file(filename, opts, &local_err);
if (local_err) {
error_propagate(errp, local_err);
}
@@ -194,7 +197,7 @@ static BlockDriver bdrv_raw = {
.bdrv_lock_medium = &raw_lock_medium,
.bdrv_ioctl = &raw_ioctl,
.bdrv_aio_ioctl = &raw_aio_ioctl,
.create_options = &raw_create_options[0],
.create_opts = &raw_create_opts,
.bdrv_has_zero_init = &raw_has_zero_init
};

View File

@@ -289,8 +289,7 @@ static int qemu_rbd_set_conf(rados_t cluster, const char *conf, Error **errp)
return ret;
}
static int qemu_rbd_create(const char *filename, QEMUOptionParameter *options,
Error **errp)
static int qemu_rbd_create(const char *filename, QemuOpts *opts, Error **errp)
{
Error *local_err = NULL;
int64_t bytes = 0;
@@ -315,24 +314,18 @@ static int qemu_rbd_create(const char *filename, QEMUOptionParameter *options,
}
/* Read out options */
while (options && options->name) {
if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
bytes = options->value.n;
} else if (!strcmp(options->name, BLOCK_OPT_CLUSTER_SIZE)) {
if (options->value.n) {
objsize = options->value.n;
if ((objsize - 1) & objsize) { /* not a power of 2? */
error_setg(errp, "obj size needs to be power of 2");
return -EINVAL;
}
if (objsize < 4096) {
error_setg(errp, "obj size too small");
return -EINVAL;
}
obj_order = ffs(objsize) - 1;
}
bytes = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
objsize = qemu_opt_get_size_del(opts, BLOCK_OPT_CLUSTER_SIZE, 0);
if (objsize) {
if ((objsize - 1) & objsize) { /* not a power of 2? */
error_setg(errp, "obj size needs to be power of 2");
return -EINVAL;
}
options++;
if (objsize < 4096) {
error_setg(errp, "obj size too small");
return -EINVAL;
}
obj_order = ffs(objsize) - 1;
}
clientname = qemu_rbd_parse_clientname(conf, clientname_buf);
@@ -555,7 +548,7 @@ static void qemu_rbd_aio_cancel(BlockDriverAIOCB *blockacb)
acb->cancelled = 1;
while (acb->status == -EINPROGRESS) {
qemu_aio_wait();
aio_poll(bdrv_get_aio_context(acb->common.bs), true);
}
qemu_aio_release(acb);
@@ -588,7 +581,8 @@ static void rbd_finish_aiocb(rbd_completion_t c, RADOSCB *rcb)
rcb->ret = rbd_aio_get_return_value(c);
rbd_aio_release(c);
acb->bh = qemu_bh_new(rbd_finish_bh, rcb);
acb->bh = aio_bh_new(bdrv_get_aio_context(acb->common.bs),
rbd_finish_bh, rcb);
qemu_bh_schedule(acb->bh);
}
@@ -684,13 +678,16 @@ static BlockDriverAIOCB *rbd_start_aio(BlockDriverState *bs,
}
if (r < 0) {
goto failed;
goto failed_completion;
}
return &acb->common;
failed_completion:
rbd_aio_release(c);
failed:
g_free(rcb);
qemu_vfree(acb->bounce);
qemu_aio_release(acb);
return NULL;
}
@@ -907,18 +904,22 @@ static BlockDriverAIOCB* qemu_rbd_aio_discard(BlockDriverState *bs,
}
#endif
static QEMUOptionParameter qemu_rbd_create_options[] = {
{
.name = BLOCK_OPT_SIZE,
.type = OPT_SIZE,
.help = "Virtual disk size"
},
{
.name = BLOCK_OPT_CLUSTER_SIZE,
.type = OPT_SIZE,
.help = "RBD object size"
},
{NULL}
static QemuOptsList qemu_rbd_create_opts = {
.name = "rbd-create-opts",
.head = QTAILQ_HEAD_INITIALIZER(qemu_rbd_create_opts.head),
.desc = {
{
.name = BLOCK_OPT_SIZE,
.type = QEMU_OPT_SIZE,
.help = "Virtual disk size"
},
{
.name = BLOCK_OPT_CLUSTER_SIZE,
.type = QEMU_OPT_SIZE,
.help = "RBD object size"
},
{ /* end of list */ }
}
};
static BlockDriver bdrv_rbd = {
@@ -930,7 +931,7 @@ static BlockDriver bdrv_rbd = {
.bdrv_create = qemu_rbd_create,
.bdrv_has_zero_init = bdrv_has_zero_init_1,
.bdrv_get_info = qemu_rbd_getinfo,
.create_options = qemu_rbd_create_options,
.create_opts = &qemu_rbd_create_opts,
.bdrv_getlength = qemu_rbd_getlength,
.bdrv_truncate = qemu_rbd_truncate,
.protocol_name = "rbd",

View File

@@ -200,6 +200,8 @@ typedef struct SheepdogInode {
uint32_t data_vdi_id[MAX_DATA_OBJS];
} SheepdogInode;
#define SD_INODE_HEADER_SIZE offsetof(SheepdogInode, data_vdi_id)
/*
* 64 bit FNV-1a non-zero initial basis
*/
@@ -282,6 +284,7 @@ typedef struct AIOReq {
unsigned int data_len;
uint8_t flags;
uint32_t id;
bool create;
QLIST_ENTRY(AIOReq) aio_siblings;
} AIOReq;
@@ -314,6 +317,7 @@ struct SheepdogAIOCB {
typedef struct BDRVSheepdogState {
BlockDriverState *bs;
AioContext *aio_context;
SheepdogInode inode;
@@ -404,7 +408,7 @@ static const char * sd_strerror(int err)
static inline AIOReq *alloc_aio_req(BDRVSheepdogState *s, SheepdogAIOCB *acb,
uint64_t oid, unsigned int data_len,
uint64_t offset, uint8_t flags,
uint64_t offset, uint8_t flags, bool create,
uint64_t base_oid, unsigned int iov_offset)
{
AIOReq *aio_req;
@@ -418,6 +422,7 @@ static inline AIOReq *alloc_aio_req(BDRVSheepdogState *s, SheepdogAIOCB *acb,
aio_req->data_len = data_len;
aio_req->flags = flags;
aio_req->id = s->aioreq_seq_num++;
aio_req->create = create;
acb->nr_pending++;
return aio_req;
@@ -496,7 +501,7 @@ static void sd_aio_cancel(BlockDriverAIOCB *blockacb)
sd_finish_aiocb(acb);
return;
}
qemu_aio_wait();
aio_poll(s->aio_context, true);
}
}
@@ -578,6 +583,7 @@ static void restart_co_req(void *opaque)
typedef struct SheepdogReqCo {
int sockfd;
AioContext *aio_context;
SheepdogReq *hdr;
void *data;
unsigned int *wlen;
@@ -598,14 +604,14 @@ static coroutine_fn void do_co_req(void *opaque)
unsigned int *rlen = srco->rlen;
co = qemu_coroutine_self();
qemu_aio_set_fd_handler(sockfd, NULL, restart_co_req, co);
aio_set_fd_handler(srco->aio_context, sockfd, NULL, restart_co_req, co);
ret = send_co_req(sockfd, hdr, data, wlen);
if (ret < 0) {
goto out;
}
qemu_aio_set_fd_handler(sockfd, restart_co_req, NULL, co);
aio_set_fd_handler(srco->aio_context, sockfd, restart_co_req, NULL, co);
ret = qemu_co_recv(sockfd, hdr, sizeof(*hdr));
if (ret != sizeof(*hdr)) {
@@ -630,18 +636,19 @@ static coroutine_fn void do_co_req(void *opaque)
out:
/* there is at most one request for this sockfd, so it is safe to
* set each handler to NULL. */
qemu_aio_set_fd_handler(sockfd, NULL, NULL, NULL);
aio_set_fd_handler(srco->aio_context, sockfd, NULL, NULL, NULL);
srco->ret = ret;
srco->finished = true;
}
static int do_req(int sockfd, SheepdogReq *hdr, void *data,
unsigned int *wlen, unsigned int *rlen)
static int do_req(int sockfd, AioContext *aio_context, SheepdogReq *hdr,
void *data, unsigned int *wlen, unsigned int *rlen)
{
Coroutine *co;
SheepdogReqCo srco = {
.sockfd = sockfd,
.aio_context = aio_context,
.hdr = hdr,
.data = data,
.wlen = wlen,
@@ -656,7 +663,7 @@ static int do_req(int sockfd, SheepdogReq *hdr, void *data,
co = qemu_coroutine_create(do_co_req);
qemu_coroutine_enter(co, &srco);
while (!srco.finished) {
qemu_aio_wait();
aio_poll(aio_context, true);
}
}
@@ -664,8 +671,8 @@ static int do_req(int sockfd, SheepdogReq *hdr, void *data,
}
static void coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
struct iovec *iov, int niov, bool create,
enum AIOCBState aiocb_type);
struct iovec *iov, int niov,
enum AIOCBState aiocb_type);
static void coroutine_fn resend_aioreq(BDRVSheepdogState *s, AIOReq *aio_req);
static int reload_inode(BDRVSheepdogState *s, uint32_t snapid, const char *tag);
static int get_sheep_fd(BDRVSheepdogState *s, Error **errp);
@@ -698,7 +705,7 @@ static void coroutine_fn send_pending_req(BDRVSheepdogState *s, uint64_t oid)
/* move aio_req from pending list to inflight one */
QLIST_REMOVE(aio_req, aio_siblings);
QLIST_INSERT_HEAD(&s->inflight_aio_head, aio_req, aio_siblings);
add_aio_request(s, aio_req, acb->qiov->iov, acb->qiov->niov, false,
add_aio_request(s, aio_req, acb->qiov->iov, acb->qiov->niov,
acb->aiocb_type);
}
}
@@ -709,7 +716,7 @@ static coroutine_fn void reconnect_to_sdog(void *opaque)
BDRVSheepdogState *s = opaque;
AIOReq *aio_req, *next;
qemu_aio_set_fd_handler(s->fd, NULL, NULL, NULL);
aio_set_fd_handler(s->aio_context, s->fd, NULL, NULL, NULL);
close(s->fd);
s->fd = -1;
@@ -797,7 +804,7 @@ static void coroutine_fn aio_read_response(void *opaque)
}
idx = data_oid_to_idx(aio_req->oid);
if (s->inode.data_vdi_id[idx] != s->inode.vdi_id) {
if (aio_req->create) {
/*
* If the object is newly created one, we need to update
* the vdi object (metadata object). min_dirty_data_idx
@@ -922,7 +929,7 @@ static int get_sheep_fd(BDRVSheepdogState *s, Error **errp)
return fd;
}
qemu_aio_set_fd_handler(fd, co_read_response, NULL, s);
aio_set_fd_handler(s->aio_context, fd, co_read_response, NULL, s);
return fd;
}
@@ -1092,7 +1099,7 @@ static int find_vdi_name(BDRVSheepdogState *s, const char *filename,
hdr.snapid = snapid;
hdr.flags = SD_FLAG_CMD_WRITE;
ret = do_req(fd, (SheepdogReq *)&hdr, buf, &wlen, &rlen);
ret = do_req(fd, s->aio_context, (SheepdogReq *)&hdr, buf, &wlen, &rlen);
if (ret) {
error_setg_errno(errp, -ret, "cannot get vdi info");
goto out;
@@ -1117,8 +1124,8 @@ out:
}
static void coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
struct iovec *iov, int niov, bool create,
enum AIOCBState aiocb_type)
struct iovec *iov, int niov,
enum AIOCBState aiocb_type)
{
int nr_copies = s->inode.nr_copies;
SheepdogObjReq hdr;
@@ -1129,6 +1136,7 @@ static void coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
uint64_t offset = aio_req->offset;
uint8_t flags = aio_req->flags;
uint64_t old_oid = aio_req->base_oid;
bool create = aio_req->create;
if (!nr_copies) {
error_report("bug");
@@ -1173,7 +1181,8 @@ static void coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
qemu_co_mutex_lock(&s->lock);
s->co_send = qemu_coroutine_self();
qemu_aio_set_fd_handler(s->fd, co_read_response, co_write_request, s);
aio_set_fd_handler(s->aio_context, s->fd,
co_read_response, co_write_request, s);
socket_set_cork(s->fd, 1);
/* send a header */
@@ -1191,12 +1200,13 @@ static void coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
}
out:
socket_set_cork(s->fd, 0);
qemu_aio_set_fd_handler(s->fd, co_read_response, NULL, s);
aio_set_fd_handler(s->aio_context, s->fd, co_read_response, NULL, s);
s->co_send = NULL;
qemu_co_mutex_unlock(&s->lock);
}
static int read_write_object(int fd, char *buf, uint64_t oid, uint8_t copies,
static int read_write_object(int fd, AioContext *aio_context, char *buf,
uint64_t oid, uint8_t copies,
unsigned int datalen, uint64_t offset,
bool write, bool create, uint32_t cache_flags)
{
@@ -1229,7 +1239,7 @@ static int read_write_object(int fd, char *buf, uint64_t oid, uint8_t copies,
hdr.offset = offset;
hdr.copies = copies;
ret = do_req(fd, (SheepdogReq *)&hdr, buf, &wlen, &rlen);
ret = do_req(fd, aio_context, (SheepdogReq *)&hdr, buf, &wlen, &rlen);
if (ret) {
error_report("failed to send a request to the sheep");
return ret;
@@ -1244,19 +1254,23 @@ static int read_write_object(int fd, char *buf, uint64_t oid, uint8_t copies,
}
}
static int read_object(int fd, char *buf, uint64_t oid, uint8_t copies,
static int read_object(int fd, AioContext *aio_context, char *buf,
uint64_t oid, uint8_t copies,
unsigned int datalen, uint64_t offset,
uint32_t cache_flags)
{
return read_write_object(fd, buf, oid, copies, datalen, offset, false,
return read_write_object(fd, aio_context, buf, oid, copies,
datalen, offset, false,
false, cache_flags);
}
static int write_object(int fd, char *buf, uint64_t oid, uint8_t copies,
static int write_object(int fd, AioContext *aio_context, char *buf,
uint64_t oid, uint8_t copies,
unsigned int datalen, uint64_t offset, bool create,
uint32_t cache_flags)
{
return read_write_object(fd, buf, oid, copies, datalen, offset, true,
return read_write_object(fd, aio_context, buf, oid, copies,
datalen, offset, true,
create, cache_flags);
}
@@ -1275,7 +1289,7 @@ static int reload_inode(BDRVSheepdogState *s, uint32_t snapid, const char *tag)
return -EIO;
}
inode = g_malloc(sizeof(s->inode));
inode = g_malloc(SD_INODE_HEADER_SIZE);
ret = find_vdi_name(s, s->name, snapid, tag, &vid, false, &local_err);
if (ret) {
@@ -1284,14 +1298,15 @@ static int reload_inode(BDRVSheepdogState *s, uint32_t snapid, const char *tag)
goto out;
}
ret = read_object(fd, (char *)inode, vid_to_vdi_oid(vid),
s->inode.nr_copies, sizeof(*inode), 0, s->cache_flags);
ret = read_object(fd, s->aio_context, (char *)inode, vid_to_vdi_oid(vid),
s->inode.nr_copies, SD_INODE_HEADER_SIZE, 0,
s->cache_flags);
if (ret < 0) {
goto out;
}
if (inode->vdi_id != s->inode.vdi_id) {
memcpy(&s->inode, inode, sizeof(s->inode));
memcpy(&s->inode, inode, SD_INODE_HEADER_SIZE);
}
out:
@@ -1315,6 +1330,7 @@ static bool check_simultaneous_create(BDRVSheepdogState *s, AIOReq *aio_req)
DPRINTF("simultaneous create to %" PRIx64 "\n", aio_req->oid);
aio_req->flags = 0;
aio_req->base_oid = 0;
aio_req->create = false;
QLIST_REMOVE(aio_req, aio_siblings);
QLIST_INSERT_HEAD(&s->pending_aio_head, aio_req, aio_siblings);
return true;
@@ -1327,7 +1343,8 @@ static bool check_simultaneous_create(BDRVSheepdogState *s, AIOReq *aio_req)
static void coroutine_fn resend_aioreq(BDRVSheepdogState *s, AIOReq *aio_req)
{
SheepdogAIOCB *acb = aio_req->aiocb;
bool create = false;
aio_req->create = false;
/* check whether this request becomes a CoW one */
if (acb->aiocb_type == AIOCB_WRITE_UDATA && is_data_obj(aio_req->oid)) {
@@ -1345,20 +1362,36 @@ static void coroutine_fn resend_aioreq(BDRVSheepdogState *s, AIOReq *aio_req)
aio_req->base_oid = vid_to_data_oid(s->inode.data_vdi_id[idx], idx);
aio_req->flags |= SD_FLAG_CMD_COW;
}
create = true;
aio_req->create = true;
}
out:
if (is_data_obj(aio_req->oid)) {
add_aio_request(s, aio_req, acb->qiov->iov, acb->qiov->niov, create,
add_aio_request(s, aio_req, acb->qiov->iov, acb->qiov->niov,
acb->aiocb_type);
} else {
struct iovec iov;
iov.iov_base = &s->inode;
iov.iov_len = sizeof(s->inode);
add_aio_request(s, aio_req, &iov, 1, false, AIOCB_WRITE_UDATA);
add_aio_request(s, aio_req, &iov, 1, AIOCB_WRITE_UDATA);
}
}
static void sd_detach_aio_context(BlockDriverState *bs)
{
BDRVSheepdogState *s = bs->opaque;
aio_set_fd_handler(s->aio_context, s->fd, NULL, NULL, NULL);
}
static void sd_attach_aio_context(BlockDriverState *bs,
AioContext *new_context)
{
BDRVSheepdogState *s = bs->opaque;
s->aio_context = new_context;
aio_set_fd_handler(new_context, s->fd, co_read_response, NULL, s);
}
/* TODO Convert to fine grained options */
static QemuOptsList runtime_opts = {
.name = "sheepdog",
@@ -1387,6 +1420,7 @@ static int sd_open(BlockDriverState *bs, QDict *options, int flags,
const char *filename;
s->bs = bs;
s->aio_context = bdrv_get_aio_context(bs);
opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err);
@@ -1448,8 +1482,8 @@ static int sd_open(BlockDriverState *bs, QDict *options, int flags,
}
buf = g_malloc(SD_INODE_SIZE);
ret = read_object(fd, buf, vid_to_vdi_oid(vid), 0, SD_INODE_SIZE, 0,
s->cache_flags);
ret = read_object(fd, s->aio_context, buf, vid_to_vdi_oid(vid),
0, SD_INODE_SIZE, 0, s->cache_flags);
closesocket(fd);
@@ -1469,7 +1503,7 @@ static int sd_open(BlockDriverState *bs, QDict *options, int flags,
g_free(buf);
return 0;
out:
qemu_aio_set_fd_handler(s->fd, NULL, NULL, NULL);
aio_set_fd_handler(bdrv_get_aio_context(bs), s->fd, NULL, NULL, NULL);
if (s->fd >= 0) {
closesocket(s->fd);
}
@@ -1512,7 +1546,7 @@ static int do_sd_create(BDRVSheepdogState *s, uint32_t *vdi_id, int snapshot,
hdr.copy_policy = s->inode.copy_policy;
hdr.copies = s->inode.nr_copies;
ret = do_req(fd, (SheepdogReq *)&hdr, buf, &wlen, &rlen);
ret = do_req(fd, s->aio_context, (SheepdogReq *)&hdr, buf, &wlen, &rlen);
closesocket(fd);
@@ -1636,12 +1670,13 @@ static int parse_redundancy(BDRVSheepdogState *s, const char *opt)
return 0;
}
static int sd_create(const char *filename, QEMUOptionParameter *options,
static int sd_create(const char *filename, QemuOpts *opts,
Error **errp)
{
int ret = 0;
uint32_t vid = 0;
char *backing_file = NULL;
char *buf = NULL;
BDRVSheepdogState *s;
char tag[SD_MAX_VDI_TAG_LEN];
uint32_t snapid;
@@ -1660,33 +1695,27 @@ static int sd_create(const char *filename, QEMUOptionParameter *options,
goto out;
}
while (options && options->name) {
if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
s->inode.vdi_size = options->value.n;
} else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
backing_file = options->value.s;
} else if (!strcmp(options->name, BLOCK_OPT_PREALLOC)) {
if (!options->value.s || !strcmp(options->value.s, "off")) {
prealloc = false;
} else if (!strcmp(options->value.s, "full")) {
prealloc = true;
} else {
error_setg(errp, "Invalid preallocation mode: '%s'",
options->value.s);
ret = -EINVAL;
goto out;
}
} else if (!strcmp(options->name, BLOCK_OPT_REDUNDANCY)) {
if (options->value.s) {
ret = parse_redundancy(s, options->value.s);
if (ret < 0) {
error_setg(errp, "Invalid redundancy mode: '%s'",
options->value.s);
goto out;
}
}
s->inode.vdi_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
buf = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);
if (!buf || !strcmp(buf, "off")) {
prealloc = false;
} else if (!strcmp(buf, "full")) {
prealloc = true;
} else {
error_setg(errp, "Invalid preallocation mode: '%s'", buf);
ret = -EINVAL;
goto out;
}
g_free(buf);
buf = qemu_opt_get_del(opts, BLOCK_OPT_REDUNDANCY);
if (buf) {
ret = parse_redundancy(s, buf);
if (ret < 0) {
error_setg(errp, "Invalid redundancy mode: '%s'", buf);
goto out;
}
options++;
}
if (s->inode.vdi_size > SD_MAX_VDI_SIZE) {
@@ -1736,6 +1765,8 @@ static int sd_create(const char *filename, QEMUOptionParameter *options,
ret = sd_prealloc(filename, errp);
}
out:
g_free(backing_file);
g_free(buf);
g_free(s);
return ret;
}
@@ -1766,7 +1797,8 @@ static void sd_close(BlockDriverState *bs)
hdr.data_length = wlen;
hdr.flags = SD_FLAG_CMD_WRITE;
ret = do_req(fd, (SheepdogReq *)&hdr, s->name, &wlen, &rlen);
ret = do_req(fd, s->aio_context, (SheepdogReq *)&hdr,
s->name, &wlen, &rlen);
closesocket(fd);
@@ -1775,7 +1807,7 @@ static void sd_close(BlockDriverState *bs)
error_report("%s, %s", sd_strerror(rsp->result), s->name);
}
qemu_aio_set_fd_handler(s->fd, NULL, NULL, NULL);
aio_set_fd_handler(bdrv_get_aio_context(bs), s->fd, NULL, NULL, NULL);
closesocket(s->fd);
g_free(s->host_spec);
}
@@ -1812,8 +1844,9 @@ static int sd_truncate(BlockDriverState *bs, int64_t offset)
/* we don't need to update entire object */
datalen = SD_INODE_SIZE - sizeof(s->inode.data_vdi_id);
s->inode.vdi_size = offset;
ret = write_object(fd, (char *)&s->inode, vid_to_vdi_oid(s->inode.vdi_id),
s->inode.nr_copies, datalen, 0, false, s->cache_flags);
ret = write_object(fd, s->aio_context, (char *)&s->inode,
vid_to_vdi_oid(s->inode.vdi_id), s->inode.nr_copies,
datalen, 0, false, s->cache_flags);
close(fd);
if (ret < 0) {
@@ -1849,9 +1882,9 @@ static void coroutine_fn sd_write_done(SheepdogAIOCB *acb)
iov.iov_base = &s->inode;
iov.iov_len = sizeof(s->inode);
aio_req = alloc_aio_req(s, acb, vid_to_vdi_oid(s->inode.vdi_id),
data_len, offset, 0, 0, offset);
data_len, offset, 0, false, 0, offset);
QLIST_INSERT_HEAD(&s->inflight_aio_head, aio_req, aio_siblings);
add_aio_request(s, aio_req, &iov, 1, false, AIOCB_WRITE_UDATA);
add_aio_request(s, aio_req, &iov, 1, AIOCB_WRITE_UDATA);
acb->aio_done_func = sd_finish_aiocb;
acb->aiocb_type = AIOCB_WRITE_UDATA;
@@ -1882,7 +1915,8 @@ static bool sd_delete(BDRVSheepdogState *s)
return false;
}
ret = do_req(fd, (SheepdogReq *)&hdr, s->name, &wlen, &rlen);
ret = do_req(fd, s->aio_context, (SheepdogReq *)&hdr,
s->name, &wlen, &rlen);
closesocket(fd);
if (ret) {
return false;
@@ -1939,8 +1973,8 @@ static int sd_create_branch(BDRVSheepdogState *s)
goto out;
}
ret = read_object(fd, buf, vid_to_vdi_oid(vid), s->inode.nr_copies,
SD_INODE_SIZE, 0, s->cache_flags);
ret = read_object(fd, s->aio_context, buf, vid_to_vdi_oid(vid),
s->inode.nr_copies, SD_INODE_SIZE, 0, s->cache_flags);
closesocket(fd);
@@ -2049,7 +2083,8 @@ static int coroutine_fn sd_co_rw_vector(void *p)
DPRINTF("new oid %" PRIx64 "\n", oid);
}
aio_req = alloc_aio_req(s, acb, oid, len, offset, flags, old_oid, done);
aio_req = alloc_aio_req(s, acb, oid, len, offset, flags, create,
old_oid, done);
QLIST_INSERT_HEAD(&s->inflight_aio_head, aio_req, aio_siblings);
if (create) {
@@ -2058,7 +2093,7 @@ static int coroutine_fn sd_co_rw_vector(void *p)
}
}
add_aio_request(s, aio_req, acb->qiov->iov, acb->qiov->niov, create,
add_aio_request(s, aio_req, acb->qiov->iov, acb->qiov->niov,
acb->aiocb_type);
done:
offset = 0;
@@ -2138,9 +2173,9 @@ static int coroutine_fn sd_co_flush_to_disk(BlockDriverState *bs)
acb->aio_done_func = sd_finish_aiocb;
aio_req = alloc_aio_req(s, acb, vid_to_vdi_oid(s->inode.vdi_id),
0, 0, 0, 0, 0);
0, 0, 0, false, 0, 0);
QLIST_INSERT_HEAD(&s->inflight_aio_head, aio_req, aio_siblings);
add_aio_request(s, aio_req, NULL, 0, false, acb->aiocb_type);
add_aio_request(s, aio_req, NULL, 0, acb->aiocb_type);
qemu_coroutine_yield();
return acb->ret;
@@ -2187,8 +2222,9 @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
goto cleanup;
}
ret = write_object(fd, (char *)&s->inode, vid_to_vdi_oid(s->inode.vdi_id),
s->inode.nr_copies, datalen, 0, false, s->cache_flags);
ret = write_object(fd, s->aio_context, (char *)&s->inode,
vid_to_vdi_oid(s->inode.vdi_id), s->inode.nr_copies,
datalen, 0, false, s->cache_flags);
if (ret < 0) {
error_report("failed to write snapshot's inode.");
goto cleanup;
@@ -2203,8 +2239,9 @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
goto cleanup;
}
ret = read_object(fd, (char *)inode, vid_to_vdi_oid(new_vid),
s->inode.nr_copies, datalen, 0, s->cache_flags);
ret = read_object(fd, s->aio_context, (char *)inode,
vid_to_vdi_oid(new_vid), s->inode.nr_copies, datalen, 0,
s->cache_flags);
if (ret < 0) {
error_report("failed to read new inode info. %s", strerror(errno));
@@ -2311,7 +2348,8 @@ static int sd_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab)
req.opcode = SD_OP_READ_VDIS;
req.data_length = max;
ret = do_req(fd, (SheepdogReq *)&req, vdi_inuse, &wlen, &rlen);
ret = do_req(fd, s->aio_context, (SheepdogReq *)&req,
vdi_inuse, &wlen, &rlen);
closesocket(fd);
if (ret) {
@@ -2338,7 +2376,8 @@ static int sd_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab)
}
/* we don't need to read entire object */
ret = read_object(fd, (char *)&inode, vid_to_vdi_oid(vid),
ret = read_object(fd, s->aio_context, (char *)&inode,
vid_to_vdi_oid(vid),
0, SD_INODE_SIZE - sizeof(inode.data_vdi_id), 0,
s->cache_flags);
@@ -2403,11 +2442,11 @@ static int do_load_save_vmstate(BDRVSheepdogState *s, uint8_t *data,
create = (offset == 0);
if (load) {
ret = read_object(fd, (char *)data, vmstate_oid,
ret = read_object(fd, s->aio_context, (char *)data, vmstate_oid,
s->inode.nr_copies, data_len, offset,
s->cache_flags);
} else {
ret = write_object(fd, (char *)data, vmstate_oid,
ret = write_object(fd, s->aio_context, (char *)data, vmstate_oid,
s->inode.nr_copies, data_len, offset, create,
s->cache_flags);
}
@@ -2529,28 +2568,32 @@ static int64_t sd_get_allocated_file_size(BlockDriverState *bs)
return size;
}
static QEMUOptionParameter sd_create_options[] = {
{
.name = BLOCK_OPT_SIZE,
.type = OPT_SIZE,
.help = "Virtual disk size"
},
{
.name = BLOCK_OPT_BACKING_FILE,
.type = OPT_STRING,
.help = "File name of a base image"
},
{
.name = BLOCK_OPT_PREALLOC,
.type = OPT_STRING,
.help = "Preallocation mode (allowed values: off, full)"
},
{
.name = BLOCK_OPT_REDUNDANCY,
.type = OPT_STRING,
.help = "Redundancy of the image"
},
{ NULL }
static QemuOptsList sd_create_opts = {
.name = "sheepdog-create-opts",
.head = QTAILQ_HEAD_INITIALIZER(sd_create_opts.head),
.desc = {
{
.name = BLOCK_OPT_SIZE,
.type = QEMU_OPT_SIZE,
.help = "Virtual disk size"
},
{
.name = BLOCK_OPT_BACKING_FILE,
.type = QEMU_OPT_STRING,
.help = "File name of a base image"
},
{
.name = BLOCK_OPT_PREALLOC,
.type = QEMU_OPT_STRING,
.help = "Preallocation mode (allowed values: off, full)"
},
{
.name = BLOCK_OPT_REDUNDANCY,
.type = QEMU_OPT_STRING,
.help = "Redundancy of the image"
},
{ /* end of list */ }
}
};
static BlockDriver bdrv_sheepdog = {
@@ -2580,7 +2623,10 @@ static BlockDriver bdrv_sheepdog = {
.bdrv_save_vmstate = sd_save_vmstate,
.bdrv_load_vmstate = sd_load_vmstate,
.create_options = sd_create_options,
.bdrv_detach_aio_context = sd_detach_aio_context,
.bdrv_attach_aio_context = sd_attach_aio_context,
.create_opts = &sd_create_opts,
};
static BlockDriver bdrv_sheepdog_tcp = {
@@ -2610,7 +2656,10 @@ static BlockDriver bdrv_sheepdog_tcp = {
.bdrv_save_vmstate = sd_save_vmstate,
.bdrv_load_vmstate = sd_load_vmstate,
.create_options = sd_create_options,
.bdrv_detach_aio_context = sd_detach_aio_context,
.bdrv_attach_aio_context = sd_attach_aio_context,
.create_opts = &sd_create_opts,
};
static BlockDriver bdrv_sheepdog_unix = {
@@ -2640,7 +2689,10 @@ static BlockDriver bdrv_sheepdog_unix = {
.bdrv_save_vmstate = sd_save_vmstate,
.bdrv_load_vmstate = sd_load_vmstate,
.create_options = sd_create_options,
.bdrv_detach_aio_context = sd_detach_aio_context,
.bdrv_attach_aio_context = sd_attach_aio_context,
.create_opts = &sd_create_opts,
};
static void bdrv_sheepdog_init(void)

View File

@@ -675,17 +675,20 @@ static int ssh_file_open(BlockDriverState *bs, QDict *options, int bdrv_flags,
return ret;
}
static QEMUOptionParameter ssh_create_options[] = {
{
.name = BLOCK_OPT_SIZE,
.type = OPT_SIZE,
.help = "Virtual disk size"
},
{ NULL }
static QemuOptsList ssh_create_opts = {
.name = "ssh-create-opts",
.head = QTAILQ_HEAD_INITIALIZER(ssh_create_opts.head),
.desc = {
{
.name = BLOCK_OPT_SIZE,
.type = QEMU_OPT_SIZE,
.help = "Virtual disk size"
},
{ /* end of list */ }
}
};
static int ssh_create(const char *filename, QEMUOptionParameter *options,
Error **errp)
static int ssh_create(const char *filename, QemuOpts *opts, Error **errp)
{
int r, ret;
int64_t total_size = 0;
@@ -697,12 +700,7 @@ static int ssh_create(const char *filename, QEMUOptionParameter *options,
ssh_state_init(&s);
/* Get desired file size. */
while (options && options->name) {
if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
total_size = options->value.n;
}
options++;
}
total_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
DPRINTF("total_size=%" PRIi64, total_size);
uri_options = qdict_new();
@@ -773,7 +771,7 @@ static void restart_coroutine(void *opaque)
qemu_coroutine_enter(co, NULL);
}
static coroutine_fn void set_fd_handler(BDRVSSHState *s)
static coroutine_fn void set_fd_handler(BDRVSSHState *s, BlockDriverState *bs)
{
int r;
IOHandler *rd_handler = NULL, *wr_handler = NULL;
@@ -791,24 +789,26 @@ static coroutine_fn void set_fd_handler(BDRVSSHState *s)
DPRINTF("s->sock=%d rd_handler=%p wr_handler=%p", s->sock,
rd_handler, wr_handler);
qemu_aio_set_fd_handler(s->sock, rd_handler, wr_handler, co);
aio_set_fd_handler(bdrv_get_aio_context(bs), s->sock,
rd_handler, wr_handler, co);
}
static coroutine_fn void clear_fd_handler(BDRVSSHState *s)
static coroutine_fn void clear_fd_handler(BDRVSSHState *s,
BlockDriverState *bs)
{
DPRINTF("s->sock=%d", s->sock);
qemu_aio_set_fd_handler(s->sock, NULL, NULL, NULL);
aio_set_fd_handler(bdrv_get_aio_context(bs), s->sock, NULL, NULL, NULL);
}
/* A non-blocking call returned EAGAIN, so yield, ensuring the
* handlers are set up so that we'll be rescheduled when there is an
* interesting event on the socket.
*/
static coroutine_fn void co_yield(BDRVSSHState *s)
static coroutine_fn void co_yield(BDRVSSHState *s, BlockDriverState *bs)
{
set_fd_handler(s);
set_fd_handler(s, bs);
qemu_coroutine_yield();
clear_fd_handler(s);
clear_fd_handler(s, bs);
}
/* SFTP has a function `libssh2_sftp_seek64' which seeks to a position
@@ -838,7 +838,7 @@ static void ssh_seek(BDRVSSHState *s, int64_t offset, int flags)
}
}
static coroutine_fn int ssh_read(BDRVSSHState *s,
static coroutine_fn int ssh_read(BDRVSSHState *s, BlockDriverState *bs,
int64_t offset, size_t size,
QEMUIOVector *qiov)
{
@@ -871,7 +871,7 @@ static coroutine_fn int ssh_read(BDRVSSHState *s,
DPRINTF("sftp_read returned %zd", r);
if (r == LIBSSH2_ERROR_EAGAIN || r == LIBSSH2_ERROR_TIMEOUT) {
co_yield(s);
co_yield(s, bs);
goto again;
}
if (r < 0) {
@@ -906,14 +906,14 @@ static coroutine_fn int ssh_co_readv(BlockDriverState *bs,
int ret;
qemu_co_mutex_lock(&s->lock);
ret = ssh_read(s, sector_num * BDRV_SECTOR_SIZE,
ret = ssh_read(s, bs, sector_num * BDRV_SECTOR_SIZE,
nb_sectors * BDRV_SECTOR_SIZE, qiov);
qemu_co_mutex_unlock(&s->lock);
return ret;
}
static int ssh_write(BDRVSSHState *s,
static int ssh_write(BDRVSSHState *s, BlockDriverState *bs,
int64_t offset, size_t size,
QEMUIOVector *qiov)
{
@@ -941,7 +941,7 @@ static int ssh_write(BDRVSSHState *s,
DPRINTF("sftp_write returned %zd", r);
if (r == LIBSSH2_ERROR_EAGAIN || r == LIBSSH2_ERROR_TIMEOUT) {
co_yield(s);
co_yield(s, bs);
goto again;
}
if (r < 0) {
@@ -960,7 +960,7 @@ static int ssh_write(BDRVSSHState *s,
*/
if (r == 0) {
ssh_seek(s, offset + written, SSH_SEEK_WRITE|SSH_SEEK_FORCE);
co_yield(s);
co_yield(s, bs);
goto again;
}
@@ -988,7 +988,7 @@ static coroutine_fn int ssh_co_writev(BlockDriverState *bs,
int ret;
qemu_co_mutex_lock(&s->lock);
ret = ssh_write(s, sector_num * BDRV_SECTOR_SIZE,
ret = ssh_write(s, bs, sector_num * BDRV_SECTOR_SIZE,
nb_sectors * BDRV_SECTOR_SIZE, qiov);
qemu_co_mutex_unlock(&s->lock);
@@ -1009,7 +1009,7 @@ static void unsafe_flush_warning(BDRVSSHState *s, const char *what)
#ifdef HAS_LIBSSH2_SFTP_FSYNC
static coroutine_fn int ssh_flush(BDRVSSHState *s)
static coroutine_fn int ssh_flush(BDRVSSHState *s, BlockDriverState *bs)
{
int r;
@@ -1017,7 +1017,7 @@ static coroutine_fn int ssh_flush(BDRVSSHState *s)
again:
r = libssh2_sftp_fsync(s->sftp_handle);
if (r == LIBSSH2_ERROR_EAGAIN || r == LIBSSH2_ERROR_TIMEOUT) {
co_yield(s);
co_yield(s, bs);
goto again;
}
if (r == LIBSSH2_ERROR_SFTP_PROTOCOL &&
@@ -1039,7 +1039,7 @@ static coroutine_fn int ssh_co_flush(BlockDriverState *bs)
int ret;
qemu_co_mutex_lock(&s->lock);
ret = ssh_flush(s);
ret = ssh_flush(s, bs);
qemu_co_mutex_unlock(&s->lock);
return ret;
@@ -1082,7 +1082,7 @@ static BlockDriver bdrv_ssh = {
.bdrv_co_writev = ssh_co_writev,
.bdrv_getlength = ssh_getlength,
.bdrv_co_flush_to_disk = ssh_co_flush,
.create_options = ssh_create_options,
.create_opts = &ssh_create_opts,
};
static void bdrv_ssh_init(void)

View File

@@ -239,7 +239,6 @@ static void vdi_header_to_le(VdiHeader *header)
cpu_to_le32s(&header->block_extra);
cpu_to_le32s(&header->blocks_in_image);
cpu_to_le32s(&header->blocks_allocated);
cpu_to_le32s(&header->blocks_allocated);
uuid_convert(header->uuid_image);
uuid_convert(header->uuid_last_snap);
uuid_convert(header->uuid_link);
@@ -673,8 +672,7 @@ static int vdi_co_write(BlockDriverState *bs,
return ret;
}
static int vdi_create(const char *filename, QEMUOptionParameter *options,
Error **errp)
static int vdi_create(const char *filename, QemuOpts *opts, Error **errp)
{
int fd;
int result = 0;
@@ -689,25 +687,18 @@ static int vdi_create(const char *filename, QEMUOptionParameter *options,
logout("\n");
/* Read out options. */
while (options && options->name) {
if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
bytes = options->value.n;
bytes = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
#if defined(CONFIG_VDI_BLOCK_SIZE)
} else if (!strcmp(options->name, BLOCK_OPT_CLUSTER_SIZE)) {
if (options->value.n) {
/* TODO: Additional checks (SECTOR_SIZE * 2^n, ...). */
block_size = options->value.n;
}
/* TODO: Additional checks (SECTOR_SIZE * 2^n, ...). */
block_size = qemu_opt_get_size_del(opts,
BLOCK_OPT_CLUSTER_SIZE,
DEFAULT_CLUSTER_SIZE);
#endif
#if defined(CONFIG_VDI_STATIC_IMAGE)
} else if (!strcmp(options->name, BLOCK_OPT_STATIC)) {
if (options->value.n) {
image_type = VDI_TYPE_STATIC;
}
#endif
}
options++;
if (qemu_opt_get_bool_del(opts, BLOCK_OPT_STATIC, false)) {
image_type = VDI_TYPE_STATIC;
}
#endif
if (bytes > VDI_DISK_SIZE_MAX) {
result = -ENOTSUP;
@@ -802,29 +793,34 @@ static void vdi_close(BlockDriverState *bs)
error_free(s->migration_blocker);
}
static QEMUOptionParameter vdi_create_options[] = {
{
.name = BLOCK_OPT_SIZE,
.type = OPT_SIZE,
.help = "Virtual disk size"
},
static QemuOptsList vdi_create_opts = {
.name = "vdi-create-opts",
.head = QTAILQ_HEAD_INITIALIZER(vdi_create_opts.head),
.desc = {
{
.name = BLOCK_OPT_SIZE,
.type = QEMU_OPT_SIZE,
.help = "Virtual disk size"
},
#if defined(CONFIG_VDI_BLOCK_SIZE)
{
.name = BLOCK_OPT_CLUSTER_SIZE,
.type = OPT_SIZE,
.help = "VDI cluster (block) size",
.value = { .n = DEFAULT_CLUSTER_SIZE },
},
{
.name = BLOCK_OPT_CLUSTER_SIZE,
.type = QEMU_OPT_SIZE,
.help = "VDI cluster (block) size",
.def_value_str = stringify(DEFAULT_CLUSTER_SIZE)
},
#endif
#if defined(CONFIG_VDI_STATIC_IMAGE)
{
.name = BLOCK_OPT_STATIC,
.type = OPT_FLAG,
.help = "VDI static (pre-allocated) image"
},
{
.name = BLOCK_OPT_STATIC,
.type = QEMU_OPT_BOOL,
.help = "VDI static (pre-allocated) image",
.def_value_str = "off"
},
#endif
/* TODO: An additional option to set UUID values might be useful. */
{ NULL }
/* TODO: An additional option to set UUID values might be useful. */
{ /* end of list */ }
}
};
static BlockDriver bdrv_vdi = {
@@ -846,7 +842,7 @@ static BlockDriver bdrv_vdi = {
.bdrv_get_info = vdi_get_info,
.create_options = vdi_create_options,
.create_opts = &vdi_create_opts,
.bdrv_check = vdi_check,
};

View File

@@ -1723,8 +1723,7 @@ exit:
* .---- ~ ----------- ~ ------------ ~ ---------------- ~ -----------.
* 1MB
*/
static int vhdx_create(const char *filename, QEMUOptionParameter *options,
Error **errp)
static int vhdx_create(const char *filename, QemuOpts *opts, Error **errp)
{
int ret = 0;
uint64_t image_size = (uint64_t) 2 * GiB;
@@ -1737,24 +1736,15 @@ static int vhdx_create(const char *filename, QEMUOptionParameter *options,
gunichar2 *creator = NULL;
glong creator_items;
BlockDriverState *bs;
const char *type = NULL;
char *type = NULL;
VHDXImageType image_type;
Error *local_err = NULL;
while (options && options->name) {
if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
image_size = options->value.n;
} else if (!strcmp(options->name, VHDX_BLOCK_OPT_LOG_SIZE)) {
log_size = options->value.n;
} else if (!strcmp(options->name, VHDX_BLOCK_OPT_BLOCK_SIZE)) {
block_size = options->value.n;
} else if (!strcmp(options->name, BLOCK_OPT_SUBFMT)) {
type = options->value.s;
} else if (!strcmp(options->name, VHDX_BLOCK_OPT_ZERO)) {
use_zero_blocks = options->value.n != 0;
}
options++;
}
image_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
log_size = qemu_opt_get_size_del(opts, VHDX_BLOCK_OPT_LOG_SIZE, 0);
block_size = qemu_opt_get_size_del(opts, VHDX_BLOCK_OPT_BLOCK_SIZE, 0);
type = qemu_opt_get_del(opts, BLOCK_OPT_SUBFMT);
use_zero_blocks = qemu_opt_get_bool_del(opts, VHDX_BLOCK_OPT_ZERO, false);
if (image_size > VHDX_MAX_IMAGE_SIZE) {
error_setg_errno(errp, EINVAL, "Image size too large; max of 64TB");
@@ -1763,7 +1753,7 @@ static int vhdx_create(const char *filename, QEMUOptionParameter *options,
}
if (type == NULL) {
type = "dynamic";
type = g_strdup("dynamic");
}
if (!strcmp(type, "dynamic")) {
@@ -1803,7 +1793,7 @@ static int vhdx_create(const char *filename, QEMUOptionParameter *options,
block_size = block_size > VHDX_BLOCK_SIZE_MAX ? VHDX_BLOCK_SIZE_MAX :
block_size;
ret = bdrv_create_file(filename, options, &local_err);
ret = bdrv_create_file(filename, opts, &local_err);
if (ret < 0) {
error_propagate(errp, local_err);
goto exit;
@@ -1863,6 +1853,7 @@ static int vhdx_create(const char *filename, QEMUOptionParameter *options,
delete_and_exit:
bdrv_unref(bs);
exit:
g_free(type);
g_free(creator);
return ret;
}
@@ -1885,37 +1876,41 @@ static int vhdx_check(BlockDriverState *bs, BdrvCheckResult *result,
return 0;
}
static QEMUOptionParameter vhdx_create_options[] = {
{
.name = BLOCK_OPT_SIZE,
.type = OPT_SIZE,
.help = "Virtual disk size; max of 64TB."
},
{
.name = VHDX_BLOCK_OPT_LOG_SIZE,
.type = OPT_SIZE,
.value.n = 1 * MiB,
.help = "Log size; min 1MB."
},
{
.name = VHDX_BLOCK_OPT_BLOCK_SIZE,
.type = OPT_SIZE,
.value.n = 0,
.help = "Block Size; min 1MB, max 256MB. " \
"0 means auto-calculate based on image size."
},
{
.name = BLOCK_OPT_SUBFMT,
.type = OPT_STRING,
.help = "VHDX format type, can be either 'dynamic' or 'fixed'. "\
"Default is 'dynamic'."
},
{
.name = VHDX_BLOCK_OPT_ZERO,
.type = OPT_FLAG,
.help = "Force use of payload blocks of type 'ZERO'. Non-standard."
},
{ NULL }
static QemuOptsList vhdx_create_opts = {
.name = "vhdx-create-opts",
.head = QTAILQ_HEAD_INITIALIZER(vhdx_create_opts.head),
.desc = {
{
.name = BLOCK_OPT_SIZE,
.type = QEMU_OPT_SIZE,
.help = "Virtual disk size; max of 64TB."
},
{
.name = VHDX_BLOCK_OPT_LOG_SIZE,
.type = QEMU_OPT_SIZE,
.def_value_str = stringify(DEFAULT_LOG_SIZE),
.help = "Log size; min 1MB."
},
{
.name = VHDX_BLOCK_OPT_BLOCK_SIZE,
.type = QEMU_OPT_SIZE,
.def_value_str = stringify(0),
.help = "Block Size; min 1MB, max 256MB. " \
"0 means auto-calculate based on image size."
},
{
.name = BLOCK_OPT_SUBFMT,
.type = QEMU_OPT_STRING,
.help = "VHDX format type, can be either 'dynamic' or 'fixed'. "\
"Default is 'dynamic'."
},
{
.name = VHDX_BLOCK_OPT_ZERO,
.type = QEMU_OPT_BOOL,
.help = "Force use of payload blocks of type 'ZERO'. Non-standard."
},
{ NULL }
}
};
static BlockDriver bdrv_vhdx = {
@@ -1931,7 +1926,7 @@ static BlockDriver bdrv_vhdx = {
.bdrv_get_info = vhdx_get_info,
.bdrv_check = vhdx_check,
.create_options = vhdx_create_options,
.create_opts = &vhdx_create_opts,
};
static void bdrv_vhdx_init(void)

View File

@@ -23,6 +23,7 @@
#define GiB (MiB * 1024)
#define TiB ((uint64_t) GiB * 1024)
#define DEFAULT_LOG_SIZE 1048576 /* 1MiB */
/* Structures and fields present in the VHDX file */
/* The header section has the following blocks,

View File

@@ -1695,17 +1695,16 @@ static int filename_decompose(const char *filename, char *path, char *prefix,
return VMDK_OK;
}
static int vmdk_create(const char *filename, QEMUOptionParameter *options,
Error **errp)
static int vmdk_create(const char *filename, QemuOpts *opts, Error **errp)
{
int idx = 0;
BlockDriverState *new_bs = NULL;
Error *local_err = NULL;
char *desc = NULL;
int64_t total_size = 0, filesize;
const char *adapter_type = NULL;
const char *backing_file = NULL;
const char *fmt = NULL;
char *adapter_type = NULL;
char *backing_file = NULL;
char *fmt = NULL;
int flags = 0;
int ret = 0;
bool flat, split, compress;
@@ -1745,24 +1744,19 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options,
goto exit;
}
/* Read out options */
while (options && options->name) {
if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
total_size = options->value.n;
} else if (!strcmp(options->name, BLOCK_OPT_ADAPTER_TYPE)) {
adapter_type = options->value.s;
} else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
backing_file = options->value.s;
} else if (!strcmp(options->name, BLOCK_OPT_COMPAT6)) {
flags |= options->value.n ? BLOCK_FLAG_COMPAT6 : 0;
} else if (!strcmp(options->name, BLOCK_OPT_SUBFMT)) {
fmt = options->value.s;
} else if (!strcmp(options->name, BLOCK_OPT_ZEROED_GRAIN)) {
zeroed_grain |= options->value.n;
}
options++;
total_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
adapter_type = qemu_opt_get_del(opts, BLOCK_OPT_ADAPTER_TYPE);
backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
if (qemu_opt_get_bool_del(opts, BLOCK_OPT_COMPAT6, false)) {
flags |= BLOCK_FLAG_COMPAT6;
}
fmt = qemu_opt_get_del(opts, BLOCK_OPT_SUBFMT);
if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ZEROED_GRAIN, false)) {
zeroed_grain = true;
}
if (!adapter_type) {
adapter_type = "ide";
adapter_type = g_strdup("ide");
} else if (strcmp(adapter_type, "ide") &&
strcmp(adapter_type, "buslogic") &&
strcmp(adapter_type, "lsilogic") &&
@@ -1778,7 +1772,7 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options,
}
if (!fmt) {
/* Default format to monolithicSparse */
fmt = "monolithicSparse";
fmt = g_strdup("monolithicSparse");
} else if (strcmp(fmt, "monolithicFlat") &&
strcmp(fmt, "monolithicSparse") &&
strcmp(fmt, "twoGbMaxExtentSparse") &&
@@ -1879,7 +1873,7 @@ static int vmdk_create(const char *filename, QEMUOptionParameter *options,
if (!split && !flat) {
desc_offset = 0x200;
} else {
ret = bdrv_create_file(filename, options, &local_err);
ret = bdrv_create_file(filename, opts, &local_err);
if (ret < 0) {
error_propagate(errp, local_err);
goto exit;
@@ -1909,6 +1903,9 @@ exit:
if (new_bs) {
bdrv_unref(new_bs);
}
g_free(adapter_type);
g_free(backing_file);
g_free(fmt);
g_free(desc);
g_string_free(ext_desc_lines, true);
return ret;
@@ -2096,41 +2093,68 @@ static int vmdk_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
return 0;
}
static QEMUOptionParameter vmdk_create_options[] = {
{
.name = BLOCK_OPT_SIZE,
.type = OPT_SIZE,
.help = "Virtual disk size"
},
{
.name = BLOCK_OPT_ADAPTER_TYPE,
.type = OPT_STRING,
.help = "Virtual adapter type, can be one of "
"ide (default), lsilogic, buslogic or legacyESX"
},
{
.name = BLOCK_OPT_BACKING_FILE,
.type = OPT_STRING,
.help = "File name of a base image"
},
{
.name = BLOCK_OPT_COMPAT6,
.type = OPT_FLAG,
.help = "VMDK version 6 image"
},
{
.name = BLOCK_OPT_SUBFMT,
.type = OPT_STRING,
.help =
"VMDK flat extent format, can be one of "
"{monolithicSparse (default) | monolithicFlat | twoGbMaxExtentSparse | twoGbMaxExtentFlat | streamOptimized} "
},
{
.name = BLOCK_OPT_ZEROED_GRAIN,
.type = OPT_FLAG,
.help = "Enable efficient zero writes using the zeroed-grain GTE feature"
},
{ NULL }
static void vmdk_detach_aio_context(BlockDriverState *bs)
{
BDRVVmdkState *s = bs->opaque;
int i;
for (i = 0; i < s->num_extents; i++) {
bdrv_detach_aio_context(s->extents[i].file);
}
}
static void vmdk_attach_aio_context(BlockDriverState *bs,
AioContext *new_context)
{
BDRVVmdkState *s = bs->opaque;
int i;
for (i = 0; i < s->num_extents; i++) {
bdrv_attach_aio_context(s->extents[i].file, new_context);
}
}
static QemuOptsList vmdk_create_opts = {
.name = "vmdk-create-opts",
.head = QTAILQ_HEAD_INITIALIZER(vmdk_create_opts.head),
.desc = {
{
.name = BLOCK_OPT_SIZE,
.type = QEMU_OPT_SIZE,
.help = "Virtual disk size"
},
{
.name = BLOCK_OPT_ADAPTER_TYPE,
.type = QEMU_OPT_STRING,
.help = "Virtual adapter type, can be one of "
"ide (default), lsilogic, buslogic or legacyESX"
},
{
.name = BLOCK_OPT_BACKING_FILE,
.type = QEMU_OPT_STRING,
.help = "File name of a base image"
},
{
.name = BLOCK_OPT_COMPAT6,
.type = QEMU_OPT_BOOL,
.help = "VMDK version 6 image",
.def_value_str = "off"
},
{
.name = BLOCK_OPT_SUBFMT,
.type = QEMU_OPT_STRING,
.help =
"VMDK flat extent format, can be one of "
"{monolithicSparse (default) | monolithicFlat | twoGbMaxExtentSparse | twoGbMaxExtentFlat | streamOptimized} "
},
{
.name = BLOCK_OPT_ZEROED_GRAIN,
.type = QEMU_OPT_BOOL,
.help = "Enable efficient zero writes "
"using the zeroed-grain GTE feature"
},
{ /* end of list */ }
}
};
static BlockDriver bdrv_vmdk = {
@@ -2153,8 +2177,10 @@ static BlockDriver bdrv_vmdk = {
.bdrv_get_specific_info = vmdk_get_specific_info,
.bdrv_refresh_limits = vmdk_refresh_limits,
.bdrv_get_info = vmdk_get_info,
.bdrv_detach_aio_context = vmdk_detach_aio_context,
.bdrv_attach_aio_context = vmdk_attach_aio_context,
.create_options = vmdk_create_options,
.create_opts = &vmdk_create_opts,
};
static void bdrv_vmdk_init(void)

View File

@@ -738,12 +738,11 @@ static int create_fixed_disk(int fd, uint8_t *buf, int64_t total_size)
return ret;
}
static int vpc_create(const char *filename, QEMUOptionParameter *options,
Error **errp)
static int vpc_create(const char *filename, QemuOpts *opts, Error **errp)
{
uint8_t buf[1024];
VHDFooter *footer = (VHDFooter *) buf;
QEMUOptionParameter *disk_type_param;
char *disk_type_param;
int fd, i;
uint16_t cyls = 0;
uint8_t heads = 0;
@@ -754,16 +753,16 @@ static int vpc_create(const char *filename, QEMUOptionParameter *options,
int ret = -EIO;
/* Read out options */
total_size = get_option_parameter(options, BLOCK_OPT_SIZE)->value.n;
disk_type_param = get_option_parameter(options, BLOCK_OPT_SUBFMT);
if (disk_type_param && disk_type_param->value.s) {
if (!strcmp(disk_type_param->value.s, "dynamic")) {
total_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
disk_type_param = qemu_opt_get_del(opts, BLOCK_OPT_SUBFMT);
if (disk_type_param) {
if (!strcmp(disk_type_param, "dynamic")) {
disk_type = VHD_DYNAMIC;
} else if (!strcmp(disk_type_param->value.s, "fixed")) {
} else if (!strcmp(disk_type_param, "fixed")) {
disk_type = VHD_FIXED;
} else {
return -EINVAL;
ret = -EINVAL;
goto out;
}
} else {
disk_type = VHD_DYNAMIC;
@@ -772,7 +771,8 @@ static int vpc_create(const char *filename, QEMUOptionParameter *options,
/* Create the file */
fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
if (fd < 0) {
return -EIO;
ret = -EIO;
goto out;
}
/*
@@ -837,8 +837,10 @@ static int vpc_create(const char *filename, QEMUOptionParameter *options,
ret = create_fixed_disk(fd, buf, total_size);
}
fail:
fail:
qemu_close(fd);
out:
g_free(disk_type_param);
return ret;
}
@@ -866,20 +868,24 @@ static void vpc_close(BlockDriverState *bs)
error_free(s->migration_blocker);
}
static QEMUOptionParameter vpc_create_options[] = {
{
.name = BLOCK_OPT_SIZE,
.type = OPT_SIZE,
.help = "Virtual disk size"
},
{
.name = BLOCK_OPT_SUBFMT,
.type = OPT_STRING,
.help =
"Type of virtual hard disk format. Supported formats are "
"{dynamic (default) | fixed} "
},
{ NULL }
static QemuOptsList vpc_create_opts = {
.name = "vpc-create-opts",
.head = QTAILQ_HEAD_INITIALIZER(vpc_create_opts.head),
.desc = {
{
.name = BLOCK_OPT_SIZE,
.type = QEMU_OPT_SIZE,
.help = "Virtual disk size"
},
{
.name = BLOCK_OPT_SUBFMT,
.type = QEMU_OPT_STRING,
.help =
"Type of virtual hard disk format. Supported formats are "
"{dynamic (default) | fixed} "
},
{ /* end of list */ }
}
};
static BlockDriver bdrv_vpc = {
@@ -897,7 +903,7 @@ static BlockDriver bdrv_vpc = {
.bdrv_get_info = vpc_get_info,
.create_options = vpc_create_options,
.create_opts = &vpc_create_opts,
.bdrv_has_zero_init = vpc_has_zero_init,
};

View File

@@ -2910,8 +2910,8 @@ static BlockDriver vvfat_write_target = {
static int enable_write_target(BDRVVVFATState *s, Error **errp)
{
BlockDriver *bdrv_qcow;
QEMUOptionParameter *options;
BlockDriver *bdrv_qcow = NULL;
QemuOpts *opts = NULL;
int ret;
int size = sector2cluster(s, s->sector_count);
s->used_clusters = calloc(size, 1);
@@ -2926,12 +2926,12 @@ static int enable_write_target(BDRVVVFATState *s, Error **errp)
}
bdrv_qcow = bdrv_find_format("qcow");
options = parse_option_parameters("", bdrv_qcow->create_options, NULL);
set_option_parameter_int(options, BLOCK_OPT_SIZE, s->sector_count * 512);
set_option_parameter(options, BLOCK_OPT_BACKING_FILE, "fat:");
opts = qemu_opts_create(bdrv_qcow->create_opts, NULL, 0, &error_abort);
qemu_opt_set_number(opts, BLOCK_OPT_SIZE, s->sector_count * 512);
qemu_opt_set(opts, BLOCK_OPT_BACKING_FILE, "fat:");
ret = bdrv_create(bdrv_qcow, s->qcow_filename, options, errp);
free_option_parameters(options);
ret = bdrv_create(bdrv_qcow, s->qcow_filename, opts, errp);
qemu_opts_del(opts);
if (ret < 0) {
goto err;
}

View File

@@ -40,6 +40,7 @@ struct QEMUWin32AIOState {
HANDLE hIOCP;
EventNotifier e;
int count;
bool is_aio_context_attached;
};
typedef struct QEMUWin32AIOCB {
@@ -114,7 +115,7 @@ static void win32_aio_cancel(BlockDriverAIOCB *blockacb)
* wait for completion.
*/
while (!HasOverlappedIoCompleted(&waiocb->ov)) {
qemu_aio_wait();
aio_poll(bdrv_get_aio_context(blockacb->bs), true);
}
}
@@ -180,6 +181,20 @@ int win32_aio_attach(QEMUWin32AIOState *aio, HANDLE hfile)
}
}
void win32_aio_detach_aio_context(QEMUWin32AIOState *aio,
AioContext *old_context)
{
aio_set_event_notifier(old_context, &aio->e, NULL);
aio->is_aio_context_attached = false;
}
void win32_aio_attach_aio_context(QEMUWin32AIOState *aio,
AioContext *new_context)
{
aio->is_aio_context_attached = true;
aio_set_event_notifier(new_context, &aio->e, win32_aio_completion_cb);
}
QEMUWin32AIOState *win32_aio_init(void)
{
QEMUWin32AIOState *s;
@@ -194,8 +209,6 @@ QEMUWin32AIOState *win32_aio_init(void)
goto out_close_efd;
}
qemu_aio_set_event_notifier(&s->e, win32_aio_completion_cb);
return s;
out_close_efd:
@@ -204,3 +217,11 @@ out_free_state:
g_free(s);
return NULL;
}
void win32_aio_cleanup(QEMUWin32AIOState *aio)
{
assert(!aio->is_aio_context_attached);
CloseHandle(aio->hIOCP);
event_notifier_cleanup(&aio->e);
g_free(aio);
}

View File

@@ -106,7 +106,7 @@ void blockdev_auto_del(BlockDriverState *bs)
DriveInfo *dinfo = drive_get_by_blockdev(bs);
if (dinfo && dinfo->auto_del) {
drive_put_ref(dinfo);
drive_del(dinfo);
}
}
@@ -213,7 +213,7 @@ static void bdrv_format_print(void *opaque, const char *name)
error_printf(" %s", name);
}
static void drive_uninit(DriveInfo *dinfo)
void drive_del(DriveInfo *dinfo)
{
if (dinfo->opts) {
qemu_opts_del(dinfo->opts);
@@ -226,19 +226,6 @@ static void drive_uninit(DriveInfo *dinfo)
g_free(dinfo);
}
void drive_put_ref(DriveInfo *dinfo)
{
assert(dinfo->refcount);
if (--dinfo->refcount == 0) {
drive_uninit(dinfo);
}
}
void drive_get_ref(DriveInfo *dinfo)
{
dinfo->refcount++;
}
typedef struct {
QEMUBH *bh;
BlockDriverState *bs;
@@ -329,7 +316,6 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
Error **errp)
{
const char *buf;
const char *serial;
int ro = 0;
int bdrv_flags = 0;
int on_read_error, on_write_error;
@@ -371,8 +357,6 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
ro = qemu_opt_get_bool(opts, "read-only", 0);
copy_on_read = qemu_opt_get_bool(opts, "copy-on-read", false);
serial = qemu_opt_get(opts, "serial");
if ((buf = qemu_opt_get(opts, "discard")) != NULL) {
if (bdrv_parse_discard_flags(buf, &bdrv_flags) != 0) {
error_setg(errp, "invalid discard option");
@@ -500,10 +484,6 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts,
dinfo->bdrv->open_flags = snapshot ? BDRV_O_SNAPSHOT : 0;
dinfo->bdrv->read_only = ro;
dinfo->bdrv->detect_zeroes = detect_zeroes;
dinfo->refcount = 1;
if (serial != NULL) {
dinfo->serial = g_strdup(serial);
}
QTAILQ_INSERT_TAIL(&drives, dinfo, next);
bdrv_set_on_error(dinfo->bdrv, on_read_error, on_write_error);
@@ -629,6 +609,10 @@ QemuOptsList qemu_legacy_drive_opts = {
.name = "addr",
.type = QEMU_OPT_STRING,
.help = "pci address (virtio only)",
},{
.name = "serial",
.type = QEMU_OPT_STRING,
.help = "disk serial number",
},{
.name = "file",
.type = QEMU_OPT_STRING,
@@ -658,7 +642,7 @@ QemuOptsList qemu_legacy_drive_opts = {
},
};
DriveInfo *drive_init(QemuOpts *all_opts, BlockInterfaceType block_default_type)
DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)
{
const char *value;
DriveInfo *dinfo = NULL;
@@ -672,6 +656,7 @@ DriveInfo *drive_init(QemuOpts *all_opts, BlockInterfaceType block_default_type)
const char *werror, *rerror;
bool read_only = false;
bool copy_on_read;
const char *serial;
const char *filename;
Error *local_err = NULL;
@@ -875,6 +860,9 @@ DriveInfo *drive_init(QemuOpts *all_opts, BlockInterfaceType block_default_type)
goto fail;
}
/* Serial number */
serial = qemu_opt_get(legacy_opts, "serial");
/* no id supplied -> create one */
if (qemu_opts_id(all_opts) == NULL) {
char *new_id;
@@ -965,6 +953,8 @@ DriveInfo *drive_init(QemuOpts *all_opts, BlockInterfaceType block_default_type)
dinfo->unit = unit_id;
dinfo->devaddr = devaddr;
dinfo->serial = g_strdup(serial);
switch(type) {
case IF_IDE:
case IF_SCSI:
@@ -1703,6 +1693,7 @@ void qmp_block_set_io_throttle(const char *device, int64_t bps, int64_t bps_rd,
{
ThrottleConfig cfg;
BlockDriverState *bs;
AioContext *aio_context;
bs = bdrv_find(device);
if (!bs) {
@@ -1746,6 +1737,9 @@ void qmp_block_set_io_throttle(const char *device, int64_t bps, int64_t bps_rd,
return;
}
aio_context = bdrv_get_aio_context(bs);
aio_context_acquire(aio_context);
if (!bs->io_limits_enabled && throttle_enabled(&cfg)) {
bdrv_io_limits_enable(bs);
} else if (bs->io_limits_enabled && !throttle_enabled(&cfg)) {
@@ -1755,6 +1749,8 @@ void qmp_block_set_io_throttle(const char *device, int64_t bps, int64_t bps_rd,
if (bs->io_limits_enabled) {
bdrv_set_io_limits(bs, &cfg);
}
aio_context_release(aio_context);
}
int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
@@ -1791,7 +1787,7 @@ int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
bdrv_set_on_error(bs, BLOCKDEV_ON_ERROR_REPORT,
BLOCKDEV_ON_ERROR_REPORT);
} else {
drive_uninit(drive_get_by_blockdev(bs));
drive_del(drive_get_by_blockdev(bs));
}
return 0;
@@ -2334,9 +2330,9 @@ void qmp_blockdev_add(BlockdevOptions *options, Error **errp)
goto fail;
}
/* TODO Sort it out in raw-posix and drive_init: Reject aio=native with
/* TODO Sort it out in raw-posix and drive_new(): Reject aio=native with
* cache.direct=false instead of silently switching to aio=threads, except
* if called from drive_init.
* when called from drive_new().
*
* For now, simply forbidding the combination for all drivers will do. */
if (options->has_aio && options->aio == BLOCKDEV_AIO_OPTIONS_NATIVE) {
@@ -2368,7 +2364,7 @@ void qmp_blockdev_add(BlockdevOptions *options, Error **errp)
}
if (bdrv_key_required(dinfo->bdrv)) {
drive_uninit(dinfo);
drive_del(dinfo);
error_setg(errp, "blockdev-add doesn't support encrypted devices");
goto fail;
}
@@ -2431,10 +2427,6 @@ QemuOptsList qemu_common_drive_opts = {
.name = "format",
.type = QEMU_OPT_STRING,
.help = "disk format (raw, qcow2, ...)",
},{
.name = "serial",
.type = QEMU_OPT_STRING,
.help = "disk serial number",
},{
.name = "rerror",
.type = QEMU_OPT_STRING,

View File

@@ -1,7 +1,37 @@
{ TARGET_FREEBSD_NR___getcwd, "__getcwd", NULL, NULL, NULL },
/*
* FreeBSD strace list
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
{ TARGET_FREEBSD_NR___acl_aclcheck_fd, "__acl_aclcheck_fd", "%s(%d, %d, %#x)", NULL, NULL },
{ TARGET_FREEBSD_NR___acl_aclcheck_file, "__acl_aclcheck_file", "%s(\"%s\", %d, %#x)", NULL, NULL },
{ TARGET_FREEBSD_NR___acl_aclcheck_link, "__acl_aclcheck_link", "%s(\"%s\", %d, %#x)", NULL, NULL },
{ TARGET_FREEBSD_NR___acl_delete_fd, "__acl_delete_fd", "%s(%d, %d)", NULL, NULL },
{ TARGET_FREEBSD_NR___acl_delete_file, "__acl_delete_file", "%s(\"%s\", %d)", NULL, NULL },
{ TARGET_FREEBSD_NR___acl_delete_link, "__acl_delete_link", "%s(\"%s\", %d)", NULL, NULL },
{ TARGET_FREEBSD_NR___acl_get_fd, "__acl_get_fd", "%s(%d, %d, %#x)", NULL, NULL },
{ TARGET_FREEBSD_NR___acl_get_file, "__acl_get_file", "%s(\"%s\", %d, %#x)", NULL, NULL },
{ TARGET_FREEBSD_NR___acl_get_link, "__acl_get_link", "%s(\"%s\", %d, %#x)", NULL, NULL },
{ TARGET_FREEBSD_NR___acl_set_fd, "__acl_set_fd", "%s(%d, %d, %#x)", NULL, NULL },
{ TARGET_FREEBSD_NR___acl_set_file, "__acl_set_file", "%s(\"%s\", %d, %#x)", NULL, NULL },
{ TARGET_FREEBSD_NR___acl_set_link, "__acl_set_link", "%s(\"%s\", %d, %#x)", NULL, NULL },
{ TARGET_FREEBSD_NR___semctl, "__semctl", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR___syscall, "__syscall", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR___sysctl, "__sysctl", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR___sysctl, "__sysctl", NULL, print_sysctl, NULL },
{ TARGET_FREEBSD_NR__umtx_op, "_umtx_op", "%s(%#x, %d, %d, %#x, %#x)", NULL, NULL },
{ TARGET_FREEBSD_NR_accept, "accept", "%s(%d,%#x,%#x)", NULL, NULL },
{ TARGET_FREEBSD_NR_access, "access", "%s(\"%s\",%#o)", NULL, NULL },
{ TARGET_FREEBSD_NR_acct, "acct", NULL, NULL, NULL },
@@ -20,24 +50,41 @@
{ TARGET_FREEBSD_NR_connect, "connect", "%s(%d,%#x,%d)", NULL, NULL },
{ TARGET_FREEBSD_NR_dup, "dup", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_dup2, "dup2", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_eaccess, "eaccess", "%s(\"%s\",%#x)", NULL, NULL },
{ TARGET_FREEBSD_NR_execve, "execve", NULL, print_execve, NULL },
{ TARGET_FREEBSD_NR_exit, "exit", "%s(%d)\n", NULL, NULL },
{ TARGET_FREEBSD_NR_extattrctl, "extattrctl", "%s(\"%s\", %d, \"%s\", %d, \"%s\"", NULL, NULL },
{ TARGET_FREEBSD_NR_extattr_delete_fd, "extattr_delete_fd", "%s(%d, %d, \"%s\")", NULL, NULL },
{ TARGET_FREEBSD_NR_extattr_delete_file, "extattr_delete_file", "%s(\"%s\", %d, \"%s\")", NULL, NULL },
{ TARGET_FREEBSD_NR_extattr_delete_link, "extattr_delete_link", "%s(\"%s\", %d, \"%s\")", NULL, NULL },
{ TARGET_FREEBSD_NR_extattr_get_fd, "extattr_get_fd", "%s(%d, %d, \"%s\", %#x, %d)", NULL, NULL },
{ TARGET_FREEBSD_NR_extattr_get_file, "extattr_get_file", "%s(\"%s\", %d, \"%s\", %#x, %d)", NULL, NULL },
{ TARGET_FREEBSD_NR_extattr_get_file, "extattr_get_link", "%s(\"%s\", %d, \"%s\", %#x, %d)", NULL, NULL },
{ TARGET_FREEBSD_NR_extattr_list_fd, "extattr_list_fd", "%s(%d, %d, %#x, %d)", NULL, NULL },
{ TARGET_FREEBSD_NR_extattr_list_file, "extattr_list_file", "%s(\"%s\", %d, %#x, %d)", NULL, NULL },
{ TARGET_FREEBSD_NR_extattr_list_link, "extattr_list_link", "%s(\"%s\", %d, %#x, %d)", NULL, NULL },
{ TARGET_FREEBSD_NR_extattr_set_fd, "extattr_set_fd", "%s(%d, %d, \"%s\", %#x, %d)", NULL, NULL },
{ TARGET_FREEBSD_NR_extattr_set_file, "extattr_set_file", "%s(\"%s\", %d, \"%s\", %#x, %d)", NULL, NULL },
{ TARGET_FREEBSD_NR_extattr_set_link, "extattr_set_link", "%s(\"%s\", %d, \"%s\", %#x, %d)", NULL, NULL },
{ TARGET_FREEBSD_NR_fchdir, "fchdir", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_fchflags, "fchflags", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_fchmod, "fchmod", "%s(%d,%#o)", NULL, NULL },
{ TARGET_FREEBSD_NR_fchown, "fchown", "%s(\"%s\",%d,%d)", NULL, NULL },
{ TARGET_FREEBSD_NR_fchown, "fchown", "%s(%d,%d,%d)", NULL, NULL },
{ TARGET_FREEBSD_NR_fcntl, "fcntl", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_fexecve, "fexecve", NULL, print_execve, NULL },
{ TARGET_FREEBSD_NR_fhopen, "fhopen", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_fhstat, "fhstat", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_fhstatfs, "fhstatfs", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_flock, "flock", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_fork, "fork", "%s()", NULL, NULL },
{ TARGET_FREEBSD_NR_fpathconf, "fpathconf", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_fstat, "fstat", "%s(%d,%p)", NULL, NULL },
{ TARGET_FREEBSD_NR_fstatfs, "fstatfs", "%s(%d,%p)", NULL, NULL },
{ TARGET_FREEBSD_NR_fstat, "fstat", "%s(%d,%#x)", NULL, NULL },
{ TARGET_FREEBSD_NR_fstatat, "fstatat", "%s(%d,\"%s\", %#x, %d)", NULL, NULL },
{ TARGET_FREEBSD_NR_fstatfs, "fstatfs", "%s(%d,%#x)", NULL, NULL },
{ TARGET_FREEBSD_NR_fsync, "fsync", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_ftruncate, "ftruncate", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_futimes, "futimes", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_getcontext, "getcontext", "%s(%#x)", NULL, NULL },
{ TARGET_FREEBSD_NR_getdirentries, "getdirentries", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_freebsd6_mmap, "freebsd6_mmap", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_getegid, "getegid", "%s()", NULL, NULL },
@@ -63,7 +110,7 @@
{ TARGET_FREEBSD_NR_getsockopt, "getsockopt", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_gettimeofday, "gettimeofday", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_getuid, "getuid", "%s()", NULL, NULL },
{ TARGET_FREEBSD_NR_ioctl, "ioctl", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_ioctl, "ioctl", NULL, print_ioctl, NULL },
{ TARGET_FREEBSD_NR_issetugid, "issetugid", "%s()", NULL, NULL },
{ TARGET_FREEBSD_NR_kevent, "kevent", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_kill, "kill", NULL, NULL, NULL },
@@ -72,6 +119,7 @@
{ TARGET_FREEBSD_NR_lchown, "lchown", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_link, "link", "%s(\"%s\",\"%s\")", NULL, NULL },
{ TARGET_FREEBSD_NR_listen, "listen", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_lpathconf, "lpathconf", "%s(\"%s\", %d)", NULL, NULL },
{ TARGET_FREEBSD_NR_lseek, "lseek", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_lstat, "lstat", "%s(\"%s\",%p)", NULL, NULL },
{ TARGET_FREEBSD_NR_madvise, "madvise", NULL, NULL, NULL },
@@ -96,7 +144,8 @@
{ TARGET_FREEBSD_NR_nanosleep, "nanosleep", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_nfssvc, "nfssvc", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_open, "open", "%s(\"%s\",%#x,%#o)", NULL, NULL },
{ TARGET_FREEBSD_NR_pathconf, "pathconf", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_openat, "openat", "%s(%d, \"%s\",%#x,%#o)", NULL, NULL },
{ TARGET_FREEBSD_NR_pathconf, "pathconf", "%s(\"%s\", %d)", NULL, NULL },
{ TARGET_FREEBSD_NR_pipe, "pipe", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_poll, "poll", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_pread, "pread", NULL, NULL, NULL },
@@ -116,6 +165,7 @@
{ TARGET_FREEBSD_NR_revoke, "revoke", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_rfork, "rfork", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_rmdir, "rmdir", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_rtprio_thread, "rtprio_thread", "%s(%d, %d, %p)", NULL, NULL },
{ TARGET_FREEBSD_NR_sbrk, "sbrk", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_sched_yield, "sched_yield", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_select, "select", NULL, NULL, NULL },
@@ -123,6 +173,7 @@
{ TARGET_FREEBSD_NR_semop, "semop", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_sendmsg, "sendmsg", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_sendto, "sendto", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_setcontext, "setcontext", "%s(%#x)", NULL, NULL },
{ TARGET_FREEBSD_NR_setegid, "setegid", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_seteuid, "seteuid", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_setgid, "setgid", NULL, NULL, NULL },
@@ -151,7 +202,7 @@
{ TARGET_FREEBSD_NR_sigprocmask, "sigprocmask", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_sigreturn, "sigreturn", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_sigsuspend, "sigsuspend", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_socket, "socket", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_socket, "socket", "%s(%d,%d,%d)", NULL, NULL },
{ TARGET_FREEBSD_NR_socketpair, "socketpair", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_sstk, "sstk", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_stat, "stat", "%s(\"%s\",%p)", NULL, NULL },
@@ -160,6 +211,15 @@
{ TARGET_FREEBSD_NR_sync, "sync", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_sysarch, "sysarch", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_syscall, "syscall", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_thr_create, "thr_create", "%s(%#x, %#x, %d)", NULL, NULL },
{ TARGET_FREEBSD_NR_thr_exit, "thr_exit", "%s(%#x)", NULL, NULL },
{ TARGET_FREEBSD_NR_thr_kill, "thr_kill", "%s(%d, %#x)", NULL, NULL },
{ TARGET_FREEBSD_NR_thr_kill2, "thr_kill2", "%s(%d, %d, %d)", NULL, NULL },
{ TARGET_FREEBSD_NR_thr_new, "thr_new", "%s(%#x, %d)", NULL, NULL },
{ TARGET_FREEBSD_NR_thr_self, "thr_self", "%s(%#x)", NULL, NULL },
{ TARGET_FREEBSD_NR_thr_set_name, "thr_set_name", "%s(%d, \"%s\")", NULL, NULL },
{ TARGET_FREEBSD_NR_thr_suspend, "thr_suspend", "%s(%d, %#x)", NULL, NULL },
{ TARGET_FREEBSD_NR_thr_wake, "thr_wake", "%s(%d)", NULL, NULL },
{ TARGET_FREEBSD_NR_truncate, "truncate", NULL, NULL, NULL },
{ TARGET_FREEBSD_NR_umask, "umask", "%s(%#o)", NULL, NULL },
{ TARGET_FREEBSD_NR_unlink, "unlink", "%s(\"%s\")", NULL, NULL },

View File

@@ -1,373 +1,450 @@
/*
* System call numbers.
*
* $FreeBSD: src/sys/sys/syscall.h,v 1.224 2008/08/24 21:23:08 rwatson Exp $
* created from FreeBSD: head/sys/kern/syscalls.master 182123 2008-08-24 21:20:35Z rwatson
* created from FreeBSD: releng/9.1/sys/kern/syscalls.master 229723
* 2012-01-06 19:29:16Z jhb
*/
#define TARGET_FREEBSD_NR_syscall 0
#define TARGET_FREEBSD_NR_exit 1
#define TARGET_FREEBSD_NR_fork 2
#define TARGET_FREEBSD_NR_read 3
#define TARGET_FREEBSD_NR_write 4
#define TARGET_FREEBSD_NR_open 5
#define TARGET_FREEBSD_NR_close 6
#define TARGET_FREEBSD_NR_wait4 7
#define TARGET_FREEBSD_NR_link 9
#define TARGET_FREEBSD_NR_unlink 10
#define TARGET_FREEBSD_NR_chdir 12
#define TARGET_FREEBSD_NR_fchdir 13
#define TARGET_FREEBSD_NR_mknod 14
#define TARGET_FREEBSD_NR_chmod 15
#define TARGET_FREEBSD_NR_chown 16
#define TARGET_FREEBSD_NR_break 17
#define TARGET_FREEBSD_NR_freebsd4_getfsstat 18
#define TARGET_FREEBSD_NR_getpid 20
#define TARGET_FREEBSD_NR_mount 21
#define TARGET_FREEBSD_NR_unmount 22
#define TARGET_FREEBSD_NR_setuid 23
#define TARGET_FREEBSD_NR_getuid 24
#define TARGET_FREEBSD_NR_geteuid 25
#define TARGET_FREEBSD_NR_ptrace 26
#define TARGET_FREEBSD_NR_recvmsg 27
#define TARGET_FREEBSD_NR_sendmsg 28
#define TARGET_FREEBSD_NR_recvfrom 29
#define TARGET_FREEBSD_NR_accept 30
#define TARGET_FREEBSD_NR_getpeername 31
#define TARGET_FREEBSD_NR_getsockname 32
#define TARGET_FREEBSD_NR_access 33
#define TARGET_FREEBSD_NR_chflags 34
#define TARGET_FREEBSD_NR_fchflags 35
#define TARGET_FREEBSD_NR_sync 36
#define TARGET_FREEBSD_NR_kill 37
#define TARGET_FREEBSD_NR_getppid 39
#define TARGET_FREEBSD_NR_dup 41
#define TARGET_FREEBSD_NR_pipe 42
#define TARGET_FREEBSD_NR_getegid 43
#define TARGET_FREEBSD_NR_profil 44
#define TARGET_FREEBSD_NR_ktrace 45
#define TARGET_FREEBSD_NR_getgid 47
#define TARGET_FREEBSD_NR_getlogin 49
#define TARGET_FREEBSD_NR_setlogin 50
#define TARGET_FREEBSD_NR_acct 51
#define TARGET_FREEBSD_NR_sigaltstack 53
#define TARGET_FREEBSD_NR_ioctl 54
#define TARGET_FREEBSD_NR_reboot 55
#define TARGET_FREEBSD_NR_revoke 56
#define TARGET_FREEBSD_NR_symlink 57
#define TARGET_FREEBSD_NR_readlink 58
#define TARGET_FREEBSD_NR_execve 59
#define TARGET_FREEBSD_NR_umask 60
#define TARGET_FREEBSD_NR_chroot 61
#define TARGET_FREEBSD_NR_msync 65
#define TARGET_FREEBSD_NR_vfork 66
#define TARGET_FREEBSD_NR_sbrk 69
#define TARGET_FREEBSD_NR_sstk 70
#define TARGET_FREEBSD_NR_vadvise 72
#define TARGET_FREEBSD_NR_munmap 73
#define TARGET_FREEBSD_NR_mprotect 74
#define TARGET_FREEBSD_NR_madvise 75
#define TARGET_FREEBSD_NR_mincore 78
#define TARGET_FREEBSD_NR_getgroups 79
#define TARGET_FREEBSD_NR_setgroups 80
#define TARGET_FREEBSD_NR_getpgrp 81
#define TARGET_FREEBSD_NR_setpgid 82
#define TARGET_FREEBSD_NR_setitimer 83
#define TARGET_FREEBSD_NR_swapon 85
#define TARGET_FREEBSD_NR_getitimer 86
#define TARGET_FREEBSD_NR_getdtablesize 89
#define TARGET_FREEBSD_NR_dup2 90
#define TARGET_FREEBSD_NR_fcntl 92
#define TARGET_FREEBSD_NR_select 93
#define TARGET_FREEBSD_NR_fsync 95
#define TARGET_FREEBSD_NR_setpriority 96
#define TARGET_FREEBSD_NR_socket 97
#define TARGET_FREEBSD_NR_connect 98
#define TARGET_FREEBSD_NR_getpriority 100
#define TARGET_FREEBSD_NR_bind 104
#define TARGET_FREEBSD_NR_setsockopt 105
#define TARGET_FREEBSD_NR_listen 106
#define TARGET_FREEBSD_NR_gettimeofday 116
#define TARGET_FREEBSD_NR_getrusage 117
#define TARGET_FREEBSD_NR_getsockopt 118
#define TARGET_FREEBSD_NR_readv 120
#define TARGET_FREEBSD_NR_writev 121
#define TARGET_FREEBSD_NR_settimeofday 122
#define TARGET_FREEBSD_NR_fchown 123
#define TARGET_FREEBSD_NR_fchmod 124
#define TARGET_FREEBSD_NR_setreuid 126
#define TARGET_FREEBSD_NR_setregid 127
#define TARGET_FREEBSD_NR_rename 128
#define TARGET_FREEBSD_NR_flock 131
#define TARGET_FREEBSD_NR_mkfifo 132
#define TARGET_FREEBSD_NR_sendto 133
#define TARGET_FREEBSD_NR_shutdown 134
#define TARGET_FREEBSD_NR_socketpair 135
#define TARGET_FREEBSD_NR_mkdir 136
#define TARGET_FREEBSD_NR_rmdir 137
#define TARGET_FREEBSD_NR_utimes 138
#define TARGET_FREEBSD_NR_adjtime 140
#define TARGET_FREEBSD_NR_setsid 147
#define TARGET_FREEBSD_NR_quotactl 148
#define TARGET_FREEBSD_NR_nlm_syscall 154
#define TARGET_FREEBSD_NR_nfssvc 155
#define TARGET_FREEBSD_NR_freebsd4_statfs 157
#define TARGET_FREEBSD_NR_freebsd4_fstatfs 158
#define TARGET_FREEBSD_NR_lgetfh 160
#define TARGET_FREEBSD_NR_getfh 161
#define TARGET_FREEBSD_NR_getdomainname 162
#define TARGET_FREEBSD_NR_setdomainname 163
#define TARGET_FREEBSD_NR_uname 164
#define TARGET_FREEBSD_NR_sysarch 165
#define TARGET_FREEBSD_NR_rtprio 166
#define TARGET_FREEBSD_NR_semsys 169
#define TARGET_FREEBSD_NR_msgsys 170
#define TARGET_FREEBSD_NR_shmsys 171
#define TARGET_FREEBSD_NR_freebsd6_pread 173
#define TARGET_FREEBSD_NR_freebsd6_pwrite 174
#define TARGET_FREEBSD_NR_setfib 175
#define TARGET_FREEBSD_NR_ntp_adjtime 176
#define TARGET_FREEBSD_NR_setgid 181
#define TARGET_FREEBSD_NR_setegid 182
#define TARGET_FREEBSD_NR_seteuid 183
#define TARGET_FREEBSD_NR_stat 188
#define TARGET_FREEBSD_NR_fstat 189
#define TARGET_FREEBSD_NR_lstat 190
#define TARGET_FREEBSD_NR_pathconf 191
#define TARGET_FREEBSD_NR_fpathconf 192
#define TARGET_FREEBSD_NR_getrlimit 194
#define TARGET_FREEBSD_NR_setrlimit 195
#define TARGET_FREEBSD_NR_getdirentries 196
#define TARGET_FREEBSD_NR_freebsd6_mmap 197
#define TARGET_FREEBSD_NR___syscall 198
#define TARGET_FREEBSD_NR_freebsd6_lseek 199
#define TARGET_FREEBSD_NR_freebsd6_truncate 200
#define TARGET_FREEBSD_NR_freebsd6_ftruncate 201
#define TARGET_FREEBSD_NR___sysctl 202
#define TARGET_FREEBSD_NR_mlock 203
#define TARGET_FREEBSD_NR_munlock 204
#define TARGET_FREEBSD_NR_undelete 205
#define TARGET_FREEBSD_NR_futimes 206
#define TARGET_FREEBSD_NR_getpgid 207
#define TARGET_FREEBSD_NR_poll 209
#define TARGET_FREEBSD_NR___semctl 220
#define TARGET_FREEBSD_NR_semget 221
#define TARGET_FREEBSD_NR_semop 222
#define TARGET_FREEBSD_NR_msgctl 224
#define TARGET_FREEBSD_NR_msgget 225
#define TARGET_FREEBSD_NR_msgsnd 226
#define TARGET_FREEBSD_NR_msgrcv 227
#define TARGET_FREEBSD_NR_shmat 228
#define TARGET_FREEBSD_NR_shmctl 229
#define TARGET_FREEBSD_NR_shmdt 230
#define TARGET_FREEBSD_NR_shmget 231
#define TARGET_FREEBSD_NR_clock_gettime 232
#define TARGET_FREEBSD_NR_clock_settime 233
#define TARGET_FREEBSD_NR_clock_getres 234
#define TARGET_FREEBSD_NR_ktimer_create 235
#define TARGET_FREEBSD_NR_ktimer_delete 236
#define TARGET_FREEBSD_NR_ktimer_settime 237
#define TARGET_FREEBSD_NR_ktimer_gettime 238
#define TARGET_FREEBSD_NR_ktimer_getoverrun 239
#define TARGET_FREEBSD_NR_nanosleep 240
#define TARGET_FREEBSD_NR_ntp_gettime 248
#define TARGET_FREEBSD_NR_minherit 250
#define TARGET_FREEBSD_NR_rfork 251
#define TARGET_FREEBSD_NR_openbsd_poll 252
#define TARGET_FREEBSD_NR_issetugid 253
#define TARGET_FREEBSD_NR_lchown 254
#define TARGET_FREEBSD_NR_aio_read 255
#define TARGET_FREEBSD_NR_aio_write 256
#define TARGET_FREEBSD_NR_lio_listio 257
#define TARGET_FREEBSD_NR_getdents 272
#define TARGET_FREEBSD_NR_lchmod 274
#define TARGET_FREEBSD_NR_netbsd_lchown 275
#define TARGET_FREEBSD_NR_lutimes 276
#define TARGET_FREEBSD_NR_netbsd_msync 277
#define TARGET_FREEBSD_NR_nstat 278
#define TARGET_FREEBSD_NR_nfstat 279
#define TARGET_FREEBSD_NR_nlstat 280
#define TARGET_FREEBSD_NR_preadv 289
#define TARGET_FREEBSD_NR_pwritev 290
#define TARGET_FREEBSD_NR_freebsd4_fhstatfs 297
#define TARGET_FREEBSD_NR_fhopen 298
#define TARGET_FREEBSD_NR_fhstat 299
#define TARGET_FREEBSD_NR_modnext 300
#define TARGET_FREEBSD_NR_modstat 301
#define TARGET_FREEBSD_NR_modfnext 302
#define TARGET_FREEBSD_NR_modfind 303
#define TARGET_FREEBSD_NR_kldload 304
#define TARGET_FREEBSD_NR_kldunload 305
#define TARGET_FREEBSD_NR_kldfind 306
#define TARGET_FREEBSD_NR_kldnext 307
#define TARGET_FREEBSD_NR_kldstat 308
#define TARGET_FREEBSD_NR_kldfirstmod 309
#define TARGET_FREEBSD_NR_getsid 310
#define TARGET_FREEBSD_NR_setresuid 311
#define TARGET_FREEBSD_NR_setresgid 312
#define TARGET_FREEBSD_NR_aio_return 314
#define TARGET_FREEBSD_NR_aio_suspend 315
#define TARGET_FREEBSD_NR_aio_cancel 316
#define TARGET_FREEBSD_NR_aio_error 317
#define TARGET_FREEBSD_NR_oaio_read 318
#define TARGET_FREEBSD_NR_oaio_write 319
#define TARGET_FREEBSD_NR_olio_listio 320
#define TARGET_FREEBSD_NR_yield 321
#define TARGET_FREEBSD_NR_mlockall 324
#define TARGET_FREEBSD_NR_munlockall 325
#define TARGET_FREEBSD_NR___getcwd 326
#define TARGET_FREEBSD_NR_sched_setparam 327
#define TARGET_FREEBSD_NR_sched_getparam 328
#define TARGET_FREEBSD_NR_sched_setscheduler 329
#define TARGET_FREEBSD_NR_sched_getscheduler 330
#define TARGET_FREEBSD_NR_sched_yield 331
#define TARGET_FREEBSD_NR_sched_get_priority_max 332
#define TARGET_FREEBSD_NR_sched_get_priority_min 333
#define TARGET_FREEBSD_NR_sched_rr_get_interval 334
#define TARGET_FREEBSD_NR_utrace 335
#define TARGET_FREEBSD_NR_freebsd4_sendfile 336
#define TARGET_FREEBSD_NR_kldsym 337
#define TARGET_FREEBSD_NR_jail 338
#define TARGET_FREEBSD_NR_sigprocmask 340
#define TARGET_FREEBSD_NR_sigsuspend 341
#define TARGET_FREEBSD_NR_freebsd4_sigaction 342
#define TARGET_FREEBSD_NR_sigpending 343
#define TARGET_FREEBSD_NR_freebsd4_sigreturn 344
#define TARGET_FREEBSD_NR_sigtimedwait 345
#define TARGET_FREEBSD_NR_sigwaitinfo 346
#define TARGET_FREEBSD_NR___acl_get_file 347
#define TARGET_FREEBSD_NR___acl_set_file 348
#define TARGET_FREEBSD_NR___acl_get_fd 349
#define TARGET_FREEBSD_NR___acl_set_fd 350
#define TARGET_FREEBSD_NR___acl_delete_file 351
#define TARGET_FREEBSD_NR___acl_delete_fd 352
#define TARGET_FREEBSD_NR___acl_aclcheck_file 353
#define TARGET_FREEBSD_NR___acl_aclcheck_fd 354
#define TARGET_FREEBSD_NR_extattrctl 355
#define TARGET_FREEBSD_NR_extattr_set_file 356
#define TARGET_FREEBSD_NR_extattr_get_file 357
#define TARGET_FREEBSD_NR_extattr_delete_file 358
#define TARGET_FREEBSD_NR_aio_waitcomplete 359
#define TARGET_FREEBSD_NR_getresuid 360
#define TARGET_FREEBSD_NR_getresgid 361
#define TARGET_FREEBSD_NR_kqueue 362
#define TARGET_FREEBSD_NR_kevent 363
#define TARGET_FREEBSD_NR_extattr_set_fd 371
#define TARGET_FREEBSD_NR_extattr_get_fd 372
#define TARGET_FREEBSD_NR_extattr_delete_fd 373
#define TARGET_FREEBSD_NR___setugid 374
#define TARGET_FREEBSD_NR_nfsclnt 375
#define TARGET_FREEBSD_NR_eaccess 376
#define TARGET_FREEBSD_NR_nmount 378
#define TARGET_FREEBSD_NR___mac_get_proc 384
#define TARGET_FREEBSD_NR___mac_set_proc 385
#define TARGET_FREEBSD_NR___mac_get_fd 386
#define TARGET_FREEBSD_NR___mac_get_file 387
#define TARGET_FREEBSD_NR___mac_set_fd 388
#define TARGET_FREEBSD_NR___mac_set_file 389
#define TARGET_FREEBSD_NR_kenv 390
#define TARGET_FREEBSD_NR_lchflags 391
#define TARGET_FREEBSD_NR_uuidgen 392
#define TARGET_FREEBSD_NR_sendfile 393
#define TARGET_FREEBSD_NR_mac_syscall 394
#define TARGET_FREEBSD_NR_getfsstat 395
#define TARGET_FREEBSD_NR_statfs 396
#define TARGET_FREEBSD_NR_fstatfs 397
#define TARGET_FREEBSD_NR_fhstatfs 398
#define TARGET_FREEBSD_NR_ksem_close 400
#define TARGET_FREEBSD_NR_ksem_post 401
#define TARGET_FREEBSD_NR_ksem_wait 402
#define TARGET_FREEBSD_NR_ksem_trywait 403
#define TARGET_FREEBSD_NR_ksem_init 404
#define TARGET_FREEBSD_NR_ksem_open 405
#define TARGET_FREEBSD_NR_ksem_unlink 406
#define TARGET_FREEBSD_NR_ksem_getvalue 407
#define TARGET_FREEBSD_NR_ksem_destroy 408
#define TARGET_FREEBSD_NR___mac_get_pid 409
#define TARGET_FREEBSD_NR___mac_get_link 410
#define TARGET_FREEBSD_NR___mac_set_link 411
#define TARGET_FREEBSD_NR_extattr_set_link 412
#define TARGET_FREEBSD_NR_extattr_get_link 413
#define TARGET_FREEBSD_NR_extattr_delete_link 414
#define TARGET_FREEBSD_NR___mac_execve 415
#define TARGET_FREEBSD_NR_sigaction 416
#define TARGET_FREEBSD_NR_sigreturn 417
#define TARGET_FREEBSD_NR_getcontext 421
#define TARGET_FREEBSD_NR_setcontext 422
#define TARGET_FREEBSD_NR_swapcontext 423
#define TARGET_FREEBSD_NR_swapoff 424
#define TARGET_FREEBSD_NR___acl_get_link 425
#define TARGET_FREEBSD_NR___acl_set_link 426
#define TARGET_FREEBSD_NR___acl_delete_link 427
#define TARGET_FREEBSD_NR___acl_aclcheck_link 428
#define TARGET_FREEBSD_NR_sigwait 429
#define TARGET_FREEBSD_NR_thr_create 430
#define TARGET_FREEBSD_NR_thr_exit 431
#define TARGET_FREEBSD_NR_thr_self 432
#define TARGET_FREEBSD_NR_thr_kill 433
#define TARGET_FREEBSD_NR__umtx_lock 434
#define TARGET_FREEBSD_NR__umtx_unlock 435
#define TARGET_FREEBSD_NR_jail_attach 436
#define TARGET_FREEBSD_NR_extattr_list_fd 437
#define TARGET_FREEBSD_NR_extattr_list_file 438
#define TARGET_FREEBSD_NR_extattr_list_link 439
#define TARGET_FREEBSD_NR_ksem_timedwait 441
#define TARGET_FREEBSD_NR_thr_suspend 442
#define TARGET_FREEBSD_NR_thr_wake 443
#define TARGET_FREEBSD_NR_kldunloadf 444
#define TARGET_FREEBSD_NR_audit 445
#define TARGET_FREEBSD_NR_auditon 446
#define TARGET_FREEBSD_NR_getauid 447
#define TARGET_FREEBSD_NR_setauid 448
#define TARGET_FREEBSD_NR_getaudit 449
#define TARGET_FREEBSD_NR_setaudit 450
#define TARGET_FREEBSD_NR_getaudit_addr 451
#define TARGET_FREEBSD_NR_setaudit_addr 452
#define TARGET_FREEBSD_NR_auditctl 453
#define TARGET_FREEBSD_NR__umtx_op 454
#define TARGET_FREEBSD_NR_thr_new 455
#define TARGET_FREEBSD_NR_sigqueue 456
#define TARGET_FREEBSD_NR_kmq_open 457
#define TARGET_FREEBSD_NR_kmq_setattr 458
#define TARGET_FREEBSD_NR_kmq_timedreceive 459
#define TARGET_FREEBSD_NR_kmq_timedsend 460
#define TARGET_FREEBSD_NR_kmq_notify 461
#define TARGET_FREEBSD_NR_kmq_unlink 462
#define TARGET_FREEBSD_NR_abort2 463
#define TARGET_FREEBSD_NR_thr_set_name 464
#define TARGET_FREEBSD_NR_aio_fsync 465
#define TARGET_FREEBSD_NR_rtprio_thread 466
#define TARGET_FREEBSD_NR_sctp_peeloff 471
#define TARGET_FREEBSD_NR_sctp_generic_sendmsg 472
#define TARGET_FREEBSD_NR_sctp_generic_sendmsg_iov 473
#define TARGET_FREEBSD_NR_sctp_generic_recvmsg 474
#define TARGET_FREEBSD_NR_pread 475
#define TARGET_FREEBSD_NR_pwrite 476
#define TARGET_FREEBSD_NR_mmap 477
#define TARGET_FREEBSD_NR_lseek 478
#define TARGET_FREEBSD_NR_truncate 479
#define TARGET_FREEBSD_NR_ftruncate 480
#define TARGET_FREEBSD_NR_thr_kill2 481
#define TARGET_FREEBSD_NR_shm_open 482
#define TARGET_FREEBSD_NR_shm_unlink 483
#define TARGET_FREEBSD_NR_cpuset 484
#define TARGET_FREEBSD_NR_cpuset_setid 485
#define TARGET_FREEBSD_NR_cpuset_getid 486
#define TARGET_FREEBSD_NR_cpuset_getaffinity 487
#define TARGET_FREEBSD_NR_cpuset_setaffinity 488
#define TARGET_FREEBSD_NR_faccessat 489
#define TARGET_FREEBSD_NR_fchmodat 490
#define TARGET_FREEBSD_NR_fchownat 491
#define TARGET_FREEBSD_NR_fexecve 492
#define TARGET_FREEBSD_NR_fstatat 493
#define TARGET_FREEBSD_NR_futimesat 494
#define TARGET_FREEBSD_NR_linkat 495
#define TARGET_FREEBSD_NR_mkdirat 496
#define TARGET_FREEBSD_NR_mkfifoat 497
#define TARGET_FREEBSD_NR_mknodat 498
#define TARGET_FREEBSD_NR_openat 499
#define TARGET_FREEBSD_NR_readlinkat 500
#define TARGET_FREEBSD_NR_renameat 501
#define TARGET_FREEBSD_NR_symlinkat 502
#define TARGET_FREEBSD_NR_unlinkat 503
#define TARGET_FREEBSD_NR_posix_openpt 504
#define TARGET_FREEBSD_NR_syscall 0
#define TARGET_FREEBSD_NR_exit 1
#define TARGET_FREEBSD_NR_fork 2
#define TARGET_FREEBSD_NR_read 3
#define TARGET_FREEBSD_NR_write 4
#define TARGET_FREEBSD_NR_open 5
#define TARGET_FREEBSD_NR_close 6
#define TARGET_FREEBSD_NR_wait4 7
/* 8 is old creat */
#define TARGET_FREEBSD_NR_link 9
#define TARGET_FREEBSD_NR_unlink 10
/* 11 is obsolete execv */
#define TARGET_FREEBSD_NR_chdir 12
#define TARGET_FREEBSD_NR_fchdir 13
#define TARGET_FREEBSD_NR_mknod 14
#define TARGET_FREEBSD_NR_chmod 15
#define TARGET_FREEBSD_NR_chown 16
#define TARGET_FREEBSD_NR_break 17
#define TARGET_FREEBSD_NR_freebsd4_getfsstat 18
/* 19 is old lseek */
#define TARGET_FREEBSD_NR_getpid 20
#define TARGET_FREEBSD_NR_mount 21
#define TARGET_FREEBSD_NR_unmount 22
#define TARGET_FREEBSD_NR_setuid 23
#define TARGET_FREEBSD_NR_getuid 24
#define TARGET_FREEBSD_NR_geteuid 25
#define TARGET_FREEBSD_NR_ptrace 26
#define TARGET_FREEBSD_NR_recvmsg 27
#define TARGET_FREEBSD_NR_sendmsg 28
#define TARGET_FREEBSD_NR_recvfrom 29
#define TARGET_FREEBSD_NR_accept 30
#define TARGET_FREEBSD_NR_getpeername 31
#define TARGET_FREEBSD_NR_getsockname 32
#define TARGET_FREEBSD_NR_access 33
#define TARGET_FREEBSD_NR_chflags 34
#define TARGET_FREEBSD_NR_fchflags 35
#define TARGET_FREEBSD_NR_sync 36
#define TARGET_FREEBSD_NR_kill 37
/* 38 is old stat */
#define TARGET_FREEBSD_NR_getppid 39
/* 40 is old lstat */
#define TARGET_FREEBSD_NR_dup 41
#define TARGET_FREEBSD_NR_pipe 42
#define TARGET_FREEBSD_NR_getegid 43
#define TARGET_FREEBSD_NR_profil 44
#define TARGET_FREEBSD_NR_ktrace 45
/* 46 is old sigaction */
#define TARGET_FREEBSD_NR_getgid 47
/* 48 is old sigprocmask */
#define TARGET_FREEBSD_NR_getlogin 49
#define TARGET_FREEBSD_NR_setlogin 50
#define TARGET_FREEBSD_NR_acct 51
/* 52 is old sigpending */
#define TARGET_FREEBSD_NR_sigaltstack 53
#define TARGET_FREEBSD_NR_ioctl 54
#define TARGET_FREEBSD_NR_reboot 55
#define TARGET_FREEBSD_NR_revoke 56
#define TARGET_FREEBSD_NR_symlink 57
#define TARGET_FREEBSD_NR_readlink 58
#define TARGET_FREEBSD_NR_execve 59
#define TARGET_FREEBSD_NR_umask 60
#define TARGET_FREEBSD_NR_chroot 61
/* 62 is old fstat */
/* 63 is old getkerninfo */
/* 64 is old getpagesize */
#define TARGET_FREEBSD_NR_msync 65
#define TARGET_FREEBSD_NR_vfork 66
/* 67 is obsolete vread */
/* 68 is obsolete vwrite */
#define TARGET_FREEBSD_NR_sbrk 69
#define TARGET_FREEBSD_NR_sstk 70
/* 71 is old mmap */
#define TARGET_FREEBSD_NR_vadvise 72
#define TARGET_FREEBSD_NR_munmap 73
#define TARGET_FREEBSD_NR_mprotect 74
#define TARGET_FREEBSD_NR_madvise 75
/* 76 is obsolete vhangup */
/* 77 is obsolete vlimit */
#define TARGET_FREEBSD_NR_mincore 78
#define TARGET_FREEBSD_NR_getgroups 79
#define TARGET_FREEBSD_NR_setgroups 80
#define TARGET_FREEBSD_NR_getpgrp 81
#define TARGET_FREEBSD_NR_setpgid 82
#define TARGET_FREEBSD_NR_setitimer 83
/* 84 is old wait */
#define TARGET_FREEBSD_NR_swapon 85
#define TARGET_FREEBSD_NR_getitimer 86
/* 87 is old gethostname */
/* 88 is old sethostname */
#define TARGET_FREEBSD_NR_getdtablesize 89
#define TARGET_FREEBSD_NR_dup2 90
#define TARGET_FREEBSD_NR_fcntl 92
#define TARGET_FREEBSD_NR_select 93
#define TARGET_FREEBSD_NR_fsync 95
#define TARGET_FREEBSD_NR_setpriority 96
#define TARGET_FREEBSD_NR_socket 97
#define TARGET_FREEBSD_NR_connect 98
/* 99 is old accept */
#define TARGET_FREEBSD_NR_getpriority 100
/* 101 is old send */
/* 102 is old recv */
/* 103 is old sigreturn */
#define TARGET_FREEBSD_NR_bind 104
#define TARGET_FREEBSD_NR_setsockopt 105
#define TARGET_FREEBSD_NR_listen 106
/* 107 is obsolete vtimes */
/* 108 is old sigvec */
/* 109 is old sigblock */
/* 110 is old sigsetmask */
/* 111 is old sigsuspend */
/* 112 is old sigstack */
/* 113 is old recvmsg */
/* 114 is old sendmsg */
/* 115 is obsolete vtrace */
#define TARGET_FREEBSD_NR_gettimeofday 116
#define TARGET_FREEBSD_NR_getrusage 117
#define TARGET_FREEBSD_NR_getsockopt 118
#define TARGET_FREEBSD_NR_readv 120
#define TARGET_FREEBSD_NR_writev 121
#define TARGET_FREEBSD_NR_settimeofday 122
#define TARGET_FREEBSD_NR_fchown 123
#define TARGET_FREEBSD_NR_fchmod 124
/* 125 is old recvfrom */
#define TARGET_FREEBSD_NR_setreuid 126
#define TARGET_FREEBSD_NR_setregid 127
#define TARGET_FREEBSD_NR_rename 128
/* 129 is old truncate */
/* 130 is old ftruncate */
#define TARGET_FREEBSD_NR_flock 131
#define TARGET_FREEBSD_NR_mkfifo 132
#define TARGET_FREEBSD_NR_sendto 133
#define TARGET_FREEBSD_NR_shutdown 134
#define TARGET_FREEBSD_NR_socketpair 135
#define TARGET_FREEBSD_NR_mkdir 136
#define TARGET_FREEBSD_NR_rmdir 137
#define TARGET_FREEBSD_NR_utimes 138
/* 139 is obsolete 4.2 sigreturn */
#define TARGET_FREEBSD_NR_adjtime 140
/* 141 is old getpeername */
/* 142 is old gethostid */
/* 143 is old sethostid */
/* 144 is old getrlimit */
/* 145 is old setrlimit */
/* 146 is old killpg */
#define TARGET_FREEBSD_NR_killpg 146 /* COMPAT */
#define TARGET_FREEBSD_NR_setsid 147
#define TARGET_FREEBSD_NR_quotactl 148
/* 149 is old quota */
/* 150 is old getsockname */
#define TARGET_FREEBSD_NR_nlm_syscall 154
#define TARGET_FREEBSD_NR_nfssvc 155
/* 156 is old getdirentries */
#define TARGET_FREEBSD_NR_freebsd4_statfs 157
#define TARGET_FREEBSD_NR_freebsd4_fstatfs 158
#define TARGET_FREEBSD_NR_lgetfh 160
#define TARGET_FREEBSD_NR_getfh 161
#define TARGET_FREEBSD_NR_freebsd4_getdomainname 162
#define TARGET_FREEBSD_NR_freebsd4_setdomainname 163
#define TARGET_FREEBSD_NR_freebsd4_uname 164
#define TARGET_FREEBSD_NR_sysarch 165
#define TARGET_FREEBSD_NR_rtprio 166
#define TARGET_FREEBSD_NR_semsys 169
#define TARGET_FREEBSD_NR_msgsys 170
#define TARGET_FREEBSD_NR_shmsys 171
#define TARGET_FREEBSD_NR_freebsd6_pread 173
#define TARGET_FREEBSD_NR_freebsd6_pwrite 174
#define TARGET_FREEBSD_NR_setfib 175
#define TARGET_FREEBSD_NR_ntp_adjtime 176
#define TARGET_FREEBSD_NR_setgid 181
#define TARGET_FREEBSD_NR_setegid 182
#define TARGET_FREEBSD_NR_seteuid 183
#define TARGET_FREEBSD_NR_stat 188
#define TARGET_FREEBSD_NR_fstat 189
#define TARGET_FREEBSD_NR_lstat 190
#define TARGET_FREEBSD_NR_pathconf 191
#define TARGET_FREEBSD_NR_fpathconf 192
#define TARGET_FREEBSD_NR_getrlimit 194
#define TARGET_FREEBSD_NR_setrlimit 195
#define TARGET_FREEBSD_NR_getdirentries 196
#define TARGET_FREEBSD_NR_freebsd6_mmap 197
#define TARGET_FREEBSD_NR___syscall 198
#define TARGET_FREEBSD_NR_freebsd6_lseek 199
#define TARGET_FREEBSD_NR_freebsd6_truncate 200
#define TARGET_FREEBSD_NR_freebsd6_ftruncate 201
#define TARGET_FREEBSD_NR___sysctl 202
#define TARGET_FREEBSD_NR_mlock 203
#define TARGET_FREEBSD_NR_munlock 204
#define TARGET_FREEBSD_NR_undelete 205
#define TARGET_FREEBSD_NR_futimes 206
#define TARGET_FREEBSD_NR_getpgid 207
#define TARGET_FREEBSD_NR_poll 209
#define TARGET_FREEBSD_NR_freebsd7___semctl 220
#define TARGET_FREEBSD_NR_semget 221
#define TARGET_FREEBSD_NR_semop 222
#define TARGET_FREEBSD_NR_freebsd7_msgctl 224
#define TARGET_FREEBSD_NR_msgget 225
#define TARGET_FREEBSD_NR_msgsnd 226
#define TARGET_FREEBSD_NR_msgrcv 227
#define TARGET_FREEBSD_NR_shmat 228
#define TARGET_FREEBSD_NR_freebsd7_shmctl 229
#define TARGET_FREEBSD_NR_shmdt 230
#define TARGET_FREEBSD_NR_shmget 231
#define TARGET_FREEBSD_NR_clock_gettime 232
#define TARGET_FREEBSD_NR_clock_settime 233
#define TARGET_FREEBSD_NR_clock_getres 234
#define TARGET_FREEBSD_NR_ktimer_create 235
#define TARGET_FREEBSD_NR_ktimer_delete 236
#define TARGET_FREEBSD_NR_ktimer_settime 237
#define TARGET_FREEBSD_NR_ktimer_gettime 238
#define TARGET_FREEBSD_NR_ktimer_getoverrun 239
#define TARGET_FREEBSD_NR_nanosleep 240
#define TARGET_FREEBSD_NR_ntp_gettime 248
#define TARGET_FREEBSD_NR_minherit 250
#define TARGET_FREEBSD_NR_rfork 251
#define TARGET_FREEBSD_NR_openbsd_poll 252
#define TARGET_FREEBSD_NR_issetugid 253
#define TARGET_FREEBSD_NR_lchown 254
#define TARGET_FREEBSD_NR_aio_read 255
#define TARGET_FREEBSD_NR_aio_write 256
#define TARGET_FREEBSD_NR_lio_listio 257
#define TARGET_FREEBSD_NR_getdents 272
#define TARGET_FREEBSD_NR_lchmod 274
#define TARGET_FREEBSD_NR_netbsd_lchown 275
#define TARGET_FREEBSD_NR_lutimes 276
#define TARGET_FREEBSD_NR_netbsd_msync 277
#define TARGET_FREEBSD_NR_nstat 278
#define TARGET_FREEBSD_NR_nfstat 279
#define TARGET_FREEBSD_NR_nlstat 280
#define TARGET_FREEBSD_NR_preadv 289
#define TARGET_FREEBSD_NR_pwritev 290
#define TARGET_FREEBSD_NR_freebsd4_fhstatfs 297
#define TARGET_FREEBSD_NR_fhopen 298
#define TARGET_FREEBSD_NR_fhstat 299
#define TARGET_FREEBSD_NR_modnext 300
#define TARGET_FREEBSD_NR_modstat 301
#define TARGET_FREEBSD_NR_modfnext 302
#define TARGET_FREEBSD_NR_modfind 303
#define TARGET_FREEBSD_NR_kldload 304
#define TARGET_FREEBSD_NR_kldunload 305
#define TARGET_FREEBSD_NR_kldfind 306
#define TARGET_FREEBSD_NR_kldnext 307
#define TARGET_FREEBSD_NR_kldstat 308
#define TARGET_FREEBSD_NR_kldfirstmod 309
#define TARGET_FREEBSD_NR_getsid 310
#define TARGET_FREEBSD_NR_setresuid 311
#define TARGET_FREEBSD_NR_setresgid 312
/* 313 is obsolete signanosleep */
#define TARGET_FREEBSD_NR_aio_return 314
#define TARGET_FREEBSD_NR_aio_suspend 315
#define TARGET_FREEBSD_NR_aio_cancel 316
#define TARGET_FREEBSD_NR_aio_error 317
#define TARGET_FREEBSD_NR_oaio_read 318
#define TARGET_FREEBSD_NR_oaio_write 319
#define TARGET_FREEBSD_NR_olio_listio 320
#define TARGET_FREEBSD_NR_yield 321
/* 322 is obsolete thr_sleep */
/* 323 is obsolete thr_wakeup */
#define TARGET_FREEBSD_NR_mlockall 324
#define TARGET_FREEBSD_NR_munlockall 325
#define TARGET_FREEBSD_NR___getcwd 326
#define TARGET_FREEBSD_NR_sched_setparam 327
#define TARGET_FREEBSD_NR_sched_getparam 328
#define TARGET_FREEBSD_NR_sched_setscheduler 329
#define TARGET_FREEBSD_NR_sched_getscheduler 330
#define TARGET_FREEBSD_NR_sched_yield 331
#define TARGET_FREEBSD_NR_sched_get_priority_max 332
#define TARGET_FREEBSD_NR_sched_get_priority_min 333
#define TARGET_FREEBSD_NR_sched_rr_get_interval 334
#define TARGET_FREEBSD_NR_utrace 335
#define TARGET_FREEBSD_NR_freebsd4_sendfile 336
#define TARGET_FREEBSD_NR_kldsym 337
#define TARGET_FREEBSD_NR_jail 338
#define TARGET_FREEBSD_NR_nnpfs_syscall 339
#define TARGET_FREEBSD_NR_sigprocmask 340
#define TARGET_FREEBSD_NR_sigsuspend 341
#define TARGET_FREEBSD_NR_freebsd4_sigaction 342
#define TARGET_FREEBSD_NR_sigpending 343
#define TARGET_FREEBSD_NR_freebsd4_sigreturn 344
#define TARGET_FREEBSD_NR_sigtimedwait 345
#define TARGET_FREEBSD_NR_sigwaitinfo 346
#define TARGET_FREEBSD_NR___acl_get_file 347
#define TARGET_FREEBSD_NR___acl_set_file 348
#define TARGET_FREEBSD_NR___acl_get_fd 349
#define TARGET_FREEBSD_NR___acl_set_fd 350
#define TARGET_FREEBSD_NR___acl_delete_file 351
#define TARGET_FREEBSD_NR___acl_delete_fd 352
#define TARGET_FREEBSD_NR___acl_aclcheck_file 353
#define TARGET_FREEBSD_NR___acl_aclcheck_fd 354
#define TARGET_FREEBSD_NR_extattrctl 355
#define TARGET_FREEBSD_NR_extattr_set_file 356
#define TARGET_FREEBSD_NR_extattr_get_file 357
#define TARGET_FREEBSD_NR_extattr_delete_file 358
#define TARGET_FREEBSD_NR_aio_waitcomplete 359
#define TARGET_FREEBSD_NR_getresuid 360
#define TARGET_FREEBSD_NR_getresgid 361
#define TARGET_FREEBSD_NR_kqueue 362
#define TARGET_FREEBSD_NR_kevent 363
#define TARGET_FREEBSD_NR_extattr_set_fd 371
#define TARGET_FREEBSD_NR_extattr_get_fd 372
#define TARGET_FREEBSD_NR_extattr_delete_fd 373
#define TARGET_FREEBSD_NR___setugid 374
#define TARGET_FREEBSD_NR_eaccess 376
#define TARGET_FREEBSD_NR_afs3_syscall 377
#define TARGET_FREEBSD_NR_nmount 378
#define TARGET_FREEBSD_NR___mac_get_proc 384
#define TARGET_FREEBSD_NR___mac_set_proc 385
#define TARGET_FREEBSD_NR___mac_get_fd 386
#define TARGET_FREEBSD_NR___mac_get_file 387
#define TARGET_FREEBSD_NR___mac_set_fd 388
#define TARGET_FREEBSD_NR___mac_set_file 389
#define TARGET_FREEBSD_NR_kenv 390
#define TARGET_FREEBSD_NR_lchflags 391
#define TARGET_FREEBSD_NR_uuidgen 392
#define TARGET_FREEBSD_NR_sendfile 393
#define TARGET_FREEBSD_NR_mac_syscall 394
#define TARGET_FREEBSD_NR_getfsstat 395
#define TARGET_FREEBSD_NR_statfs 396
#define TARGET_FREEBSD_NR_fstatfs 397
#define TARGET_FREEBSD_NR_fhstatfs 398
#define TARGET_FREEBSD_NR_ksem_close 400
#define TARGET_FREEBSD_NR_ksem_post 401
#define TARGET_FREEBSD_NR_ksem_wait 402
#define TARGET_FREEBSD_NR_ksem_trywait 403
#define TARGET_FREEBSD_NR_ksem_init 404
#define TARGET_FREEBSD_NR_ksem_open 405
#define TARGET_FREEBSD_NR_ksem_unlink 406
#define TARGET_FREEBSD_NR_ksem_getvalue 407
#define TARGET_FREEBSD_NR_ksem_destroy 408
#define TARGET_FREEBSD_NR___mac_get_pid 409
#define TARGET_FREEBSD_NR___mac_get_link 410
#define TARGET_FREEBSD_NR___mac_set_link 411
#define TARGET_FREEBSD_NR_extattr_set_link 412
#define TARGET_FREEBSD_NR_extattr_get_link 413
#define TARGET_FREEBSD_NR_extattr_delete_link 414
#define TARGET_FREEBSD_NR___mac_execve 415
#define TARGET_FREEBSD_NR_sigaction 416
#define TARGET_FREEBSD_NR_sigreturn 417
#define TARGET_FREEBSD_NR_getcontext 421
#define TARGET_FREEBSD_NR_setcontext 422
#define TARGET_FREEBSD_NR_swapcontext 423
#define TARGET_FREEBSD_NR_swapoff 424
#define TARGET_FREEBSD_NR___acl_get_link 425
#define TARGET_FREEBSD_NR___acl_set_link 426
#define TARGET_FREEBSD_NR___acl_delete_link 427
#define TARGET_FREEBSD_NR___acl_aclcheck_link 428
#define TARGET_FREEBSD_NR_sigwait 429
#define TARGET_FREEBSD_NR_thr_create 430
#define TARGET_FREEBSD_NR_thr_exit 431
#define TARGET_FREEBSD_NR_thr_self 432
#define TARGET_FREEBSD_NR_thr_kill 433
#define TARGET_FREEBSD_NR__umtx_lock 434
#define TARGET_FREEBSD_NR__umtx_unlock 435
#define TARGET_FREEBSD_NR_jail_attach 436
#define TARGET_FREEBSD_NR_extattr_list_fd 437
#define TARGET_FREEBSD_NR_extattr_list_file 438
#define TARGET_FREEBSD_NR_extattr_list_link 439
#define TARGET_FREEBSD_NR_ksem_timedwait 441
#define TARGET_FREEBSD_NR_thr_suspend 442
#define TARGET_FREEBSD_NR_thr_wake 443
#define TARGET_FREEBSD_NR_kldunloadf 444
#define TARGET_FREEBSD_NR_audit 445
#define TARGET_FREEBSD_NR_auditon 446
#define TARGET_FREEBSD_NR_getauid 447
#define TARGET_FREEBSD_NR_setauid 448
#define TARGET_FREEBSD_NR_getaudit 449
#define TARGET_FREEBSD_NR_setaudit 450
#define TARGET_FREEBSD_NR_getaudit_addr 451
#define TARGET_FREEBSD_NR_setaudit_addr 452
#define TARGET_FREEBSD_NR_auditctl 453
#define TARGET_FREEBSD_NR__umtx_op 454
#define TARGET_FREEBSD_NR_thr_new 455
#define TARGET_FREEBSD_NR_sigqueue 456
#define TARGET_FREEBSD_NR_kmq_open 457
#define TARGET_FREEBSD_NR_kmq_setattr 458
#define TARGET_FREEBSD_NR_kmq_timedreceive 459
#define TARGET_FREEBSD_NR_kmq_timedsend 460
#define TARGET_FREEBSD_NR_kmq_notify 461
#define TARGET_FREEBSD_NR_kmq_unlink 462
#define TARGET_FREEBSD_NR_abort2 463
#define TARGET_FREEBSD_NR_thr_set_name 464
#define TARGET_FREEBSD_NR_aio_fsync 465
#define TARGET_FREEBSD_NR_rtprio_thread 466
#define TARGET_FREEBSD_NR_sctp_peeloff 471
#define TARGET_FREEBSD_NR_sctp_generic_sendmsg 472
#define TARGET_FREEBSD_NR_sctp_generic_sendmsg_iov 473
#define TARGET_FREEBSD_NR_sctp_generic_recvmsg 474
#define TARGET_FREEBSD_NR_pread 475
#define TARGET_FREEBSD_NR_pwrite 476
#define TARGET_FREEBSD_NR_mmap 477
#define TARGET_FREEBSD_NR_lseek 478
#define TARGET_FREEBSD_NR_truncate 479
#define TARGET_FREEBSD_NR_ftruncate 480
#define TARGET_FREEBSD_NR_thr_kill2 481
#define TARGET_FREEBSD_NR_shm_open 482
#define TARGET_FREEBSD_NR_shm_unlink 483
#define TARGET_FREEBSD_NR_cpuset 484
#define TARGET_FREEBSD_NR_cpuset_setid 485
#define TARGET_FREEBSD_NR_cpuset_getid 486
#define TARGET_FREEBSD_NR_cpuset_getaffinity 487
#define TARGET_FREEBSD_NR_cpuset_setaffinity 488
#define TARGET_FREEBSD_NR_faccessat 489
#define TARGET_FREEBSD_NR_fchmodat 490
#define TARGET_FREEBSD_NR_fchownat 491
#define TARGET_FREEBSD_NR_fexecve 492
#define TARGET_FREEBSD_NR_fstatat 493
#define TARGET_FREEBSD_NR_futimesat 494
#define TARGET_FREEBSD_NR_linkat 495
#define TARGET_FREEBSD_NR_mkdirat 496
#define TARGET_FREEBSD_NR_mkfifoat 497
#define TARGET_FREEBSD_NR_mknodat 498
#define TARGET_FREEBSD_NR_openat 499
#define TARGET_FREEBSD_NR_readlinkat 500
#define TARGET_FREEBSD_NR_renameat 501
#define TARGET_FREEBSD_NR_symlinkat 502
#define TARGET_FREEBSD_NR_unlinkat 503
#define TARGET_FREEBSD_NR_posix_openpt 504
#define TARGET_FREEBSD_NR_gssd_syscall 505
#define TARGET_FREEBSD_NR_jail_get 506
#define TARGET_FREEBSD_NR_jail_set 507
#define TARGET_FREEBSD_NR_jail_remove 508
#define TARGET_FREEBSD_NR_closefrom 509
#define TARGET_FREEBSD_NR___semctl 510
#define TARGET_FREEBSD_NR_msgctl 511
#define TARGET_FREEBSD_NR_shmctl 512
#define TARGET_FREEBSD_NR_lpathconf 513
#define TARGET_FREEBSD_NR_cap_new 514
#define TARGET_FREEBSD_NR_cap_getrights 515
#define TARGET_FREEBSD_NR_cap_enter 516
#define TARGET_FREEBSD_NR_cap_getmode 517
#define TARGET_FREEBSD_NR_pdfork 518
#define TARGET_FREEBSD_NR_pdkill 519
#define TARGET_FREEBSD_NR_pdgetpid 520
#define TARGET_FREEBSD_NR_pselect 522
#define TARGET_FREEBSD_NR_getloginclass 523
#define TARGET_FREEBSD_NR_setloginclass 524
#define TARGET_FREEBSD_NR_rctl_get_racct 525
#define TARGET_FREEBSD_NR_rctl_get_rules 526
#define TARGET_FREEBSD_NR_rctl_get_limits 527
#define TARGET_FREEBSD_NR_rctl_add_rule 528
#define TARGET_FREEBSD_NR_rctl_remove_rule 529
#define TARGET_FREEBSD_NR_posix_fallocate 530
#define TARGET_FREEBSD_NR_posix_fadvise 531
#define TARGET_FREEBSD_NR_MAXSYSCALL 532

View File

@@ -1004,7 +1004,7 @@ int main(int argc, char **argv)
#if defined(TARGET_I386)
env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK;
env->hflags |= HF_PE_MASK;
env->hflags |= HF_PE_MASK | HF_CPL_MASK;
if (env->features[FEAT_1_EDX] & CPUID_SSE) {
env->cr[4] |= CR4_OSFXSR_MASK;
env->hflags |= HF_OSFXSR_MASK;

View File

@@ -74,66 +74,6 @@ void mmap_unlock(void)
}
#endif
static void *bsd_vmalloc(size_t size)
{
void *p;
mmap_lock();
/* Use map and mark the pages as used. */
p = mmap(NULL, size, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANON, -1, 0);
if (h2g_valid(p)) {
/* Allocated region overlaps guest address space.
This may recurse. */
abi_ulong addr = h2g(p);
page_set_flags(addr & TARGET_PAGE_MASK, TARGET_PAGE_ALIGN(addr + size),
PAGE_RESERVED);
}
mmap_unlock();
return p;
}
void *g_malloc(size_t size)
{
char * p;
size += 16;
p = bsd_vmalloc(size);
*(size_t *)p = size;
return p + 16;
}
/* We use map, which is always zero initialized. */
void * g_malloc0(size_t size)
{
return g_malloc(size);
}
void g_free(void *ptr)
{
/* FIXME: We should unmark the reserved pages here. However this gets
complicated when one target page spans multiple host pages, so we
don't bother. */
size_t *p;
p = (size_t *)((char *)ptr - 16);
munmap(p, *p);
}
void *g_realloc(void *ptr, size_t size)
{
size_t old_size, copy;
void *new_ptr;
if (!ptr)
return g_malloc(size);
old_size = *(size_t *)((char *)ptr - 16);
copy = old_size < size ? old_size : size;
new_ptr = g_malloc(size);
memcpy(new_ptr, ptr, copy);
g_free(ptr);
return new_ptr;
}
/* NOTE: all the constants are the HOST ones, but addresses are target. */
int target_mprotect(abi_ulong start, abi_ulong len, int prot)
{

View File

@@ -1,3 +1,19 @@
/*
* qemu bsd user mode definition
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef QEMU_H
#define QEMU_H
@@ -5,6 +21,7 @@
#include <string.h>
#include "cpu.h"
#include "exec/cpu_ldst.h"
#undef DEBUG_REMAP
#ifdef DEBUG_REMAP
@@ -149,6 +166,16 @@ void fork_end(int child);
#include "qemu/log.h"
/* strace.c */
struct syscallname {
int nr;
const char *name;
const char *format;
void (*call)(const struct syscallname *,
abi_long, abi_long, abi_long,
abi_long, abi_long, abi_long);
void (*result)(const struct syscallname *, abi_long);
};
void
print_freebsd_syscall(int num,
abi_long arg1, abi_long arg2, abi_long arg3,

View File

@@ -1,37 +1,71 @@
/*
* System call tracing and debugging
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <errno.h>
#include <sys/select.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <sys/ioccom.h>
#include <ctype.h>
#include "qemu.h"
int do_strace=0;
struct syscallname {
int nr;
const char *name;
const char *format;
void (*call)(const struct syscallname *,
abi_long, abi_long, abi_long,
abi_long, abi_long, abi_long);
void (*result)(const struct syscallname *, abi_long);
};
int do_strace;
/*
* Utility functions
*/
static void
print_execve(const struct syscallname *name,
abi_long arg1, abi_long arg2, abi_long arg3,
abi_long arg4, abi_long arg5, abi_long arg6)
static void print_sysctl(const struct syscallname *name, abi_long arg1,
abi_long arg2, abi_long arg3, abi_long arg4, abi_long arg5,
abi_long arg6)
{
uint32_t i;
int32_t *namep;
gemu_log("%s({ ", name->name);
namep = lock_user(VERIFY_READ, arg1, sizeof(int32_t) * arg2, 1);
if (namep) {
int32_t *p = namep;
for (i = 0; i < (uint32_t)arg2; i++) {
gemu_log("%d ", tswap32(*p++));
}
unlock_user(namep, arg1, 0);
}
gemu_log("}, %u, 0x" TARGET_ABI_FMT_lx ", 0x" TARGET_ABI_FMT_lx ", 0x"
TARGET_ABI_FMT_lx ", 0x" TARGET_ABI_FMT_lx ")",
(uint32_t)arg2, arg3, arg4, arg5, arg6);
}
static void print_execve(const struct syscallname *name, abi_long arg1,
abi_long arg2, abi_long arg3, abi_long arg4, abi_long arg5,
abi_long arg6)
{
abi_ulong arg_ptr_addr;
char *s;
if (!(s = lock_user_string(arg1)))
s = lock_user_string(arg1);
if (s == NULL) {
return;
}
gemu_log("%s(\"%s\",{", name->name, s);
unlock_user(s, arg1, 0);
@@ -39,29 +73,48 @@ print_execve(const struct syscallname *name,
abi_ulong *arg_ptr, arg_addr;
arg_ptr = lock_user(VERIFY_READ, arg_ptr_addr, sizeof(abi_ulong), 1);
if (!arg_ptr)
if (!arg_ptr) {
return;
}
arg_addr = tswapl(*arg_ptr);
unlock_user(arg_ptr, arg_ptr_addr, 0);
if (!arg_addr)
if (!arg_addr) {
break;
}
if ((s = lock_user_string(arg_addr))) {
gemu_log("\"%s\",", s);
unlock_user(s, arg_addr, 0);
}
}
gemu_log("NULL})");
}
static void print_ioctl(const struct syscallname *name,
abi_long arg1, abi_long arg2, abi_long arg3, abi_long arg4,
abi_long arg5, abi_long arg6)
{
/* Decode the ioctl request */
gemu_log("%s(%d, 0x%0lx { IO%s%s GRP:0x%x('%c') CMD:%d LEN:%d }, 0x"
TARGET_ABI_FMT_lx ", ...)",
name->name,
(int)arg1,
(unsigned long)arg2,
arg2 & IOC_OUT ? "R" : "",
arg2 & IOC_IN ? "W" : "",
(unsigned)IOCGROUP(arg2),
isprint(IOCGROUP(arg2)) ? (char)IOCGROUP(arg2) : '?',
(int)arg2 & 0xFF,
(int)IOCPARM_LEN(arg2),
arg3);
}
/*
* Variants for the return value output function
*/
static void
print_syscall_ret_addr(const struct syscallname *name, abi_long ret)
static void print_syscall_ret_addr(const struct syscallname *name, abi_long ret)
{
if( ret == -1 ) {
if (ret == -1) {
gemu_log(" = -1 errno=%d (%s)\n", errno, strerror(errno));
} else {
gemu_log(" = 0x" TARGET_ABI_FMT_lx "\n", ret);
@@ -90,10 +143,9 @@ static const struct syscallname openbsd_scnames[] = {
#include "openbsd/strace.list"
};
static void
print_syscall(int num, const struct syscallname *scnames, unsigned int nscnames,
abi_long arg1, abi_long arg2, abi_long arg3,
abi_long arg4, abi_long arg5, abi_long arg6)
static void print_syscall(int num, const struct syscallname *scnames,
unsigned int nscnames, abi_long arg1, abi_long arg2, abi_long arg3,
abi_long arg4, abi_long arg5, abi_long arg6)
{
unsigned int i;
const char *format="%s(" TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld ","
@@ -102,36 +154,37 @@ print_syscall(int num, const struct syscallname *scnames, unsigned int nscnames,
gemu_log("%d ", getpid() );
for (i = 0; i < nscnames; i++)
for (i = 0; i < nscnames; i++) {
if (scnames[i].nr == num) {
if (scnames[i].call != NULL) {
scnames[i].call(&scnames[i], arg1, arg2, arg3, arg4, arg5,
arg6);
arg6);
} else {
/* XXX: this format system is broken because it uses
host types and host pointers for strings */
if (scnames[i].format != NULL)
if (scnames[i].format != NULL) {
format = scnames[i].format;
gemu_log(format, scnames[i].name, arg1, arg2, arg3, arg4,
arg5, arg6);
}
gemu_log(format, scnames[i].name, arg1, arg2, arg3, arg4, arg5,
arg6);
}
return;
}
}
gemu_log("Unknown syscall %d\n", num);
}
static void
print_syscall_ret(int num, abi_long ret, const struct syscallname *scnames,
unsigned int nscnames)
static void print_syscall_ret(int num, abi_long ret,
const struct syscallname *scnames, unsigned int nscnames)
{
unsigned int i;
for (i = 0; i < nscnames; i++)
for (i = 0; i < nscnames; i++) {
if (scnames[i].nr == num) {
if (scnames[i].result != NULL) {
scnames[i].result(&scnames[i], ret);
} else {
if( ret < 0 ) {
if (ret < 0) {
gemu_log(" = -1 errno=" TARGET_ABI_FMT_ld " (%s)\n", -ret,
strerror(-ret));
} else {
@@ -140,52 +193,50 @@ print_syscall_ret(int num, abi_long ret, const struct syscallname *scnames,
}
break;
}
}
}
/*
* The public interface to this module.
*/
void
print_freebsd_syscall(int num,
abi_long arg1, abi_long arg2, abi_long arg3,
abi_long arg4, abi_long arg5, abi_long arg6)
void print_freebsd_syscall(int num, abi_long arg1, abi_long arg2, abi_long arg3,
abi_long arg4, abi_long arg5, abi_long arg6)
{
print_syscall(num, freebsd_scnames, ARRAY_SIZE(freebsd_scnames),
arg1, arg2, arg3, arg4, arg5, arg6);
print_syscall(num, freebsd_scnames, ARRAY_SIZE(freebsd_scnames), arg1, arg2,
arg3, arg4, arg5, arg6);
}
void
print_freebsd_syscall_ret(int num, abi_long ret)
void print_freebsd_syscall_ret(int num, abi_long ret)
{
print_syscall_ret(num, ret, freebsd_scnames, ARRAY_SIZE(freebsd_scnames));
}
void
print_netbsd_syscall(int num,
abi_long arg1, abi_long arg2, abi_long arg3,
abi_long arg4, abi_long arg5, abi_long arg6)
void print_netbsd_syscall(int num, abi_long arg1, abi_long arg2, abi_long arg3,
abi_long arg4, abi_long arg5, abi_long arg6)
{
print_syscall(num, netbsd_scnames, ARRAY_SIZE(netbsd_scnames),
arg1, arg2, arg3, arg4, arg5, arg6);
}
void
print_netbsd_syscall_ret(int num, abi_long ret)
void print_netbsd_syscall_ret(int num, abi_long ret)
{
print_syscall_ret(num, ret, netbsd_scnames, ARRAY_SIZE(netbsd_scnames));
}
void
print_openbsd_syscall(int num,
abi_long arg1, abi_long arg2, abi_long arg3,
abi_long arg4, abi_long arg5, abi_long arg6)
void print_openbsd_syscall(int num, abi_long arg1, abi_long arg2, abi_long arg3,
abi_long arg4, abi_long arg5, abi_long arg6)
{
print_syscall(num, openbsd_scnames, ARRAY_SIZE(openbsd_scnames),
arg1, arg2, arg3, arg4, arg5, arg6);
print_syscall(num, openbsd_scnames, ARRAY_SIZE(openbsd_scnames), arg1, arg2,
arg3, arg4, arg5, arg6);
}
void
print_openbsd_syscall_ret(int num, abi_long ret)
void print_openbsd_syscall_ret(int num, abi_long ret)
{
print_syscall_ret(num, ret, openbsd_scnames, ARRAY_SIZE(openbsd_scnames));
}

119
configure vendored
View File

@@ -3,6 +3,11 @@
# qemu configure script (c) 2003 Fabrice Bellard
#
# Unset some variables known to interfere with behavior of common tools,
# just as autoconf does.
CLICOLOR_FORCE= GREP_OPTIONS=
unset CLICOLOR_FORCE GREP_OPTIONS
# Temporary directory used for files created while
# configure runs. Since it is in the build directory
# we can safely blow away any previous version of it
@@ -182,6 +187,10 @@ path_of() {
return 1
}
have_backend () {
echo "$trace_backends" | grep "$1" >/dev/null
}
# default parameters
source_path=`dirname "$0"`
cpu=""
@@ -293,7 +302,7 @@ pkgversion=""
pie=""
zero_malloc=""
qom_cast_debug="yes"
trace_backend="nop"
trace_backends="nop"
trace_file="trace"
spice=""
rbd=""
@@ -302,8 +311,8 @@ libusb=""
usb_redir=""
glx=""
zlib="yes"
lzo="no"
snappy="no"
lzo=""
snappy=""
guest_agent=""
guest_agent_with_vss="no"
vss_win32_sdk=""
@@ -324,7 +333,7 @@ vte=""
tpm="no"
libssh2=""
vhdx=""
quorum="no"
quorum=""
# parse CC options first
for opt do
@@ -537,6 +546,9 @@ fi
# OS specific
# host *BSD for user mode
HOST_VARIANT_DIR=""
case $targetos in
CYGWIN*)
mingw32="yes"
@@ -562,12 +574,14 @@ FreeBSD)
# needed for kinfo_getvmmap(3) in libutil.h
LIBS="-lutil $LIBS"
netmap="" # enable netmap autodetect
HOST_VARIANT_DIR="freebsd"
;;
DragonFly)
bsd="yes"
make="${MAKE-gmake}"
audio_drv_list="oss"
audio_possible_drivers="oss sdl esd pa"
HOST_VARIANT_DIR="dragonfly"
;;
NetBSD)
bsd="yes"
@@ -575,12 +589,14 @@ NetBSD)
audio_drv_list="oss"
audio_possible_drivers="oss sdl esd"
oss_lib="-lossaudio"
HOST_VARIANT_DIR="netbsd"
;;
OpenBSD)
bsd="yes"
make="${MAKE-gmake}"
audio_drv_list="sdl"
audio_possible_drivers="sdl esd"
HOST_VARIANT_DIR="openbsd"
;;
Darwin)
bsd="yes"
@@ -598,6 +614,7 @@ Darwin)
# Disable attempts to use ObjectiveC features in os/object.h since they
# won't work when we're compiling with gcc as a C compiler.
QEMU_CFLAGS="-DOS_OBJECT_USE_OBJC=0 $QEMU_CFLAGS"
HOST_VARIANT_DIR="darwin"
;;
SunOS)
solaris="yes"
@@ -753,7 +770,10 @@ for opt do
;;
--target-list=*) target_list="$optarg"
;;
--enable-trace-backend=*) trace_backend="$optarg"
--enable-trace-backends=*) trace_backends="$optarg"
;;
# XXX: backwards compatibility
--enable-trace-backend=*) trace_backends="$optarg"
;;
--with-trace-file=*) trace_file="$optarg"
;;
@@ -1030,8 +1050,12 @@ for opt do
;;
--disable-zlib-test) zlib="no"
;;
--disable-lzo) lzo="no"
;;
--enable-lzo) lzo="yes"
;;
--disable-snappy) snappy="no"
;;
--enable-snappy) snappy="yes"
;;
--enable-guest-agent) guest_agent="yes"
@@ -1320,7 +1344,7 @@ Advanced options (experts only):
--disable-docs disable documentation build
--disable-vhost-net disable vhost-net acceleration support
--enable-vhost-net enable vhost-net acceleration support
--enable-trace-backend=B Set trace backend
--enable-trace-backends=B Set trace backend
Available backends: $($python $source_path/scripts/tracetool.py --list-backends)
--with-trace-file=NAME Full PATH,NAME of file to store traces
Default:trace-<pid>
@@ -1729,13 +1753,14 @@ if test "$lzo" != "no" ; then
int main(void) { lzo_version(); return 0; }
EOF
if compile_prog "" "-llzo2" ; then
:
libs_softmmu="$libs_softmmu -llzo2"
lzo="yes"
else
error_exit "lzo check failed" \
"Make sure to have the lzo libs and headers installed."
if test "$lzo" = "yes"; then
feature_not_found "liblzo2" "Install liblzo2 devel"
fi
lzo="no"
fi
libs_softmmu="$libs_softmmu -llzo2"
fi
##########################################
@@ -1747,13 +1772,14 @@ if test "$snappy" != "no" ; then
int main(void) { snappy_max_compressed_length(4096); return 0; }
EOF
if compile_prog "" "-lsnappy" ; then
:
libs_softmmu="$libs_softmmu -lsnappy"
snappy="yes"
else
error_exit "snappy check failed" \
"Make sure to have the snappy libs and headers installed."
if test "$snappy" = "yes"; then
feature_not_found "libsnappy" "Install libsnappy devel"
fi
snappy="no"
fi
libs_softmmu="$libs_softmmu -lsnappy"
fi
##########################################
@@ -1986,6 +2012,7 @@ fi
if test "$gtk" != "no"; then
gtkpackage="gtk+-$gtkabi"
gtkx11package="gtk+-x11-$gtkabi"
if test "$gtkabi" = "3.0" ; then
gtkversion="3.0.0"
else
@@ -1994,6 +2021,9 @@ if test "$gtk" != "no"; then
if $pkg_config --exists "$gtkpackage >= $gtkversion"; then
gtk_cflags=`$pkg_config --cflags $gtkpackage`
gtk_libs=`$pkg_config --libs $gtkpackage`
if $pkg_config --exists "$gtkx11package >= $gtkversion"; then
gtk_libs="$gtk_libs -lX11"
fi
libs_softmmu="$gtk_libs $libs_softmmu"
gtk="yes"
elif test "$gtk" = "yes"; then
@@ -2195,9 +2225,12 @@ if compile_prog "$quorum_tls_cflags" "$quorum_tls_libs" ; then
libs_softmmu="$quorum_tls_libs $libs_softmmu"
libs_tools="$quorum_tls_libs $libs_softmmu"
QEMU_CFLAGS="$QEMU_CFLAGS $quorum_tls_cflags"
quorum="yes"
else
echo "gnutls > 2.10.0 required to compile Quorum"
exit 1
if test "$quorum" = "yes"; then
feature_not_found "gnutls" "gnutls > 2.10.0 required to compile Quorum"
fi
quorum="no"
fi
fi
@@ -3445,9 +3478,9 @@ EOF
if compile_prog "" "" ; then
:
# we need pthread for static linking. use previous pthread test result
elif compile_prog "" "-lrt $pthread_lib" ; then
LIBS="-lrt $LIBS"
libs_qga="-lrt $libs_qga"
elif compile_prog "" "$pthread_lib -lrt" ; then
LIBS="$LIBS -lrt"
libs_qga="$libs_qga -lrt"
fi
if test "$darwin" != "yes" -a "$mingw32" != "yes" -a "$solaris" != yes -a \
@@ -3666,15 +3699,15 @@ fi
##########################################
# check if trace backend exists
$python "$source_path/scripts/tracetool.py" "--backend=$trace_backend" --check-backend > /dev/null 2> /dev/null
$python "$source_path/scripts/tracetool.py" "--backends=$trace_backends" --check-backends > /dev/null 2> /dev/null
if test "$?" -ne 0 ; then
error_exit "invalid trace backend" \
"Please choose a supported trace backend."
error_exit "invalid trace backends" \
"Please choose supported trace backends."
fi
##########################################
# For 'ust' backend, test if ust headers are present
if test "$trace_backend" = "ust"; then
if have_backend "ust"; then
cat > $TMPC << EOF
#include <lttng/tracepoint.h>
int main(void) { return 0; }
@@ -3700,7 +3733,7 @@ fi
##########################################
# For 'dtrace' backend, test if 'dtrace' command is present
if test "$trace_backend" = "dtrace"; then
if have_backend "dtrace"; then
if ! has 'dtrace' ; then
error_exit "dtrace command is not found in PATH $PATH"
fi
@@ -4170,7 +4203,7 @@ echo "uuid support $uuid"
echo "libcap-ng support $cap_ng"
echo "vhost-net support $vhost_net"
echo "vhost-scsi support $vhost_scsi"
echo "Trace backend $trace_backend"
echo "Trace backends $trace_backends"
if test "$trace_backend" = "simple"; then
echo "Trace output file $trace_file-<pid>"
fi
@@ -4664,43 +4697,35 @@ if test "$tpm" = "yes"; then
fi
fi
# use default implementation for tracing backend-specific routines
trace_default=yes
echo "TRACE_BACKEND=$trace_backend" >> $config_host_mak
if test "$trace_backend" = "nop"; then
echo "TRACE_BACKENDS=$trace_backends" >> $config_host_mak
if have_backend "nop"; then
echo "CONFIG_TRACE_NOP=y" >> $config_host_mak
fi
if test "$trace_backend" = "simple"; then
if have_backend "simple"; then
echo "CONFIG_TRACE_SIMPLE=y" >> $config_host_mak
trace_default=no
# Set the appropriate trace file.
trace_file="\"$trace_file-\" FMT_pid"
fi
if test "$trace_backend" = "stderr"; then
if have_backend "stderr"; then
echo "CONFIG_TRACE_STDERR=y" >> $config_host_mak
trace_default=no
fi
if test "$trace_backend" = "ust"; then
if have_backend "ust"; then
echo "CONFIG_TRACE_UST=y" >> $config_host_mak
fi
if test "$trace_backend" = "dtrace"; then
if have_backend "dtrace"; then
echo "CONFIG_TRACE_DTRACE=y" >> $config_host_mak
if test "$trace_backend_stap" = "yes" ; then
echo "CONFIG_TRACE_SYSTEMTAP=y" >> $config_host_mak
fi
fi
if test "$trace_backend" = "ftrace"; then
if have_backend "ftrace"; then
if test "$linux" = "yes" ; then
echo "CONFIG_TRACE_FTRACE=y" >> $config_host_mak
trace_default=no
else
feature_not_found "ftrace(trace backend)" "ftrace requires Linux"
fi
fi
echo "CONFIG_TRACE_FILE=$trace_file" >> $config_host_mak
if test "$trace_default" = "yes"; then
echo "CONFIG_TRACE_DEFAULT=y" >> $config_host_mak
fi
if test "$rdma" = "yes" ; then
echo "CONFIG_RDMA=y" >> $config_host_mak
@@ -4930,6 +4955,12 @@ case "$target_name" in
TARGET_ABI_DIR=ppc
gdb_xml_files="power64-core.xml power-fpu.xml power-altivec.xml power-spe.xml"
;;
ppc64le)
TARGET_ARCH=ppc64
TARGET_BASE_ARCH=ppc
TARGET_ABI_DIR=ppc
gdb_xml_files="power64-core.xml power-fpu.xml power-altivec.xml power-spe.xml"
;;
ppc64abi32)
TARGET_ARCH=ppc64
TARGET_BASE_ARCH=ppc
@@ -4982,6 +5013,9 @@ if [ "$TARGET_ABI_DIR" = "" ]; then
TARGET_ABI_DIR=$TARGET_ARCH
fi
echo "TARGET_ABI_DIR=$TARGET_ABI_DIR" >> $config_target_mak
if [ "$HOST_VARIANT_DIR" != "" ]; then
echo "HOST_VARIANT_DIR=$HOST_VARIANT_DIR" >> $config_target_mak
fi
case "$target_name" in
i386|x86_64)
if test "$xen" = "yes" -a "$target_softmmu" = "yes" ; then
@@ -5194,6 +5228,7 @@ for bios_file in \
$source_path/pc-bios/*.dtb \
$source_path/pc-bios/*.img \
$source_path/pc-bios/openbios-* \
$source_path/pc-bios/u-boot.* \
$source_path/pc-bios/palcode-*
do
FILES="$FILES pc-bios/`basename $bios_file`"

View File

@@ -30,20 +30,14 @@ typedef struct {
CoroutineAction action;
} CoroutineGThread;
static GStaticMutex coroutine_lock = G_STATIC_MUTEX_INIT;
static CompatGMutex coroutine_lock;
static CompatGCond coroutine_cond;
/* GLib 2.31 and beyond deprecated various parts of the thread API,
* but the new interfaces are not available in older GLib versions
* so we have to cope with both.
*/
#if GLIB_CHECK_VERSION(2, 31, 0)
/* Default zero-initialisation is sufficient for 2.31+ GCond */
static GCond the_coroutine_cond;
static GCond *coroutine_cond = &the_coroutine_cond;
static inline void init_coroutine_cond(void)
{
}
/* Awkwardly, the GPrivate API doesn't provide a way to update the
* GDestroyNotify handler for the coroutine key dynamically. So instead
* we track whether or not the CoroutineGThread should be freed on
@@ -84,11 +78,6 @@ static inline GThread *create_thread(GThreadFunc func, gpointer data)
#else
/* Handle older GLib versions */
static GCond *coroutine_cond;
static inline void init_coroutine_cond(void)
{
coroutine_cond = g_cond_new();
}
static GStaticPrivate coroutine_key = G_STATIC_PRIVATE_INIT;
@@ -120,22 +109,20 @@ static void __attribute__((constructor)) coroutine_init(void)
g_thread_init(NULL);
}
#endif
init_coroutine_cond();
}
static void coroutine_wait_runnable_locked(CoroutineGThread *co)
{
while (!co->runnable) {
g_cond_wait(coroutine_cond, g_static_mutex_get_mutex(&coroutine_lock));
g_cond_wait(&coroutine_cond, &coroutine_lock);
}
}
static void coroutine_wait_runnable(CoroutineGThread *co)
{
g_static_mutex_lock(&coroutine_lock);
g_mutex_lock(&coroutine_lock);
coroutine_wait_runnable_locked(co);
g_static_mutex_unlock(&coroutine_lock);
g_mutex_unlock(&coroutine_lock);
}
static gpointer coroutine_thread(gpointer opaque)
@@ -177,17 +164,17 @@ CoroutineAction qemu_coroutine_switch(Coroutine *from_,
CoroutineGThread *from = DO_UPCAST(CoroutineGThread, base, from_);
CoroutineGThread *to = DO_UPCAST(CoroutineGThread, base, to_);
g_static_mutex_lock(&coroutine_lock);
g_mutex_lock(&coroutine_lock);
from->runnable = false;
from->action = action;
to->runnable = true;
to->action = action;
g_cond_broadcast(coroutine_cond);
g_cond_broadcast(&coroutine_cond);
if (action != COROUTINE_TERMINATE) {
coroutine_wait_runnable_locked(from);
}
g_static_mutex_unlock(&coroutine_lock);
g_mutex_unlock(&coroutine_lock);
return from->action;
}

2
cpus.c
View File

@@ -347,7 +347,7 @@ void qtest_clock_warp(int64_t dest)
assert(qtest_enabled());
while (clock < dest) {
int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
int64_t warp = MIN(dest - clock, deadline);
int64_t warp = qemu_soonest_timeout(dest - clock, deadline);
seqlock_write_lock(&timers_state.vm_clock_seqlock);
qemu_icount_bias += warp;
seqlock_write_unlock(&timers_state.vm_clock_seqlock);

View File

@@ -22,11 +22,13 @@
#include "exec/exec-all.h"
#include "exec/memory.h"
#include "exec/address-spaces.h"
#include "exec/cpu_ldst.h"
#include "exec/cputlb.h"
#include "exec/memory-internal.h"
#include "exec/ram_addr.h"
#include "tcg/tcg.h"
//#define DEBUG_TLB
//#define DEBUG_TLB_CHECK
@@ -330,21 +332,36 @@ tb_page_addr_t get_page_addr_code(CPUArchState *env1, target_ulong addr)
return qemu_ram_addr_from_host_nofail(p);
}
#define MMUSUFFIX _mmu
#define SHIFT 0
#include "softmmu_template.h"
#define SHIFT 1
#include "softmmu_template.h"
#define SHIFT 2
#include "softmmu_template.h"
#define SHIFT 3
#include "softmmu_template.h"
#undef MMUSUFFIX
#define MMUSUFFIX _cmmu
#undef GETPC
#define GETPC() ((uintptr_t)0)
#undef GETPC_ADJ
#define GETPC_ADJ 0
#undef GETRA
#define GETRA() ((uintptr_t)0)
#define SOFTMMU_CODE_ACCESS
#define SHIFT 0
#include "exec/softmmu_template.h"
#include "softmmu_template.h"
#define SHIFT 1
#include "exec/softmmu_template.h"
#include "softmmu_template.h"
#define SHIFT 2
#include "exec/softmmu_template.h"
#include "softmmu_template.h"
#define SHIFT 3
#include "exec/softmmu_template.h"
#undef env
#include "softmmu_template.h"

View File

@@ -1 +1,2 @@
# Default configuration for ppc-linux-user
CONFIG_LIBDECNUMBER=y

View File

@@ -49,3 +49,4 @@ CONFIG_OPENPIC_KVM=$(and $(CONFIG_E500),$(CONFIG_KVM))
CONFIG_MC146818RTC=y
CONFIG_ETSEC=y
CONFIG_ISA_TESTDEV=y
CONFIG_LIBDECNUMBER=y

View File

@@ -1 +1,2 @@
# Default configuration for ppc64-linux-user
CONFIG_LIBDECNUMBER=y

View File

@@ -58,3 +58,4 @@ CONFIG_I82374=y
CONFIG_I8257=y
CONFIG_MC146818RTC=y
CONFIG_ISA_TESTDEV=y
CONFIG_LIBDECNUMBER=y

View File

@@ -1 +1,2 @@
# Default configuration for ppc64abi32-linux-user
CONFIG_LIBDECNUMBER=y

View File

@@ -0,0 +1,2 @@
# Default configuration for ppc64le-linux-user
CONFIG_LIBDECNUMBER=y

View File

@@ -16,3 +16,4 @@ CONFIG_I8259=y
CONFIG_XILINX=y
CONFIG_XILINX_ETHLITE=y
CONFIG_OPENPIC=y
CONFIG_LIBDECNUMBER=y

View File

@@ -40,7 +40,7 @@ DriveInfo *add_init_drive(const char *optstr)
return NULL;
mc = MACHINE_GET_CLASS(current_machine);
dinfo = drive_init(opts, mc->block_default_type);
dinfo = drive_new(opts, mc->block_default_type);
if (!dinfo) {
qemu_opts_del(opts);
return NULL;
@@ -76,6 +76,6 @@ void drive_hot_add(Monitor *mon, const QDict *qdict)
err:
if (dinfo) {
drive_put_ref(dinfo);
drive_del(dinfo);
}
}

21
disas.c
View File

@@ -191,7 +191,8 @@ static int print_insn_od_target(bfd_vma pc, disassemble_info *info)
values:
i386 - 1 means 16 bit code, 2 means 64 bit code
arm - bit 0 = thumb, bit 1 = reverse endian, bit 2 = A64
ppc - nonzero means little endian
ppc - bits 0:15 specify (optionally) the machine instruction set;
bit 16 indicates little endian.
other targets - unused
*/
void target_disas(FILE *out, CPUArchState *env, target_ulong code,
@@ -251,11 +252,11 @@ void target_disas(FILE *out, CPUArchState *env, target_ulong code,
s.info.mach = bfd_mach_sparc_v9b;
#endif
#elif defined(TARGET_PPC)
if (flags >> 16) {
if ((flags >> 16) & 1) {
s.info.endian = BFD_ENDIAN_LITTLE;
}
if (flags & 0xFFFF) {
/* If we have a precise definitions of the instructions set, use it */
/* If we have a precise definition of the instruction set, use it. */
s.info.mach = flags & 0xFFFF;
} else {
#ifdef TARGET_PPC64
@@ -444,6 +445,8 @@ monitor_fprintf(FILE *stream, const char *fmt, ...)
return 0;
}
/* Disassembler for the monitor.
See target_disas for a description of flags. */
void monitor_disas(Monitor *mon, CPUArchState *env,
target_ulong pc, int nb_insn, int is_physical, int flags)
{
@@ -484,11 +487,19 @@ void monitor_disas(Monitor *mon, CPUArchState *env,
s.info.mach = bfd_mach_sparc_v9b;
#endif
#elif defined(TARGET_PPC)
if (flags & 0xFFFF) {
/* If we have a precise definition of the instruction set, use it. */
s.info.mach = flags & 0xFFFF;
} else {
#ifdef TARGET_PPC64
s.info.mach = bfd_mach_ppc64;
s.info.mach = bfd_mach_ppc64;
#else
s.info.mach = bfd_mach_ppc;
s.info.mach = bfd_mach_ppc;
#endif
}
if ((flags >> 16) & 1) {
s.info.endian = BFD_ENDIAN_LITTLE;
}
print_insn = print_insn_ppc;
#elif defined(TARGET_M68K)
print_insn = print_insn_m68k;

View File

@@ -47,6 +47,7 @@ In ubuntu/debian:
Configuring and building:
./configure --enable-smartcard && make
3. Using ccid-card-emulated with hardware
Assuming you have a working smartcard on the host with the current
@@ -54,19 +55,55 @@ user, using NSS, qemu acts as another NSS client using ccid-card-emulated:
qemu -usb -device usb-ccid -device ccid-card-emulated
4. Using ccid-card-emulated with certificates
You must create the certificates. This is a one time process. We use NSS
certificates:
4. Using ccid-card-emulated with certificates stored in files
certutil -d /etc/pki/nssdb -x -t "CT,CT,CT" -S -s "CN=cert1" -n cert1
You must create the CA and card certificates. This is a one time process.
We use NSS certificates:
mkdir fake-smartcard
cd fake-smartcard
certutil -N -d sql:$PWD
certutil -S -d sql:$PWD -s "CN=Fake Smart Card CA" -x -t TC,TC,TC -n fake-smartcard-ca
certutil -S -d sql:$PWD -t ,, -s "CN=John Doe" -n id-cert -c fake-smartcard-ca
certutil -S -d sql:$PWD -t ,, -s "CN=John Doe (signing)" --nsCertType smime -n signing-cert -c fake-smartcard-ca
certutil -S -d sql:$PWD -t ,, -s "CN=John Doe (encryption)" --nsCertType sslClient -n encryption-cert -c fake-smartcard-ca
Note: you must have exactly three certificates.
Assuming the current user can access the certificates (use certutil -L to
verify), you can use the emulated card type with the certificates backend:
You can use the emulated card type with the certificates backend:
qemu -usb -device usb-ccid -device ccid-card-emulated,backend=certificates,db=sql:$PWD,cert1=id-cert,cert2=signing-cert,cert3=encryption-cert
To use the certificates in the guest, export the CA certificate:
certutil -L -r -d sql:$PWD -o fake-smartcard-ca.cer -n fake-smartcard-ca
and import it in the guest:
certutil -A -d /etc/pki/nssdb -i fake-smartcard-ca.cer -t TC,TC,TC -n fake-smartcard-ca
In a Linux guest you can then use the CoolKey PKCS #11 module to access
the card:
certutil -d /etc/pki/nssdb -L -h all
It will prompt you for the PIN (which is the password you assigned to the
certificate database early on), and then show you all three certificates
together with the manually imported CA cert:
Certificate Nickname Trust Attributes
fake-smartcard-ca CT,C,C
John Doe:CAC ID Certificate u,u,u
John Doe:CAC Email Signature Certificate u,u,u
John Doe:CAC Email Encryption Certificate u,u,u
If this does not happen, CoolKey is not installed or not registered with
NSS. Registration can be done from Firefox or the command line:
modutil -dbdir /etc/pki/nssdb -add "CAC Module" -libfile /usr/lib64/pkcs11/libcoolkeypk11.so
modutil -dbdir /etc/pki/nssdb -list
qemu -usb -device usb-ccid -device ccid-card-emulated,backend=certificates,cert1=cert1,cert2=cert2,cert3=cert3
5. Using ccid-card-passthru with client side hardware
@@ -74,15 +111,23 @@ on the host specify the ccid-card-passthru device with a suitable chardev:
qemu -chardev socket,server,host=0.0.0.0,port=2001,id=ccid,nowait -usb -device usb-ccid -device ccid-card-passthru,chardev=ccid
on the client run vscclient, built when you built the libcacard library:
libcacard/vscclient <qemu-host> 2001
on the client run vscclient, built when you built QEMU:
vscclient <qemu-host> 2001
6. Using ccid-card-passthru with client side certificates
Run qemu as per #5, and run vscclient as follows:
(Note: vscclient command line interface is in a state of change)
This case is not particularly useful, but you can use it to debug
your setup if #4 works but #5 does not.
Follow instructions as per #4, except run QEMU and vscclient as follows:
Run qemu as per #5, and run vscclient from the "fake-smartcard"
directory as follows:
qemu -chardev socket,server,host=0.0.0.0,port=2001,id=ccid,nowait -usb -device usb-ccid -device ccid-card-passthru,chardev=ccid
vscclient -e "db=\"sql:$PWD\" use_hw=no soft=(,Test,CAC,,id-cert,signing-cert,encryption-cert)" <qemu-host> 2001
libcacard/vscclient -e "db=\"/etc/pki/nssdb\" use_hw=no soft=(,Test,CAC,,cert1,cert2,cert3)" <qemu-host> 2001
7. Passthrough protocol scenario
@@ -126,10 +171,11 @@ kill/quit | | | |
8. libcacard
ccid-card-passthru and vscclient use libcacard as the card emulator.
libcacard implements a completely virtual CAC (DoD standard for smart cards)
compliant card and uses NSS to actually retrive certificates and do any
encryption using the backend (real reader + card or file backed certificates).
Both ccid-card-emulated and vscclient use libcacard as the card emulator.
libcacard implements a completely virtual CAC (DoD standard for smart
cards) compliant card and uses NSS to retrieve certificates and do
any encryption. The backend can then be a real reader and card, or
certificates stored in files.
For documentation of cac_card see README in libcacard subdirectory.
For documentation of the library see docs/libcacard.txt.

View File

@@ -9,7 +9,7 @@ for debugging, profiling, and observing execution.
1. Build with the 'simple' trace backend:
./configure --enable-trace-backend=simple
./configure --enable-trace-backends=simple
make
2. Create a file with the events you want to trace:
@@ -142,7 +142,7 @@ script.
The trace backend is chosen at configure time and only one trace backend can
be built into the binary:
./configure --trace-backend=simple
./configure --trace-backends=simple
For a list of supported trace backends, try ./configure --help or see below.

View File

@@ -35,7 +35,8 @@ which will return a dictionary containing:
o A key named last-update, which contains the last stats update
timestamp in seconds. Since this timestamp is generated by the host,
a buggy guest can't influence its value
a buggy guest can't influence its value. The value is 0 if the guest
has not updated the stats (yet).
It's also important to note the following:
@@ -49,7 +50,7 @@ It's also important to note the following:
- Polling can be enabled even if the guest doesn't have stats support
or the balloon driver wasn't loaded in the guest. If this is the case
and stats are queried, an error will be returned
and stats are queried, last-update will be 0.
- The polling timer is only re-armed when the guest responds to the
statistics request. This means that if a (buggy) guest doesn't ever

363
dump.c
View File

@@ -36,9 +36,9 @@
#define ELF_MACHINE_UNAME "Unknown"
#endif
static uint16_t cpu_convert_to_target16(uint16_t val, int endian)
uint16_t cpu_to_dump16(DumpState *s, uint16_t val)
{
if (endian == ELFDATA2LSB) {
if (s->dump_info.d_endian == ELFDATA2LSB) {
val = cpu_to_le16(val);
} else {
val = cpu_to_be16(val);
@@ -47,9 +47,9 @@ static uint16_t cpu_convert_to_target16(uint16_t val, int endian)
return val;
}
static uint32_t cpu_convert_to_target32(uint32_t val, int endian)
uint32_t cpu_to_dump32(DumpState *s, uint32_t val)
{
if (endian == ELFDATA2LSB) {
if (s->dump_info.d_endian == ELFDATA2LSB) {
val = cpu_to_le32(val);
} else {
val = cpu_to_be32(val);
@@ -58,9 +58,9 @@ static uint32_t cpu_convert_to_target32(uint32_t val, int endian)
return val;
}
static uint64_t cpu_convert_to_target64(uint64_t val, int endian)
uint64_t cpu_to_dump64(DumpState *s, uint64_t val)
{
if (endian == ELFDATA2LSB) {
if (s->dump_info.d_endian == ELFDATA2LSB) {
val = cpu_to_le64(val);
} else {
val = cpu_to_be64(val);
@@ -69,38 +69,6 @@ static uint64_t cpu_convert_to_target64(uint64_t val, int endian)
return val;
}
typedef struct DumpState {
GuestPhysBlockList guest_phys_blocks;
ArchDumpInfo dump_info;
MemoryMappingList list;
uint16_t phdr_num;
uint32_t sh_info;
bool have_section;
bool resume;
ssize_t note_size;
hwaddr memory_offset;
int fd;
GuestPhysBlock *next_block;
ram_addr_t start;
bool has_filter;
int64_t begin;
int64_t length;
uint8_t *note_buf; /* buffer for notes */
size_t note_buf_offset; /* the writing place in note_buf */
uint32_t nr_cpus; /* number of guest's cpu */
size_t page_size; /* guest's page size */
uint32_t page_shift; /* guest's page shift */
uint64_t max_mapnr; /* the biggest guest's phys-mem's number */
size_t len_dump_bitmap; /* the size of the place used to store
dump_bitmap in vmcore */
off_t offset_dump_bitmap; /* offset of dump_bitmap part in vmcore */
off_t offset_page; /* offset of page part in vmcore */
size_t num_dumpable; /* number of page that can be dumped */
uint32_t flag_compress; /* indicate the compression format */
} DumpState;
static int dump_cleanup(DumpState *s)
{
int ret = 0;
@@ -139,29 +107,25 @@ static int write_elf64_header(DumpState *s)
{
Elf64_Ehdr elf_header;
int ret;
int endian = s->dump_info.d_endian;
memset(&elf_header, 0, sizeof(Elf64_Ehdr));
memcpy(&elf_header, ELFMAG, SELFMAG);
elf_header.e_ident[EI_CLASS] = ELFCLASS64;
elf_header.e_ident[EI_DATA] = s->dump_info.d_endian;
elf_header.e_ident[EI_VERSION] = EV_CURRENT;
elf_header.e_type = cpu_convert_to_target16(ET_CORE, endian);
elf_header.e_machine = cpu_convert_to_target16(s->dump_info.d_machine,
endian);
elf_header.e_version = cpu_convert_to_target32(EV_CURRENT, endian);
elf_header.e_ehsize = cpu_convert_to_target16(sizeof(elf_header), endian);
elf_header.e_phoff = cpu_convert_to_target64(sizeof(Elf64_Ehdr), endian);
elf_header.e_phentsize = cpu_convert_to_target16(sizeof(Elf64_Phdr),
endian);
elf_header.e_phnum = cpu_convert_to_target16(s->phdr_num, endian);
elf_header.e_type = cpu_to_dump16(s, ET_CORE);
elf_header.e_machine = cpu_to_dump16(s, s->dump_info.d_machine);
elf_header.e_version = cpu_to_dump32(s, EV_CURRENT);
elf_header.e_ehsize = cpu_to_dump16(s, sizeof(elf_header));
elf_header.e_phoff = cpu_to_dump64(s, sizeof(Elf64_Ehdr));
elf_header.e_phentsize = cpu_to_dump16(s, sizeof(Elf64_Phdr));
elf_header.e_phnum = cpu_to_dump16(s, s->phdr_num);
if (s->have_section) {
uint64_t shoff = sizeof(Elf64_Ehdr) + sizeof(Elf64_Phdr) * s->sh_info;
elf_header.e_shoff = cpu_convert_to_target64(shoff, endian);
elf_header.e_shentsize = cpu_convert_to_target16(sizeof(Elf64_Shdr),
endian);
elf_header.e_shnum = cpu_convert_to_target16(1, endian);
elf_header.e_shoff = cpu_to_dump64(s, shoff);
elf_header.e_shentsize = cpu_to_dump16(s, sizeof(Elf64_Shdr));
elf_header.e_shnum = cpu_to_dump16(s, 1);
}
ret = fd_write_vmcore(&elf_header, sizeof(elf_header), s);
@@ -177,29 +141,25 @@ static int write_elf32_header(DumpState *s)
{
Elf32_Ehdr elf_header;
int ret;
int endian = s->dump_info.d_endian;
memset(&elf_header, 0, sizeof(Elf32_Ehdr));
memcpy(&elf_header, ELFMAG, SELFMAG);
elf_header.e_ident[EI_CLASS] = ELFCLASS32;
elf_header.e_ident[EI_DATA] = endian;
elf_header.e_ident[EI_DATA] = s->dump_info.d_endian;
elf_header.e_ident[EI_VERSION] = EV_CURRENT;
elf_header.e_type = cpu_convert_to_target16(ET_CORE, endian);
elf_header.e_machine = cpu_convert_to_target16(s->dump_info.d_machine,
endian);
elf_header.e_version = cpu_convert_to_target32(EV_CURRENT, endian);
elf_header.e_ehsize = cpu_convert_to_target16(sizeof(elf_header), endian);
elf_header.e_phoff = cpu_convert_to_target32(sizeof(Elf32_Ehdr), endian);
elf_header.e_phentsize = cpu_convert_to_target16(sizeof(Elf32_Phdr),
endian);
elf_header.e_phnum = cpu_convert_to_target16(s->phdr_num, endian);
elf_header.e_type = cpu_to_dump16(s, ET_CORE);
elf_header.e_machine = cpu_to_dump16(s, s->dump_info.d_machine);
elf_header.e_version = cpu_to_dump32(s, EV_CURRENT);
elf_header.e_ehsize = cpu_to_dump16(s, sizeof(elf_header));
elf_header.e_phoff = cpu_to_dump32(s, sizeof(Elf32_Ehdr));
elf_header.e_phentsize = cpu_to_dump16(s, sizeof(Elf32_Phdr));
elf_header.e_phnum = cpu_to_dump16(s, s->phdr_num);
if (s->have_section) {
uint32_t shoff = sizeof(Elf32_Ehdr) + sizeof(Elf32_Phdr) * s->sh_info;
elf_header.e_shoff = cpu_convert_to_target32(shoff, endian);
elf_header.e_shentsize = cpu_convert_to_target16(sizeof(Elf32_Shdr),
endian);
elf_header.e_shnum = cpu_convert_to_target16(1, endian);
elf_header.e_shoff = cpu_to_dump32(s, shoff);
elf_header.e_shentsize = cpu_to_dump16(s, sizeof(Elf32_Shdr));
elf_header.e_shnum = cpu_to_dump16(s, 1);
}
ret = fd_write_vmcore(&elf_header, sizeof(elf_header), s);
@@ -217,15 +177,14 @@ static int write_elf64_load(DumpState *s, MemoryMapping *memory_mapping,
{
Elf64_Phdr phdr;
int ret;
int endian = s->dump_info.d_endian;
memset(&phdr, 0, sizeof(Elf64_Phdr));
phdr.p_type = cpu_convert_to_target32(PT_LOAD, endian);
phdr.p_offset = cpu_convert_to_target64(offset, endian);
phdr.p_paddr = cpu_convert_to_target64(memory_mapping->phys_addr, endian);
phdr.p_filesz = cpu_convert_to_target64(filesz, endian);
phdr.p_memsz = cpu_convert_to_target64(memory_mapping->length, endian);
phdr.p_vaddr = cpu_convert_to_target64(memory_mapping->virt_addr, endian);
phdr.p_type = cpu_to_dump32(s, PT_LOAD);
phdr.p_offset = cpu_to_dump64(s, offset);
phdr.p_paddr = cpu_to_dump64(s, memory_mapping->phys_addr);
phdr.p_filesz = cpu_to_dump64(s, filesz);
phdr.p_memsz = cpu_to_dump64(s, memory_mapping->length);
phdr.p_vaddr = cpu_to_dump64(s, memory_mapping->virt_addr);
assert(memory_mapping->length >= filesz);
@@ -244,15 +203,14 @@ static int write_elf32_load(DumpState *s, MemoryMapping *memory_mapping,
{
Elf32_Phdr phdr;
int ret;
int endian = s->dump_info.d_endian;
memset(&phdr, 0, sizeof(Elf32_Phdr));
phdr.p_type = cpu_convert_to_target32(PT_LOAD, endian);
phdr.p_offset = cpu_convert_to_target32(offset, endian);
phdr.p_paddr = cpu_convert_to_target32(memory_mapping->phys_addr, endian);
phdr.p_filesz = cpu_convert_to_target32(filesz, endian);
phdr.p_memsz = cpu_convert_to_target32(memory_mapping->length, endian);
phdr.p_vaddr = cpu_convert_to_target32(memory_mapping->virt_addr, endian);
phdr.p_type = cpu_to_dump32(s, PT_LOAD);
phdr.p_offset = cpu_to_dump32(s, offset);
phdr.p_paddr = cpu_to_dump32(s, memory_mapping->phys_addr);
phdr.p_filesz = cpu_to_dump32(s, filesz);
phdr.p_memsz = cpu_to_dump32(s, memory_mapping->length);
phdr.p_vaddr = cpu_to_dump32(s, memory_mapping->virt_addr);
assert(memory_mapping->length >= filesz);
@@ -268,16 +226,15 @@ static int write_elf32_load(DumpState *s, MemoryMapping *memory_mapping,
static int write_elf64_note(DumpState *s)
{
Elf64_Phdr phdr;
int endian = s->dump_info.d_endian;
hwaddr begin = s->memory_offset - s->note_size;
int ret;
memset(&phdr, 0, sizeof(Elf64_Phdr));
phdr.p_type = cpu_convert_to_target32(PT_NOTE, endian);
phdr.p_offset = cpu_convert_to_target64(begin, endian);
phdr.p_type = cpu_to_dump32(s, PT_NOTE);
phdr.p_offset = cpu_to_dump64(s, begin);
phdr.p_paddr = 0;
phdr.p_filesz = cpu_convert_to_target64(s->note_size, endian);
phdr.p_memsz = cpu_convert_to_target64(s->note_size, endian);
phdr.p_filesz = cpu_to_dump64(s, s->note_size);
phdr.p_memsz = cpu_to_dump64(s, s->note_size);
phdr.p_vaddr = 0;
ret = fd_write_vmcore(&phdr, sizeof(Elf64_Phdr), s);
@@ -324,15 +281,14 @@ static int write_elf32_note(DumpState *s)
{
hwaddr begin = s->memory_offset - s->note_size;
Elf32_Phdr phdr;
int endian = s->dump_info.d_endian;
int ret;
memset(&phdr, 0, sizeof(Elf32_Phdr));
phdr.p_type = cpu_convert_to_target32(PT_NOTE, endian);
phdr.p_offset = cpu_convert_to_target32(begin, endian);
phdr.p_type = cpu_to_dump32(s, PT_NOTE);
phdr.p_offset = cpu_to_dump32(s, begin);
phdr.p_paddr = 0;
phdr.p_filesz = cpu_convert_to_target32(s->note_size, endian);
phdr.p_memsz = cpu_convert_to_target32(s->note_size, endian);
phdr.p_filesz = cpu_to_dump32(s, s->note_size);
phdr.p_memsz = cpu_to_dump32(s, s->note_size);
phdr.p_vaddr = 0;
ret = fd_write_vmcore(&phdr, sizeof(Elf32_Phdr), s);
@@ -374,7 +330,6 @@ static int write_elf_section(DumpState *s, int type)
{
Elf32_Shdr shdr32;
Elf64_Shdr shdr64;
int endian = s->dump_info.d_endian;
int shdr_size;
void *shdr;
int ret;
@@ -382,12 +337,12 @@ static int write_elf_section(DumpState *s, int type)
if (type == 0) {
shdr_size = sizeof(Elf32_Shdr);
memset(&shdr32, 0, shdr_size);
shdr32.sh_info = cpu_convert_to_target32(s->sh_info, endian);
shdr32.sh_info = cpu_to_dump32(s, s->sh_info);
shdr = &shdr32;
} else {
shdr_size = sizeof(Elf64_Shdr);
memset(&shdr64, 0, shdr_size);
shdr64.sh_info = cpu_convert_to_target32(s->sh_info, endian);
shdr64.sh_info = cpu_to_dump32(s, s->sh_info);
shdr = &shdr64;
}
@@ -711,27 +666,25 @@ static int create_vmcore(DumpState *s)
static int write_start_flat_header(int fd)
{
uint8_t *buf;
MakedumpfileHeader mh;
MakedumpfileHeader *mh;
int ret = 0;
memset(&mh, 0, sizeof(mh));
strncpy(mh.signature, MAKEDUMPFILE_SIGNATURE,
strlen(MAKEDUMPFILE_SIGNATURE));
QEMU_BUILD_BUG_ON(sizeof *mh > MAX_SIZE_MDF_HEADER);
mh = g_malloc0(MAX_SIZE_MDF_HEADER);
mh.type = cpu_to_be64(TYPE_FLAT_HEADER);
mh.version = cpu_to_be64(VERSION_FLAT_HEADER);
memcpy(mh->signature, MAKEDUMPFILE_SIGNATURE,
MIN(sizeof mh->signature, sizeof MAKEDUMPFILE_SIGNATURE));
buf = g_malloc0(MAX_SIZE_MDF_HEADER);
memcpy(buf, &mh, sizeof(mh));
mh->type = cpu_to_be64(TYPE_FLAT_HEADER);
mh->version = cpu_to_be64(VERSION_FLAT_HEADER);
size_t written_size;
written_size = qemu_write_full(fd, buf, MAX_SIZE_MDF_HEADER);
written_size = qemu_write_full(fd, mh, MAX_SIZE_MDF_HEADER);
if (written_size != MAX_SIZE_MDF_HEADER) {
ret = -1;
}
g_free(buf);
g_free(mh);
return ret;
}
@@ -795,7 +748,6 @@ static int create_header32(DumpState *s)
DiskDumpHeader32 *dh = NULL;
KdumpSubHeader32 *kh = NULL;
size_t size;
int endian = s->dump_info.d_endian;
uint32_t block_size;
uint32_t sub_hdr_size;
uint32_t bitmap_blocks;
@@ -807,18 +759,17 @@ static int create_header32(DumpState *s)
dh = g_malloc0(size);
strncpy(dh->signature, KDUMP_SIGNATURE, strlen(KDUMP_SIGNATURE));
dh->header_version = cpu_convert_to_target32(6, endian);
block_size = s->page_size;
dh->block_size = cpu_convert_to_target32(block_size, endian);
dh->header_version = cpu_to_dump32(s, 6);
block_size = TARGET_PAGE_SIZE;
dh->block_size = cpu_to_dump32(s, block_size);
sub_hdr_size = sizeof(struct KdumpSubHeader32) + s->note_size;
sub_hdr_size = DIV_ROUND_UP(sub_hdr_size, block_size);
dh->sub_hdr_size = cpu_convert_to_target32(sub_hdr_size, endian);
dh->sub_hdr_size = cpu_to_dump32(s, sub_hdr_size);
/* dh->max_mapnr may be truncated, full 64bit is in kh.max_mapnr_64 */
dh->max_mapnr = cpu_convert_to_target32(MIN(s->max_mapnr, UINT_MAX),
endian);
dh->nr_cpus = cpu_convert_to_target32(s->nr_cpus, endian);
dh->max_mapnr = cpu_to_dump32(s, MIN(s->max_mapnr, UINT_MAX));
dh->nr_cpus = cpu_to_dump32(s, s->nr_cpus);
bitmap_blocks = DIV_ROUND_UP(s->len_dump_bitmap, block_size) * 2;
dh->bitmap_blocks = cpu_convert_to_target32(bitmap_blocks, endian);
dh->bitmap_blocks = cpu_to_dump32(s, bitmap_blocks);
strncpy(dh->utsname.machine, ELF_MACHINE_UNAME, sizeof(dh->utsname.machine));
if (s->flag_compress & DUMP_DH_COMPRESSED_ZLIB) {
@@ -834,7 +785,7 @@ static int create_header32(DumpState *s)
status |= DUMP_DH_COMPRESSED_SNAPPY;
}
#endif
dh->status = cpu_convert_to_target32(status, endian);
dh->status = cpu_to_dump32(s, status);
if (write_buffer(s->fd, 0, dh, size) < 0) {
dump_error(s, "dump: failed to write disk dump header.\n");
@@ -847,13 +798,13 @@ static int create_header32(DumpState *s)
kh = g_malloc0(size);
/* 64bit max_mapnr_64 */
kh->max_mapnr_64 = cpu_convert_to_target64(s->max_mapnr, endian);
kh->phys_base = cpu_convert_to_target32(PHYS_BASE, endian);
kh->dump_level = cpu_convert_to_target32(DUMP_LEVEL, endian);
kh->max_mapnr_64 = cpu_to_dump64(s, s->max_mapnr);
kh->phys_base = cpu_to_dump32(s, PHYS_BASE);
kh->dump_level = cpu_to_dump32(s, DUMP_LEVEL);
offset_note = DISKDUMP_HEADER_BLOCKS * block_size + size;
kh->offset_note = cpu_convert_to_target64(offset_note, endian);
kh->note_size = cpu_convert_to_target32(s->note_size, endian);
kh->offset_note = cpu_to_dump64(s, offset_note);
kh->note_size = cpu_to_dump32(s, s->note_size);
if (write_buffer(s->fd, DISKDUMP_HEADER_BLOCKS *
block_size, kh, size) < 0) {
@@ -902,7 +853,6 @@ static int create_header64(DumpState *s)
DiskDumpHeader64 *dh = NULL;
KdumpSubHeader64 *kh = NULL;
size_t size;
int endian = s->dump_info.d_endian;
uint32_t block_size;
uint32_t sub_hdr_size;
uint32_t bitmap_blocks;
@@ -914,18 +864,17 @@ static int create_header64(DumpState *s)
dh = g_malloc0(size);
strncpy(dh->signature, KDUMP_SIGNATURE, strlen(KDUMP_SIGNATURE));
dh->header_version = cpu_convert_to_target32(6, endian);
block_size = s->page_size;
dh->block_size = cpu_convert_to_target32(block_size, endian);
dh->header_version = cpu_to_dump32(s, 6);
block_size = TARGET_PAGE_SIZE;
dh->block_size = cpu_to_dump32(s, block_size);
sub_hdr_size = sizeof(struct KdumpSubHeader64) + s->note_size;
sub_hdr_size = DIV_ROUND_UP(sub_hdr_size, block_size);
dh->sub_hdr_size = cpu_convert_to_target32(sub_hdr_size, endian);
dh->sub_hdr_size = cpu_to_dump32(s, sub_hdr_size);
/* dh->max_mapnr may be truncated, full 64bit is in kh.max_mapnr_64 */
dh->max_mapnr = cpu_convert_to_target32(MIN(s->max_mapnr, UINT_MAX),
endian);
dh->nr_cpus = cpu_convert_to_target32(s->nr_cpus, endian);
dh->max_mapnr = cpu_to_dump32(s, MIN(s->max_mapnr, UINT_MAX));
dh->nr_cpus = cpu_to_dump32(s, s->nr_cpus);
bitmap_blocks = DIV_ROUND_UP(s->len_dump_bitmap, block_size) * 2;
dh->bitmap_blocks = cpu_convert_to_target32(bitmap_blocks, endian);
dh->bitmap_blocks = cpu_to_dump32(s, bitmap_blocks);
strncpy(dh->utsname.machine, ELF_MACHINE_UNAME, sizeof(dh->utsname.machine));
if (s->flag_compress & DUMP_DH_COMPRESSED_ZLIB) {
@@ -941,7 +890,7 @@ static int create_header64(DumpState *s)
status |= DUMP_DH_COMPRESSED_SNAPPY;
}
#endif
dh->status = cpu_convert_to_target32(status, endian);
dh->status = cpu_to_dump32(s, status);
if (write_buffer(s->fd, 0, dh, size) < 0) {
dump_error(s, "dump: failed to write disk dump header.\n");
@@ -954,13 +903,13 @@ static int create_header64(DumpState *s)
kh = g_malloc0(size);
/* 64bit max_mapnr_64 */
kh->max_mapnr_64 = cpu_convert_to_target64(s->max_mapnr, endian);
kh->phys_base = cpu_convert_to_target64(PHYS_BASE, endian);
kh->dump_level = cpu_convert_to_target32(DUMP_LEVEL, endian);
kh->max_mapnr_64 = cpu_to_dump64(s, s->max_mapnr);
kh->phys_base = cpu_to_dump64(s, PHYS_BASE);
kh->dump_level = cpu_to_dump32(s, DUMP_LEVEL);
offset_note = DISKDUMP_HEADER_BLOCKS * block_size + size;
kh->offset_note = cpu_convert_to_target64(offset_note, endian);
kh->note_size = cpu_convert_to_target64(s->note_size, endian);
kh->offset_note = cpu_to_dump64(s, offset_note);
kh->note_size = cpu_to_dump64(s, s->note_size);
if (write_buffer(s->fd, DISKDUMP_HEADER_BLOCKS *
block_size, kh, size) < 0) {
@@ -1004,7 +953,7 @@ out:
static int write_dump_header(DumpState *s)
{
if (s->dump_info.d_machine == EM_386) {
if (s->dump_info.d_class == ELFCLASS32) {
return create_header32(s);
} else {
return create_header64(s);
@@ -1086,9 +1035,9 @@ static bool get_next_page(GuestPhysBlock **blockptr, uint64_t *pfnptr,
if (!block) {
block = QTAILQ_FIRST(&s->guest_phys_blocks.head);
*blockptr = block;
assert(block->target_start % s->page_size == 0);
assert(block->target_end % s->page_size == 0);
*pfnptr = paddr_to_pfn(block->target_start, s->page_shift);
assert((block->target_start & ~TARGET_PAGE_MASK) == 0);
assert((block->target_end & ~TARGET_PAGE_MASK) == 0);
*pfnptr = paddr_to_pfn(block->target_start);
if (bufptr) {
*bufptr = block->host_addr;
}
@@ -1096,10 +1045,10 @@ static bool get_next_page(GuestPhysBlock **blockptr, uint64_t *pfnptr,
}
*pfnptr = *pfnptr + 1;
addr = pfn_to_paddr(*pfnptr, s->page_shift);
addr = pfn_to_paddr(*pfnptr);
if ((addr >= block->target_start) &&
(addr + s->page_size <= block->target_end)) {
(addr + TARGET_PAGE_SIZE <= block->target_end)) {
buf = block->host_addr + (addr - block->target_start);
} else {
/* the next page is in the next block */
@@ -1108,9 +1057,9 @@ static bool get_next_page(GuestPhysBlock **blockptr, uint64_t *pfnptr,
if (!block) {
return false;
}
assert(block->target_start % s->page_size == 0);
assert(block->target_end % s->page_size == 0);
*pfnptr = paddr_to_pfn(block->target_start, s->page_shift);
assert((block->target_start & ~TARGET_PAGE_MASK) == 0);
assert((block->target_end & ~TARGET_PAGE_MASK) == 0);
*pfnptr = paddr_to_pfn(block->target_start);
buf = block->host_addr;
}
@@ -1224,42 +1173,24 @@ static void free_data_cache(DataCache *data_cache)
static size_t get_len_buf_out(size_t page_size, uint32_t flag_compress)
{
size_t len_buf_out_zlib, len_buf_out_lzo, len_buf_out_snappy;
size_t len_buf_out;
switch (flag_compress) {
case DUMP_DH_COMPRESSED_ZLIB:
return compressBound(page_size);
/* init buf_out */
len_buf_out_zlib = len_buf_out_lzo = len_buf_out_snappy = 0;
/* buf size for zlib */
len_buf_out_zlib = compressBound(page_size);
/* buf size for lzo */
#ifdef CONFIG_LZO
if (flag_compress & DUMP_DH_COMPRESSED_LZO) {
if (lzo_init() != LZO_E_OK) {
/* return 0 to indicate lzo is unavailable */
return 0;
}
}
/*
* LZO will expand incompressible data by a little amount. please check the
* following URL to see the expansion calculation:
* http://www.oberhumer.com/opensource/lzo/lzofaq.php
*/
len_buf_out_lzo = page_size + page_size / 16 + 64 + 3;
#endif
case DUMP_DH_COMPRESSED_LZO:
/*
* LZO will expand incompressible data by a little amount. Please check
* the following URL to see the expansion calculation:
* http://www.oberhumer.com/opensource/lzo/lzofaq.php
*/
return page_size + page_size / 16 + 64 + 3;
#ifdef CONFIG_SNAPPY
/* buf size for snappy */
len_buf_out_snappy = snappy_max_compressed_length(page_size);
case DUMP_DH_COMPRESSED_SNAPPY:
return snappy_max_compressed_length(page_size);
#endif
/* get the biggest that can store all kinds of compressed page */
len_buf_out = MAX(len_buf_out_zlib,
MAX(len_buf_out_lzo, len_buf_out_snappy));
return len_buf_out;
}
return 0;
}
/*
@@ -1282,7 +1213,6 @@ static int write_dump_pages(DumpState *s)
off_t offset_desc, offset_data;
PageDescriptor pd, pd_zero;
uint8_t *buf;
int endian = s->dump_info.d_endian;
GuestPhysBlock *block_iter = NULL;
uint64_t pfn_iter;
@@ -1294,11 +1224,8 @@ static int write_dump_pages(DumpState *s)
prepare_data_cache(&page_data, s, offset_data);
/* prepare buffer to store compressed data */
len_buf_out = get_len_buf_out(s->page_size, s->flag_compress);
if (len_buf_out == 0) {
dump_error(s, "dump: failed to get length of output buffer.\n");
goto out;
}
len_buf_out = get_len_buf_out(TARGET_PAGE_SIZE, s->flag_compress);
assert(len_buf_out != 0);
#ifdef CONFIG_LZO
wrkmem = g_malloc(LZO1X_1_MEM_COMPRESS);
@@ -1310,19 +1237,19 @@ static int write_dump_pages(DumpState *s)
* init zero page's page_desc and page_data, because every zero page
* uses the same page_data
*/
pd_zero.size = cpu_convert_to_target32(s->page_size, endian);
pd_zero.flags = cpu_convert_to_target32(0, endian);
pd_zero.offset = cpu_convert_to_target64(offset_data, endian);
pd_zero.page_flags = cpu_convert_to_target64(0, endian);
buf = g_malloc0(s->page_size);
ret = write_cache(&page_data, buf, s->page_size, false);
pd_zero.size = cpu_to_dump32(s, TARGET_PAGE_SIZE);
pd_zero.flags = cpu_to_dump32(s, 0);
pd_zero.offset = cpu_to_dump64(s, offset_data);
pd_zero.page_flags = cpu_to_dump64(s, 0);
buf = g_malloc0(TARGET_PAGE_SIZE);
ret = write_cache(&page_data, buf, TARGET_PAGE_SIZE, false);
g_free(buf);
if (ret < 0) {
dump_error(s, "dump: failed to write page data(zero page).\n");
goto out;
}
offset_data += s->page_size;
offset_data += TARGET_PAGE_SIZE;
/*
* dump memory to vmcore page by page. zero page will all be resided in the
@@ -1330,7 +1257,7 @@ static int write_dump_pages(DumpState *s)
*/
while (get_next_page(&block_iter, &pfn_iter, &buf, s)) {
/* check zero page */
if (is_zero_page(buf, s->page_size)) {
if (is_zero_page(buf, TARGET_PAGE_SIZE)) {
ret = write_cache(&page_desc, &pd_zero, sizeof(PageDescriptor),
false);
if (ret < 0) {
@@ -1351,11 +1278,11 @@ static int write_dump_pages(DumpState *s)
*/
size_out = len_buf_out;
if ((s->flag_compress & DUMP_DH_COMPRESSED_ZLIB) &&
(compress2(buf_out, (uLongf *)&size_out, buf, s->page_size,
Z_BEST_SPEED) == Z_OK) && (size_out < s->page_size)) {
pd.flags = cpu_convert_to_target32(DUMP_DH_COMPRESSED_ZLIB,
endian);
pd.size = cpu_convert_to_target32(size_out, endian);
(compress2(buf_out, (uLongf *)&size_out, buf,
TARGET_PAGE_SIZE, Z_BEST_SPEED) == Z_OK) &&
(size_out < TARGET_PAGE_SIZE)) {
pd.flags = cpu_to_dump32(s, DUMP_DH_COMPRESSED_ZLIB);
pd.size = cpu_to_dump32(s, size_out);
ret = write_cache(&page_data, buf_out, size_out, false);
if (ret < 0) {
@@ -1364,12 +1291,11 @@ static int write_dump_pages(DumpState *s)
}
#ifdef CONFIG_LZO
} else if ((s->flag_compress & DUMP_DH_COMPRESSED_LZO) &&
(lzo1x_1_compress(buf, s->page_size, buf_out,
(lzo1x_1_compress(buf, TARGET_PAGE_SIZE, buf_out,
(lzo_uint *)&size_out, wrkmem) == LZO_E_OK) &&
(size_out < s->page_size)) {
pd.flags = cpu_convert_to_target32(DUMP_DH_COMPRESSED_LZO,
endian);
pd.size = cpu_convert_to_target32(size_out, endian);
(size_out < TARGET_PAGE_SIZE)) {
pd.flags = cpu_to_dump32(s, DUMP_DH_COMPRESSED_LZO);
pd.size = cpu_to_dump32(s, size_out);
ret = write_cache(&page_data, buf_out, size_out, false);
if (ret < 0) {
@@ -1379,12 +1305,11 @@ static int write_dump_pages(DumpState *s)
#endif
#ifdef CONFIG_SNAPPY
} else if ((s->flag_compress & DUMP_DH_COMPRESSED_SNAPPY) &&
(snappy_compress((char *)buf, s->page_size,
(snappy_compress((char *)buf, TARGET_PAGE_SIZE,
(char *)buf_out, &size_out) == SNAPPY_OK) &&
(size_out < s->page_size)) {
pd.flags = cpu_convert_to_target32(
DUMP_DH_COMPRESSED_SNAPPY, endian);
pd.size = cpu_convert_to_target32(size_out, endian);
(size_out < TARGET_PAGE_SIZE)) {
pd.flags = cpu_to_dump32(s, DUMP_DH_COMPRESSED_SNAPPY);
pd.size = cpu_to_dump32(s, size_out);
ret = write_cache(&page_data, buf_out, size_out, false);
if (ret < 0) {
@@ -1395,13 +1320,13 @@ static int write_dump_pages(DumpState *s)
} else {
/*
* fall back to save in plaintext, size_out should be
* assigned to s->page_size
* assigned TARGET_PAGE_SIZE
*/
pd.flags = cpu_convert_to_target32(0, endian);
size_out = s->page_size;
pd.size = cpu_convert_to_target32(size_out, endian);
pd.flags = cpu_to_dump32(s, 0);
size_out = TARGET_PAGE_SIZE;
pd.size = cpu_to_dump32(s, size_out);
ret = write_cache(&page_data, buf, s->page_size, false);
ret = write_cache(&page_data, buf, TARGET_PAGE_SIZE, false);
if (ret < 0) {
dump_error(s, "dump: failed to write page data.\n");
goto out;
@@ -1409,8 +1334,8 @@ static int write_dump_pages(DumpState *s)
}
/* get and write page desc here */
pd.page_flags = cpu_convert_to_target64(0, endian);
pd.offset = cpu_convert_to_target64(offset_data, endian);
pd.page_flags = cpu_to_dump64(s, 0);
pd.offset = cpu_to_dump64(s, offset_data);
offset_data += size_out;
ret = write_cache(&page_desc, &pd, sizeof(PageDescriptor), false);
@@ -1536,7 +1461,7 @@ static void get_max_mapnr(DumpState *s)
GuestPhysBlock *last_block;
last_block = QTAILQ_LAST(&s->guest_phys_blocks.head, GuestPhysBlockHead);
s->max_mapnr = paddr_to_pfn(last_block->target_end, s->page_shift);
s->max_mapnr = paddr_to_pfn(last_block->target_end);
}
static int dump_init(DumpState *s, int fd, bool has_format,
@@ -1613,14 +1538,12 @@ static int dump_init(DumpState *s, int fd, bool has_format,
}
s->nr_cpus = nr_cpus;
s->page_size = TARGET_PAGE_SIZE;
s->page_shift = ffs(s->page_size) - 1;
get_max_mapnr(s);
uint64_t tmp;
tmp = DIV_ROUND_UP(DIV_ROUND_UP(s->max_mapnr, CHAR_BIT), s->page_size);
s->len_dump_bitmap = tmp * s->page_size;
tmp = DIV_ROUND_UP(DIV_ROUND_UP(s->max_mapnr, CHAR_BIT), TARGET_PAGE_SIZE);
s->len_dump_bitmap = tmp * TARGET_PAGE_SIZE;
/* init for kdump-compressed format */
if (has_format && format != DUMP_GUEST_MEMORY_FORMAT_ELF) {
@@ -1630,6 +1553,12 @@ static int dump_init(DumpState *s, int fd, bool has_format,
break;
case DUMP_GUEST_MEMORY_FORMAT_KDUMP_LZO:
#ifdef CONFIG_LZO
if (lzo_init() != LZO_E_OK) {
error_setg(errp, "failed to initialize the LZO library");
goto cleanup;
}
#endif
s->flag_compress = DUMP_DH_COMPRESSED_LZO;
break;

40
exec.c
View File

@@ -1201,17 +1201,24 @@ static void qemu_ram_setup_dump(void *addr, ram_addr_t size)
}
}
void qemu_ram_set_idstr(ram_addr_t addr, const char *name, DeviceState *dev)
static RAMBlock *find_ram_block(ram_addr_t addr)
{
RAMBlock *new_block, *block;
RAMBlock *block;
new_block = NULL;
QTAILQ_FOREACH(block, &ram_list.blocks, next) {
if (block->offset == addr) {
new_block = block;
break;
return block;
}
}
return NULL;
}
void qemu_ram_set_idstr(ram_addr_t addr, const char *name, DeviceState *dev)
{
RAMBlock *new_block = find_ram_block(addr);
RAMBlock *block;
assert(new_block);
assert(!new_block->idstr[0]);
@@ -1236,6 +1243,15 @@ void qemu_ram_set_idstr(ram_addr_t addr, const char *name, DeviceState *dev)
qemu_mutex_unlock_ramlist();
}
void qemu_ram_unset_idstr(ram_addr_t addr)
{
RAMBlock *block = find_ram_block(addr);
if (block) {
memset(block->idstr, 0, sizeof(block->idstr));
}
}
static int memory_try_enable_merging(void *addr, size_t len)
{
if (!qemu_opt_get_bool(qemu_get_machine_opts(), "mem-merge", true)) {
@@ -1760,10 +1776,12 @@ static subpage_t *subpage_init(AddressSpace *as, hwaddr base)
return mmio;
}
static uint16_t dummy_section(PhysPageMap *map, MemoryRegion *mr)
static uint16_t dummy_section(PhysPageMap *map, AddressSpace *as,
MemoryRegion *mr)
{
assert(as);
MemoryRegionSection section = {
.address_space = &address_space_memory,
.address_space = as,
.mr = mr,
.offset_within_address_space = 0,
.offset_within_region = 0,
@@ -1795,13 +1813,13 @@ static void mem_begin(MemoryListener *listener)
AddressSpaceDispatch *d = g_new0(AddressSpaceDispatch, 1);
uint16_t n;
n = dummy_section(&d->map, &io_mem_unassigned);
n = dummy_section(&d->map, as, &io_mem_unassigned);
assert(n == PHYS_SECTION_UNASSIGNED);
n = dummy_section(&d->map, &io_mem_notdirty);
n = dummy_section(&d->map, as, &io_mem_notdirty);
assert(n == PHYS_SECTION_NOTDIRTY);
n = dummy_section(&d->map, &io_mem_rom);
n = dummy_section(&d->map, as, &io_mem_rom);
assert(n == PHYS_SECTION_ROM);
n = dummy_section(&d->map, &io_mem_watch);
n = dummy_section(&d->map, as, &io_mem_watch);
assert(n == PHYS_SECTION_WATCH);
d->phys_map = (PhysPageEntry) { .ptr = PHYS_MAP_NODE_NIL, .skip = 1 };

View File

@@ -335,6 +335,7 @@ ETEXI
.params = "tag|id",
.help = "restore a VM snapshot from its tag or id",
.mhandler.cmd = do_loadvm,
.command_completion = loadvm_completion,
},
STEXI
@@ -350,6 +351,7 @@ ETEXI
.params = "tag|id",
.help = "delete a VM snapshot from its tag or id",
.mhandler.cmd = do_delvm,
.command_completion = delvm_completion,
},
STEXI
@@ -852,6 +854,7 @@ ETEXI
.params = "device data",
.help = "Write to a ring buffer character device",
.mhandler.cmd = hmp_ringbuf_write,
.command_completion = ringbuf_write_completion,
},
STEXI
@@ -868,6 +871,7 @@ ETEXI
.params = "device size",
.help = "Read from a ring buffer character device",
.mhandler.cmd = hmp_ringbuf_read,
.command_completion = ringbuf_write_completion,
},
STEXI
@@ -973,6 +977,7 @@ ETEXI
.params = "capability state",
.help = "Enable/Disable the usage of a capability for migration",
.mhandler.cmd = hmp_migrate_set_capability,
.command_completion = migrate_set_capability_completion,
},
STEXI
@@ -1206,9 +1211,10 @@ ETEXI
{
.name = "host_net_add",
.args_type = "device:s,opts:s?",
.params = "tap|user|socket|vde|netmap|dump [options]",
.params = "tap|user|socket|vde|netmap|bridge|dump [options]",
.help = "add host VLAN client",
.mhandler.cmd = net_host_device_add,
.command_completion = host_net_add_completion,
},
STEXI
@@ -1223,6 +1229,7 @@ ETEXI
.params = "vlan_id name",
.help = "remove host VLAN client",
.mhandler.cmd = net_host_device_remove,
.command_completion = host_net_remove_completion,
},
STEXI
@@ -1357,6 +1364,7 @@ ETEXI
.params = "[reset|shutdown|poweroff|pause|debug|none]",
.help = "change watchdog action",
.mhandler.cmd = do_watchdog_action,
.command_completion = watchdog_action_completion,
},
STEXI

11
hmp.h
View File

@@ -103,5 +103,16 @@ void chardev_add_completion(ReadLineState *rs, int nb_args, const char *str);
void set_link_completion(ReadLineState *rs, int nb_args, const char *str);
void netdev_add_completion(ReadLineState *rs, int nb_args, const char *str);
void netdev_del_completion(ReadLineState *rs, int nb_args, const char *str);
void ringbuf_write_completion(ReadLineState *rs, int nb_args, const char *str);
void ringbuf_read_completion(ReadLineState *rs, int nb_args, const char *str);
void watchdog_action_completion(ReadLineState *rs, int nb_args,
const char *str);
void migrate_set_capability_completion(ReadLineState *rs, int nb_args,
const char *str);
void host_net_add_completion(ReadLineState *rs, int nb_args, const char *str);
void host_net_remove_completion(ReadLineState *rs, int nb_args,
const char *str);
void delvm_completion(ReadLineState *rs, int nb_args, const char *str);
void loadvm_completion(ReadLineState *rs, int nb_args, const char *str);
#endif

View File

@@ -34,7 +34,7 @@ static void virtio_9p_get_config(VirtIODevice *vdev, uint8_t *config)
len = strlen(s->tag);
cfg = g_malloc0(sizeof(struct virtio_9p_config) + len);
stw_raw(&cfg->tag_len, len);
stw_p(&cfg->tag_len, len);
/* We don't copy the terminating null to config space */
memcpy(cfg->tag, s->tag, len);
memcpy(config, cfg, s->config_size);

View File

@@ -143,7 +143,6 @@ const VMStateDescription vmstate_ich9_pm = {
.name = "ich9_pm",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.post_load = ich9_pm_post_load,
.fields = (VMStateField[]) {
VMSTATE_UINT16(acpi_regs.pm1.evt.sts, ICH9LPCPMRegs),

View File

@@ -324,8 +324,7 @@ const VMStateDescription vmstate_acpi_pcihp_pci_status = {
.name = "acpi_pcihp_pci_status",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField []) {
.fields = (VMStateField[]) {
VMSTATE_UINT32(up, AcpiPciHpPciStatus),
VMSTATE_UINT32(down, AcpiPciHpPciStatus),
VMSTATE_END_OF_LIST()

View File

@@ -177,8 +177,7 @@ static const VMStateDescription vmstate_gpe = {
.name = "gpe",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField []) {
.fields = (VMStateField[]) {
VMSTATE_GPE_ARRAY(sts, ACPIGPE),
VMSTATE_GPE_ARRAY(en, ACPIGPE),
VMSTATE_END_OF_LIST()
@@ -189,8 +188,7 @@ static const VMStateDescription vmstate_pci_status = {
.name = "pci_status",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField []) {
.fields = (VMStateField[]) {
VMSTATE_UINT32(up, struct AcpiPciHpPciStatus),
VMSTATE_UINT32(down, struct AcpiPciHpPciStatus),
VMSTATE_END_OF_LIST()
@@ -259,7 +257,7 @@ static const VMStateDescription vmstate_acpi = {
.minimum_version_id_old = 1,
.load_state_old = acpi_load_old,
.post_load = vmstate_acpi_post_load,
.fields = (VMStateField []) {
.fields = (VMStateField[]) {
VMSTATE_PCI_DEVICE(parent_obj, PIIX4PMState),
VMSTATE_UINT16(ar.pm1.evt.sts, PIIX4PMState),
VMSTATE_UINT16(ar.pm1.evt.en, PIIX4PMState),

View File

@@ -239,8 +239,9 @@ static void n800_key_event(void *opaque, int keycode)
int code = s->keymap[keycode & 0x7f];
if (code == -1) {
if ((keycode & 0x7f) == RETU_KEYCODE)
if ((keycode & 0x7f) == RETU_KEYCODE) {
retu_key_event(s->retu, !(keycode & 0x80));
}
return;
}
@@ -280,11 +281,14 @@ static void n800_tsc_kbd_setup(struct n800_s *s)
s->ts.opaque = s->ts.chip->opaque;
s->ts.txrx = tsc210x_txrx;
for (i = 0; i < 0x80; i ++)
for (i = 0; i < 0x80; i++) {
s->keymap[i] = -1;
for (i = 0; i < 0x10; i ++)
if (n800_keys[i] >= 0)
}
for (i = 0; i < 0x10; i++) {
if (n800_keys[i] >= 0) {
s->keymap[n800_keys[i]] = i;
}
}
qemu_add_kbd_event_handler(n800_key_event, s);
@@ -308,8 +312,9 @@ static void n810_key_event(void *opaque, int keycode)
int code = s->keymap[keycode & 0x7f];
if (code == -1) {
if ((keycode & 0x7f) == RETU_KEYCODE)
if ((keycode & 0x7f) == RETU_KEYCODE) {
retu_key_event(s->retu, !(keycode & 0x80));
}
return;
}
@@ -388,11 +393,14 @@ static void n810_kbd_setup(struct n800_s *s)
qemu_irq kbd_irq = qdev_get_gpio_in(s->mpu->gpio, N810_KEYBOARD_GPIO);
int i;
for (i = 0; i < 0x80; i ++)
for (i = 0; i < 0x80; i++) {
s->keymap[i] = -1;
for (i = 0; i < 0x80; i ++)
if (n810_keys[i] > 0)
}
for (i = 0; i < 0x80; i++) {
if (n810_keys[i] > 0) {
s->keymap[n810_keys[i]] = i;
}
}
qemu_add_kbd_event_handler(n810_key_event, s);
@@ -449,17 +457,20 @@ static uint32_t mipid_txrx(void *opaque, uint32_t cmd, int len)
struct mipid_s *s = (struct mipid_s *) opaque;
uint8_t ret;
if (len > 9)
if (len > 9) {
hw_error("%s: FIXME: bad SPI word width %i\n", __FUNCTION__, len);
}
if (s->p >= ARRAY_SIZE(s->resp))
if (s->p >= ARRAY_SIZE(s->resp)) {
ret = 0;
else
ret = s->resp[s->p ++];
if (s->pm --> 0)
} else {
ret = s->resp[s->p++];
}
if (s->pm-- > 0) {
s->param[s->pm] = cmd;
else
} else {
s->cmd = cmd;
}
switch (s->cmd) {
case 0x00: /* NOP */
@@ -560,15 +571,17 @@ static uint32_t mipid_txrx(void *opaque, uint32_t cmd, int len)
goto bad_cmd;
case 0x25: /* WRCNTR */
if (s->pm < 0)
if (s->pm < 0) {
s->pm = 1;
}
goto bad_cmd;
case 0x26: /* GAMSET */
if (!s->pm)
if (!s->pm) {
s->gamma = ffs(s->param[0] & 0xf) - 1;
else if (s->pm < 0)
} else if (s->pm < 0) {
s->pm = 1;
}
break;
case 0x28: /* DISPOFF */
@@ -591,10 +604,11 @@ static uint32_t mipid_txrx(void *opaque, uint32_t cmd, int len)
s->te = 0;
break;
case 0x35: /* TEON */
if (!s->pm)
if (!s->pm) {
s->te = 1;
else if (s->pm < 0)
} else if (s->pm < 0) {
s->pm = 1;
}
break;
case 0x36: /* MADCTR */
@@ -613,8 +627,9 @@ static uint32_t mipid_txrx(void *opaque, uint32_t cmd, int len)
case 0xb0: /* CLKINT / DISCTL */
case 0xb1: /* CLKEXT */
if (s->pm < 0)
if (s->pm < 0) {
s->pm = 2;
}
break;
case 0xb4: /* FRMSEL */
@@ -635,8 +650,9 @@ static uint32_t mipid_txrx(void *opaque, uint32_t cmd, int len)
break;
case 0xc2: /* IFMOD */
if (s->pm < 0)
if (s->pm < 0) {
s->pm = 2;
}
break;
case 0xc6: /* PWRCTL */
@@ -834,118 +850,119 @@ static void n800_setup_nolo_tags(void *sram_base)
strcpy((void *) (p + 8), "F5");
stl_raw(p + 10, 0x04f70000);
stl_p(p + 10, 0x04f70000);
strcpy((void *) (p + 9), "RX-34");
/* RAM size in MB? */
stl_raw(p + 12, 0x80);
stl_p(p + 12, 0x80);
/* Pointer to the list of tags */
stl_raw(p + 13, OMAP2_SRAM_BASE + 0x9000);
stl_p(p + 13, OMAP2_SRAM_BASE + 0x9000);
/* The NOLO tags start here */
p = sram_base + 0x9000;
#define ADD_TAG(tag, len) \
stw_raw((uint16_t *) p + 0, tag); \
stw_raw((uint16_t *) p + 1, len); p ++; \
stl_raw(p ++, OMAP2_SRAM_BASE | (((void *) v - sram_base) & 0xffff));
stw_p((uint16_t *) p + 0, tag); \
stw_p((uint16_t *) p + 1, len); p++; \
stl_p(p++, OMAP2_SRAM_BASE | (((void *) v - sram_base) & 0xffff));
/* OMAP STI console? Pin out settings? */
ADD_TAG(0x6e01, 414);
for (i = 0; i < ARRAY_SIZE(n800_pinout); i ++)
stl_raw(v ++, n800_pinout[i]);
for (i = 0; i < ARRAY_SIZE(n800_pinout); i++) {
stl_p(v++, n800_pinout[i]);
}
/* Kernel memsize? */
ADD_TAG(0x6e05, 1);
stl_raw(v ++, 2);
stl_p(v++, 2);
/* NOLO serial console */
ADD_TAG(0x6e02, 4);
stl_raw(v ++, XLDR_LL_UART); /* UART number (1 - 3) */
stl_p(v++, XLDR_LL_UART); /* UART number (1 - 3) */
#if 0
/* CBUS settings (Retu/AVilma) */
ADD_TAG(0x6e03, 6);
stw_raw((uint16_t *) v + 0, 65); /* CBUS GPIO0 */
stw_raw((uint16_t *) v + 1, 66); /* CBUS GPIO1 */
stw_raw((uint16_t *) v + 2, 64); /* CBUS GPIO2 */
stw_p((uint16_t *) v + 0, 65); /* CBUS GPIO0 */
stw_p((uint16_t *) v + 1, 66); /* CBUS GPIO1 */
stw_p((uint16_t *) v + 2, 64); /* CBUS GPIO2 */
v += 2;
#endif
/* Nokia ASIC BB5 (Retu/Tahvo) */
ADD_TAG(0x6e0a, 4);
stw_raw((uint16_t *) v + 0, 111); /* "Retu" interrupt GPIO */
stw_raw((uint16_t *) v + 1, 108); /* "Tahvo" interrupt GPIO */
v ++;
stw_p((uint16_t *) v + 0, 111); /* "Retu" interrupt GPIO */
stw_p((uint16_t *) v + 1, 108); /* "Tahvo" interrupt GPIO */
v++;
/* LCD console? */
ADD_TAG(0x6e04, 4);
stw_raw((uint16_t *) v + 0, 30); /* ??? */
stw_raw((uint16_t *) v + 1, 24); /* ??? */
v ++;
stw_p((uint16_t *) v + 0, 30); /* ??? */
stw_p((uint16_t *) v + 1, 24); /* ??? */
v++;
#if 0
/* LCD settings */
ADD_TAG(0x6e06, 2);
stw_raw((uint16_t *) (v ++), 15); /* ??? */
stw_p((uint16_t *) (v++), 15); /* ??? */
#endif
/* I^2C (Menelaus) */
ADD_TAG(0x6e07, 4);
stl_raw(v ++, 0x00720000); /* ??? */
stl_p(v++, 0x00720000); /* ??? */
/* Unknown */
ADD_TAG(0x6e0b, 6);
stw_raw((uint16_t *) v + 0, 94); /* ??? */
stw_raw((uint16_t *) v + 1, 23); /* ??? */
stw_raw((uint16_t *) v + 2, 0); /* ??? */
stw_p((uint16_t *) v + 0, 94); /* ??? */
stw_p((uint16_t *) v + 1, 23); /* ??? */
stw_p((uint16_t *) v + 2, 0); /* ??? */
v += 2;
/* OMAP gpio switch info */
ADD_TAG(0x6e0c, 80);
strcpy((void *) v, "bat_cover"); v += 3;
stw_raw((uint16_t *) v + 0, 110); /* GPIO num ??? */
stw_raw((uint16_t *) v + 1, 1); /* GPIO num ??? */
stw_p((uint16_t *) v + 0, 110); /* GPIO num ??? */
stw_p((uint16_t *) v + 1, 1); /* GPIO num ??? */
v += 2;
strcpy((void *) v, "cam_act"); v += 3;
stw_raw((uint16_t *) v + 0, 95); /* GPIO num ??? */
stw_raw((uint16_t *) v + 1, 32); /* GPIO num ??? */
stw_p((uint16_t *) v + 0, 95); /* GPIO num ??? */
stw_p((uint16_t *) v + 1, 32); /* GPIO num ??? */
v += 2;
strcpy((void *) v, "cam_turn"); v += 3;
stw_raw((uint16_t *) v + 0, 12); /* GPIO num ??? */
stw_raw((uint16_t *) v + 1, 33); /* GPIO num ??? */
stw_p((uint16_t *) v + 0, 12); /* GPIO num ??? */
stw_p((uint16_t *) v + 1, 33); /* GPIO num ??? */
v += 2;
strcpy((void *) v, "headphone"); v += 3;
stw_raw((uint16_t *) v + 0, 107); /* GPIO num ??? */
stw_raw((uint16_t *) v + 1, 17); /* GPIO num ??? */
stw_p((uint16_t *) v + 0, 107); /* GPIO num ??? */
stw_p((uint16_t *) v + 1, 17); /* GPIO num ??? */
v += 2;
/* Bluetooth */
ADD_TAG(0x6e0e, 12);
stl_raw(v ++, 0x5c623d01); /* ??? */
stl_raw(v ++, 0x00000201); /* ??? */
stl_raw(v ++, 0x00000000); /* ??? */
stl_p(v++, 0x5c623d01); /* ??? */
stl_p(v++, 0x00000201); /* ??? */
stl_p(v++, 0x00000000); /* ??? */
/* CX3110x WLAN settings */
ADD_TAG(0x6e0f, 8);
stl_raw(v ++, 0x00610025); /* ??? */
stl_raw(v ++, 0xffff0057); /* ??? */
stl_p(v++, 0x00610025); /* ??? */
stl_p(v++, 0xffff0057); /* ??? */
/* MMC host settings */
ADD_TAG(0x6e10, 12);
stl_raw(v ++, 0xffff000f); /* ??? */
stl_raw(v ++, 0xffffffff); /* ??? */
stl_raw(v ++, 0x00000060); /* ??? */
stl_p(v++, 0xffff000f); /* ??? */
stl_p(v++, 0xffffffff); /* ??? */
stl_p(v++, 0x00000060); /* ??? */
/* OneNAND chip select */
ADD_TAG(0x6e11, 10);
stl_raw(v ++, 0x00000401); /* ??? */
stl_raw(v ++, 0x0002003a); /* ??? */
stl_raw(v ++, 0x00000002); /* ??? */
stl_p(v++, 0x00000401); /* ??? */
stl_p(v++, 0x0002003a); /* ??? */
stl_p(v++, 0x00000002); /* ??? */
/* TEA5761 sensor settings */
ADD_TAG(0x6e12, 2);
stl_raw(v ++, 93); /* GPIO num ??? */
stl_p(v++, 93); /* GPIO num ??? */
#if 0
/* Unknown tag */
@@ -956,8 +973,8 @@ static void n800_setup_nolo_tags(void *sram_base)
#endif
/* End of the list */
stl_raw(p ++, 0x00000000);
stl_raw(p ++, 0x00000000);
stl_p(p++, 0x00000000);
stl_p(p++, 0x00000000);
}
/* This task is normally performed by the bootloader. If we're loading
@@ -1032,8 +1049,9 @@ static void n8x0_boot_init(void *opaque)
s->mpu->cpu->env.GE = 0x5;
/* If the machine has a slided keyboard, open it */
if (s->kbd)
if (s->kbd) {
qemu_irq_raise(qdev_get_gpio_in(s->mpu->gpio, N810_SLIDE_GPIO));
}
}
#define OMAP_TAG_NOKIA_BT 0x4e01
@@ -1119,112 +1137,112 @@ static int n8x0_atag_setup(void *p, int model)
w = p;
stw_raw(w ++, OMAP_TAG_UART); /* u16 tag */
stw_raw(w ++, 4); /* u16 len */
stw_raw(w ++, (1 << 2) | (1 << 1) | (1 << 0)); /* uint enabled_uarts */
w ++;
stw_p(w++, OMAP_TAG_UART); /* u16 tag */
stw_p(w++, 4); /* u16 len */
stw_p(w++, (1 << 2) | (1 << 1) | (1 << 0)); /* uint enabled_uarts */
w++;
#if 0
stw_raw(w ++, OMAP_TAG_SERIAL_CONSOLE); /* u16 tag */
stw_raw(w ++, 4); /* u16 len */
stw_raw(w ++, XLDR_LL_UART + 1); /* u8 console_uart */
stw_raw(w ++, 115200); /* u32 console_speed */
stw_p(w++, OMAP_TAG_SERIAL_CONSOLE); /* u16 tag */
stw_p(w++, 4); /* u16 len */
stw_p(w++, XLDR_LL_UART + 1); /* u8 console_uart */
stw_p(w++, 115200); /* u32 console_speed */
#endif
stw_raw(w ++, OMAP_TAG_LCD); /* u16 tag */
stw_raw(w ++, 36); /* u16 len */
stw_p(w++, OMAP_TAG_LCD); /* u16 tag */
stw_p(w++, 36); /* u16 len */
strcpy((void *) w, "QEMU LCD panel"); /* char panel_name[16] */
w += 8;
strcpy((void *) w, "blizzard"); /* char ctrl_name[16] */
w += 8;
stw_raw(w ++, N810_BLIZZARD_RESET_GPIO); /* TODO: n800 s16 nreset_gpio */
stw_raw(w ++, 24); /* u8 data_lines */
stw_p(w++, N810_BLIZZARD_RESET_GPIO); /* TODO: n800 s16 nreset_gpio */
stw_p(w++, 24); /* u8 data_lines */
stw_raw(w ++, OMAP_TAG_CBUS); /* u16 tag */
stw_raw(w ++, 8); /* u16 len */
stw_raw(w ++, N8X0_CBUS_CLK_GPIO); /* s16 clk_gpio */
stw_raw(w ++, N8X0_CBUS_DAT_GPIO); /* s16 dat_gpio */
stw_raw(w ++, N8X0_CBUS_SEL_GPIO); /* s16 sel_gpio */
w ++;
stw_p(w++, OMAP_TAG_CBUS); /* u16 tag */
stw_p(w++, 8); /* u16 len */
stw_p(w++, N8X0_CBUS_CLK_GPIO); /* s16 clk_gpio */
stw_p(w++, N8X0_CBUS_DAT_GPIO); /* s16 dat_gpio */
stw_p(w++, N8X0_CBUS_SEL_GPIO); /* s16 sel_gpio */
w++;
stw_raw(w ++, OMAP_TAG_EM_ASIC_BB5); /* u16 tag */
stw_raw(w ++, 4); /* u16 len */
stw_raw(w ++, N8X0_RETU_GPIO); /* s16 retu_irq_gpio */
stw_raw(w ++, N8X0_TAHVO_GPIO); /* s16 tahvo_irq_gpio */
stw_p(w++, OMAP_TAG_EM_ASIC_BB5); /* u16 tag */
stw_p(w++, 4); /* u16 len */
stw_p(w++, N8X0_RETU_GPIO); /* s16 retu_irq_gpio */
stw_p(w++, N8X0_TAHVO_GPIO); /* s16 tahvo_irq_gpio */
gpiosw = (model == 810) ? n810_gpiosw_info : n800_gpiosw_info;
for (; gpiosw->name; gpiosw ++) {
stw_raw(w ++, OMAP_TAG_GPIO_SWITCH); /* u16 tag */
stw_raw(w ++, 20); /* u16 len */
for (; gpiosw->name; gpiosw++) {
stw_p(w++, OMAP_TAG_GPIO_SWITCH); /* u16 tag */
stw_p(w++, 20); /* u16 len */
strcpy((void *) w, gpiosw->name); /* char name[12] */
w += 6;
stw_raw(w ++, gpiosw->line); /* u16 gpio */
stw_raw(w ++, gpiosw->type);
stw_raw(w ++, 0);
stw_raw(w ++, 0);
stw_p(w++, gpiosw->line); /* u16 gpio */
stw_p(w++, gpiosw->type);
stw_p(w++, 0);
stw_p(w++, 0);
}
stw_raw(w ++, OMAP_TAG_NOKIA_BT); /* u16 tag */
stw_raw(w ++, 12); /* u16 len */
stw_p(w++, OMAP_TAG_NOKIA_BT); /* u16 tag */
stw_p(w++, 12); /* u16 len */
b = (void *) w;
stb_raw(b ++, 0x01); /* u8 chip_type (CSR) */
stb_raw(b ++, N8X0_BT_WKUP_GPIO); /* u8 bt_wakeup_gpio */
stb_raw(b ++, N8X0_BT_HOST_WKUP_GPIO); /* u8 host_wakeup_gpio */
stb_raw(b ++, N8X0_BT_RESET_GPIO); /* u8 reset_gpio */
stb_raw(b ++, BT_UART + 1); /* u8 bt_uart */
stb_p(b++, 0x01); /* u8 chip_type (CSR) */
stb_p(b++, N8X0_BT_WKUP_GPIO); /* u8 bt_wakeup_gpio */
stb_p(b++, N8X0_BT_HOST_WKUP_GPIO); /* u8 host_wakeup_gpio */
stb_p(b++, N8X0_BT_RESET_GPIO); /* u8 reset_gpio */
stb_p(b++, BT_UART + 1); /* u8 bt_uart */
memcpy(b, &n8x0_bd_addr, 6); /* u8 bd_addr[6] */
b += 6;
stb_raw(b ++, 0x02); /* u8 bt_sysclk (38.4) */
stb_p(b++, 0x02); /* u8 bt_sysclk (38.4) */
w = (void *) b;
stw_raw(w ++, OMAP_TAG_WLAN_CX3110X); /* u16 tag */
stw_raw(w ++, 8); /* u16 len */
stw_raw(w ++, 0x25); /* u8 chip_type */
stw_raw(w ++, N8X0_WLAN_PWR_GPIO); /* s16 power_gpio */
stw_raw(w ++, N8X0_WLAN_IRQ_GPIO); /* s16 irq_gpio */
stw_raw(w ++, -1); /* s16 spi_cs_gpio */
stw_p(w++, OMAP_TAG_WLAN_CX3110X); /* u16 tag */
stw_p(w++, 8); /* u16 len */
stw_p(w++, 0x25); /* u8 chip_type */
stw_p(w++, N8X0_WLAN_PWR_GPIO); /* s16 power_gpio */
stw_p(w++, N8X0_WLAN_IRQ_GPIO); /* s16 irq_gpio */
stw_p(w++, -1); /* s16 spi_cs_gpio */
stw_raw(w ++, OMAP_TAG_MMC); /* u16 tag */
stw_raw(w ++, 16); /* u16 len */
stw_p(w++, OMAP_TAG_MMC); /* u16 tag */
stw_p(w++, 16); /* u16 len */
if (model == 810) {
stw_raw(w ++, 0x23f); /* unsigned flags */
stw_raw(w ++, -1); /* s16 power_pin */
stw_raw(w ++, -1); /* s16 switch_pin */
stw_raw(w ++, -1); /* s16 wp_pin */
stw_raw(w ++, 0x240); /* unsigned flags */
stw_raw(w ++, 0xc000); /* s16 power_pin */
stw_raw(w ++, 0x0248); /* s16 switch_pin */
stw_raw(w ++, 0xc000); /* s16 wp_pin */
stw_p(w++, 0x23f); /* unsigned flags */
stw_p(w++, -1); /* s16 power_pin */
stw_p(w++, -1); /* s16 switch_pin */
stw_p(w++, -1); /* s16 wp_pin */
stw_p(w++, 0x240); /* unsigned flags */
stw_p(w++, 0xc000); /* s16 power_pin */
stw_p(w++, 0x0248); /* s16 switch_pin */
stw_p(w++, 0xc000); /* s16 wp_pin */
} else {
stw_raw(w ++, 0xf); /* unsigned flags */
stw_raw(w ++, -1); /* s16 power_pin */
stw_raw(w ++, -1); /* s16 switch_pin */
stw_raw(w ++, -1); /* s16 wp_pin */
stw_raw(w ++, 0); /* unsigned flags */
stw_raw(w ++, 0); /* s16 power_pin */
stw_raw(w ++, 0); /* s16 switch_pin */
stw_raw(w ++, 0); /* s16 wp_pin */
stw_p(w++, 0xf); /* unsigned flags */
stw_p(w++, -1); /* s16 power_pin */
stw_p(w++, -1); /* s16 switch_pin */
stw_p(w++, -1); /* s16 wp_pin */
stw_p(w++, 0); /* unsigned flags */
stw_p(w++, 0); /* s16 power_pin */
stw_p(w++, 0); /* s16 switch_pin */
stw_p(w++, 0); /* s16 wp_pin */
}
stw_raw(w ++, OMAP_TAG_TEA5761); /* u16 tag */
stw_raw(w ++, 4); /* u16 len */
stw_raw(w ++, N8X0_TEA5761_CS_GPIO); /* u16 enable_gpio */
w ++;
stw_p(w++, OMAP_TAG_TEA5761); /* u16 tag */
stw_p(w++, 4); /* u16 len */
stw_p(w++, N8X0_TEA5761_CS_GPIO); /* u16 enable_gpio */
w++;
partition = (model == 810) ? n810_part_info : n800_part_info;
for (; partition->name; partition ++) {
stw_raw(w ++, OMAP_TAG_PARTITION); /* u16 tag */
stw_raw(w ++, 28); /* u16 len */
for (; partition->name; partition++) {
stw_p(w++, OMAP_TAG_PARTITION); /* u16 tag */
stw_p(w++, 28); /* u16 len */
strcpy((void *) w, partition->name); /* char name[16] */
l = (void *) (w + 8);
stl_raw(l ++, partition->size); /* unsigned int size */
stl_raw(l ++, partition->offset); /* unsigned int offset */
stl_raw(l ++, partition->mask); /* unsigned int mask_flags */
stl_p(l++, partition->size); /* unsigned int size */
stl_p(l++, partition->offset); /* unsigned int offset */
stl_p(l++, partition->mask); /* unsigned int mask_flags */
w = (void *) l;
}
stw_raw(w ++, OMAP_TAG_BOOT_REASON); /* u16 tag */
stw_raw(w ++, 12); /* u16 len */
stw_p(w++, OMAP_TAG_BOOT_REASON); /* u16 tag */
stw_p(w++, 12); /* u16 len */
#if 0
strcpy((void *) w, "por"); /* char reason_str[12] */
strcpy((void *) w, "charger"); /* char reason_str[12] */
@@ -1242,15 +1260,15 @@ static int n8x0_atag_setup(void *p, int model)
w += 6;
tag = (model == 810) ? "RX-44" : "RX-34";
stw_raw(w ++, OMAP_TAG_VERSION_STR); /* u16 tag */
stw_raw(w ++, 24); /* u16 len */
stw_p(w++, OMAP_TAG_VERSION_STR); /* u16 tag */
stw_p(w++, 24); /* u16 len */
strcpy((void *) w, "product"); /* char component[12] */
w += 6;
strcpy((void *) w, tag); /* char version[12] */
w += 6;
stw_raw(w ++, OMAP_TAG_VERSION_STR); /* u16 tag */
stw_raw(w ++, 24); /* u16 len */
stw_p(w++, OMAP_TAG_VERSION_STR); /* u16 tag */
stw_p(w++, 24); /* u16 len */
strcpy((void *) w, "hw-build"); /* char component[12] */
w += 6;
strcpy((void *) w, "QEMU ");
@@ -1258,8 +1276,8 @@ static int n8x0_atag_setup(void *p, int model)
w += 6;
tag = (model == 810) ? "1.1.10-qemu" : "1.1.6-qemu";
stw_raw(w ++, OMAP_TAG_VERSION_STR); /* u16 tag */
stw_raw(w ++, 24); /* u16 len */
stw_p(w++, OMAP_TAG_VERSION_STR); /* u16 tag */
stw_p(w++, 24); /* u16 len */
strcpy((void *) w, "nolo"); /* char component[12] */
w += 6;
strcpy((void *) w, tag); /* char version[12] */
@@ -1315,9 +1333,9 @@ static void n8x0_init(MachineState *machine,
n8x0_gpio_setup(s);
n8x0_nand_setup(s);
n8x0_i2c_setup(s);
if (model == 800)
if (model == 800) {
n800_tsc_kbd_setup(s);
else if (model == 810) {
} else if (model == 810) {
n810_tsc_setup(s);
n810_kbd_setup(s);
}

View File

@@ -28,6 +28,7 @@
#include "net/net.h"
#include "sysemu/sysemu.h"
#include "hw/boards.h"
#include "hw/loader.h"
#include "exec/address-spaces.h"
#include "sysemu/blockdev.h"
#include "hw/block/flash.h"
@@ -528,6 +529,18 @@ static void vexpress_common_init(VEDBoardInfo *daughterboard,
daughterboard->init(daughterboard, machine->ram_size, machine->cpu_model,
pic);
/*
* If a bios file was provided, attempt to map it into memory
*/
if (bios_name) {
const char *fn = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
if (!fn || load_image_targphys(fn, map[VE_NORFLASH0],
VEXPRESS_FLASH_SIZE) < 0) {
error_report("Could not load ROM image '%s'", bios_name);
exit(1);
}
}
/* Motherboard peripherals: the wiring is the same but the
* addresses vary between the legacy and A-Series memory maps.
*/

View File

@@ -1163,8 +1163,7 @@ static const VMStateDescription vmstate_ac97_bm_regs = {
.name = "ac97_bm_regs",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField []) {
.fields = (VMStateField[]) {
VMSTATE_UINT32 (bdbar, AC97BusMasterRegs),
VMSTATE_UINT8 (civ, AC97BusMasterRegs),
VMSTATE_UINT8 (lvi, AC97BusMasterRegs),
@@ -1211,9 +1210,8 @@ static const VMStateDescription vmstate_ac97 = {
.name = "ac97",
.version_id = 3,
.minimum_version_id = 2,
.minimum_version_id_old = 2,
.post_load = ac97_post_load,
.fields = (VMStateField []) {
.fields = (VMStateField[]) {
VMSTATE_PCI_DEVICE (dev, AC97LinkState),
VMSTATE_UINT32 (glob_cnt, AC97LinkState),
VMSTATE_UINT32 (glob_sta, AC97LinkState),

View File

@@ -275,9 +275,7 @@ static void Adlib_fini (AdlibState *s)
}
#endif
if (s->mixbuf) {
g_free (s->mixbuf);
}
g_free(s->mixbuf);
s->active = 0;
s->enabled = 0;

View File

@@ -137,8 +137,7 @@ static const VMStateDescription vmstate_cs4231 = {
.name ="cs4231",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField []) {
.fields = (VMStateField[]) {
VMSTATE_UINT32_ARRAY(regs, CSState, CS_REGS),
VMSTATE_UINT8_ARRAY(dregs, CSState, CS_DREGS),
VMSTATE_END_OF_LIST()

View File

@@ -621,10 +621,9 @@ static const VMStateDescription vmstate_cs4231a = {
.name = "cs4231a",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.pre_load = cs4231a_pre_load,
.post_load = cs4231a_post_load,
.fields = (VMStateField []) {
.fields = (VMStateField[]) {
VMSTATE_UINT32_ARRAY (regs, CSState, CS_REGS),
VMSTATE_BUFFER (dregs, CSState),
VMSTATE_INT32 (dma_running, CSState),

View File

@@ -953,8 +953,7 @@ static const VMStateDescription vmstate_es1370_channel = {
.name = "es1370_channel",
.version_id = 2,
.minimum_version_id = 2,
.minimum_version_id_old = 2,
.fields = (VMStateField []) {
.fields = (VMStateField[]) {
VMSTATE_UINT32 (shift, struct chan),
VMSTATE_UINT32 (leftover, struct chan),
VMSTATE_UINT32 (scount, struct chan),
@@ -997,9 +996,8 @@ static const VMStateDescription vmstate_es1370 = {
.name = "es1370",
.version_id = 2,
.minimum_version_id = 2,
.minimum_version_id_old = 2,
.post_load = es1370_post_load,
.fields = (VMStateField []) {
.fields = (VMStateField[]) {
VMSTATE_PCI_DEVICE (dev, ES1370State),
VMSTATE_STRUCT_ARRAY (chan, ES1370State, NB_CHANNELS, 2,
vmstate_es1370_channel, struct chan),

View File

@@ -222,8 +222,7 @@ static const VMStateDescription vmstate_gus = {
.name = "gus",
.version_id = 2,
.minimum_version_id = 2,
.minimum_version_id_old = 2,
.fields = (VMStateField []) {
.fields = (VMStateField[]) {
VMSTATE_INT32 (pos, GUSState),
VMSTATE_INT32 (left, GUSState),
VMSTATE_INT32 (shift, GUSState),

View File

@@ -583,7 +583,7 @@ static void hda_audio_reset(DeviceState *dev)
static const VMStateDescription vmstate_hda_audio_stream = {
.name = "hda-audio-stream",
.version_id = 1,
.fields = (VMStateField []) {
.fields = (VMStateField[]) {
VMSTATE_UINT32(stream, HDAAudioStream),
VMSTATE_UINT32(channel, HDAAudioStream),
VMSTATE_UINT32(format, HDAAudioStream),
@@ -601,7 +601,7 @@ static const VMStateDescription vmstate_hda_audio = {
.name = "hda-audio",
.version_id = 2,
.post_load = hda_audio_post_load,
.fields = (VMStateField []) {
.fields = (VMStateField[]) {
VMSTATE_STRUCT_ARRAY(st, HDAAudioState, 4, 0,
vmstate_hda_audio_stream,
HDAAudioStream),

View File

@@ -1176,7 +1176,7 @@ static int intel_hda_post_load(void *opaque, int version)
static const VMStateDescription vmstate_intel_hda_stream = {
.name = "intel-hda-stream",
.version_id = 1,
.fields = (VMStateField []) {
.fields = (VMStateField[]) {
VMSTATE_UINT32(ctl, IntelHDAStream),
VMSTATE_UINT32(lpib, IntelHDAStream),
VMSTATE_UINT32(cbl, IntelHDAStream),
@@ -1192,7 +1192,7 @@ static const VMStateDescription vmstate_intel_hda = {
.name = "intel-hda",
.version_id = 1,
.post_load = intel_hda_post_load,
.fields = (VMStateField []) {
.fields = (VMStateField[]) {
VMSTATE_PCI_DEVICE(pci, IntelHDAState),
/* registers */

View File

@@ -1289,9 +1289,8 @@ static const VMStateDescription vmstate_sb16 = {
.name = "sb16",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.post_load = sb16_post_load,
.fields = (VMStateField []) {
.fields = (VMStateField[]) {
VMSTATE_UINT32 (irq, SB16State),
VMSTATE_UINT32 (dma, SB16State),
VMSTATE_UINT32 (hdma, SB16State),

View File

@@ -1 +1 @@
obj-y += ioq.o virtio-blk.o
obj-y += virtio-blk.o

View File

@@ -1,117 +0,0 @@
/*
* Linux AIO request queue
*
* Copyright 2012 IBM, Corp.
* Copyright 2012 Red Hat, Inc. and/or its affiliates
*
* Authors:
* Stefan Hajnoczi <stefanha@redhat.com>
*
* 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 "ioq.h"
void ioq_init(IOQueue *ioq, int fd, unsigned int max_reqs)
{
int rc;
ioq->fd = fd;
ioq->max_reqs = max_reqs;
memset(&ioq->io_ctx, 0, sizeof ioq->io_ctx);
rc = io_setup(max_reqs, &ioq->io_ctx);
if (rc != 0) {
fprintf(stderr, "ioq io_setup failed %d\n", rc);
exit(1);
}
rc = event_notifier_init(&ioq->io_notifier, 0);
if (rc != 0) {
fprintf(stderr, "ioq io event notifier creation failed %d\n", rc);
exit(1);
}
ioq->freelist = g_malloc0(sizeof ioq->freelist[0] * max_reqs);
ioq->freelist_idx = 0;
ioq->queue = g_malloc0(sizeof ioq->queue[0] * max_reqs);
ioq->queue_idx = 0;
}
void ioq_cleanup(IOQueue *ioq)
{
g_free(ioq->freelist);
g_free(ioq->queue);
event_notifier_cleanup(&ioq->io_notifier);
io_destroy(ioq->io_ctx);
}
EventNotifier *ioq_get_notifier(IOQueue *ioq)
{
return &ioq->io_notifier;
}
struct iocb *ioq_get_iocb(IOQueue *ioq)
{
/* Underflow cannot happen since ioq is sized for max_reqs */
assert(ioq->freelist_idx != 0);
struct iocb *iocb = ioq->freelist[--ioq->freelist_idx];
ioq->queue[ioq->queue_idx++] = iocb;
return iocb;
}
void ioq_put_iocb(IOQueue *ioq, struct iocb *iocb)
{
/* Overflow cannot happen since ioq is sized for max_reqs */
assert(ioq->freelist_idx != ioq->max_reqs);
ioq->freelist[ioq->freelist_idx++] = iocb;
}
struct iocb *ioq_rdwr(IOQueue *ioq, bool read, struct iovec *iov,
unsigned int count, long long offset)
{
struct iocb *iocb = ioq_get_iocb(ioq);
if (read) {
io_prep_preadv(iocb, ioq->fd, iov, count, offset);
} else {
io_prep_pwritev(iocb, ioq->fd, iov, count, offset);
}
io_set_eventfd(iocb, event_notifier_get_fd(&ioq->io_notifier));
return iocb;
}
int ioq_submit(IOQueue *ioq)
{
int rc = io_submit(ioq->io_ctx, ioq->queue_idx, ioq->queue);
ioq->queue_idx = 0; /* reset */
return rc;
}
int ioq_run_completion(IOQueue *ioq, IOQueueCompletion *completion,
void *opaque)
{
struct io_event events[ioq->max_reqs];
int nevents, i;
do {
nevents = io_getevents(ioq->io_ctx, 0, ioq->max_reqs, events, NULL);
} while (nevents < 0 && errno == EINTR);
if (nevents < 0) {
return nevents;
}
for (i = 0; i < nevents; i++) {
ssize_t ret = ((uint64_t)events[i].res2 << 32) | events[i].res;
completion(events[i].obj, ret, opaque);
ioq_put_iocb(ioq, events[i].obj);
}
return nevents;
}

View File

@@ -1,57 +0,0 @@
/*
* Linux AIO request queue
*
* Copyright 2012 IBM, Corp.
* Copyright 2012 Red Hat, Inc. and/or its affiliates
*
* Authors:
* Stefan Hajnoczi <stefanha@redhat.com>
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*
*/
#ifndef IOQ_H
#define IOQ_H
#include <libaio.h>
#include "qemu/event_notifier.h"
typedef struct {
int fd; /* file descriptor */
unsigned int max_reqs; /* max length of freelist and queue */
io_context_t io_ctx; /* Linux AIO context */
EventNotifier io_notifier; /* Linux AIO eventfd */
/* Requests can complete in any order so a free list is necessary to manage
* available iocbs.
*/
struct iocb **freelist; /* free iocbs */
unsigned int freelist_idx;
/* Multiple requests are queued up before submitting them all in one go */
struct iocb **queue; /* queued iocbs */
unsigned int queue_idx;
} IOQueue;
void ioq_init(IOQueue *ioq, int fd, unsigned int max_reqs);
void ioq_cleanup(IOQueue *ioq);
EventNotifier *ioq_get_notifier(IOQueue *ioq);
struct iocb *ioq_get_iocb(IOQueue *ioq);
void ioq_put_iocb(IOQueue *ioq, struct iocb *iocb);
struct iocb *ioq_rdwr(IOQueue *ioq, bool read, struct iovec *iov,
unsigned int count, long long offset);
int ioq_submit(IOQueue *ioq);
static inline unsigned int ioq_num_queued(IOQueue *ioq)
{
return ioq->queue_idx;
}
typedef void IOQueueCompletion(struct iocb *iocb, ssize_t ret, void *opaque);
int ioq_run_completion(IOQueue *ioq, IOQueueCompletion *completion,
void *opaque);
#endif /* IOQ_H */

View File

@@ -17,7 +17,6 @@
#include "qemu/thread.h"
#include "qemu/error-report.h"
#include "hw/virtio/dataplane/vring.h"
#include "ioq.h"
#include "block/block.h"
#include "hw/virtio/virtio-blk.h"
#include "virtio-blk.h"
@@ -25,20 +24,14 @@
#include "hw/virtio/virtio-bus.h"
#include "qom/object_interfaces.h"
enum {
SEG_MAX = 126, /* maximum number of I/O segments */
VRING_MAX = SEG_MAX + 2, /* maximum number of vring descriptors */
REQ_MAX = VRING_MAX, /* maximum number of requests in the vring,
* is VRING_MAX / 2 with traditional and
* VRING_MAX with indirect descriptors */
};
typedef struct {
struct iocb iocb; /* Linux AIO control block */
VirtIOBlockDataPlane *s;
QEMUIOVector *inhdr; /* iovecs for virtio_blk_inhdr */
VirtQueueElement *elem; /* saved data from the virtqueue */
struct iovec *bounce_iov; /* used if guest buffers are unaligned */
QEMUIOVector *read_qiov; /* for read completion /w bounce buffer */
QEMUIOVector qiov; /* original request iovecs */
struct iovec bounce_iov; /* used if guest buffers are unaligned */
QEMUIOVector bounce_qiov; /* bounce buffer iovecs */
bool read; /* read or write? */
} VirtIOBlockRequest;
struct VirtIOBlockDataPlane {
@@ -47,7 +40,6 @@ struct VirtIOBlockDataPlane {
bool stopping;
VirtIOBlkConf *blk;
int fd; /* image file descriptor */
VirtIODevice *vdev;
Vring vring; /* virtqueue vring */
@@ -61,16 +53,8 @@ struct VirtIOBlockDataPlane {
IOThread *iothread;
IOThread internal_iothread_obj;
AioContext *ctx;
EventNotifier io_notifier; /* Linux AIO completion */
EventNotifier host_notifier; /* doorbell */
IOQueue ioqueue; /* Linux AIO queue (should really be per
IOThread) */
VirtIOBlockRequest requests[REQ_MAX]; /* pool of requests, managed by the
queue */
unsigned int num_reqs;
/* Operation blocker on BDS */
Error *blocker;
};
@@ -85,33 +69,28 @@ static void notify_guest(VirtIOBlockDataPlane *s)
event_notifier_set(s->guest_notifier);
}
static void complete_request(struct iocb *iocb, ssize_t ret, void *opaque)
static void complete_rdwr(void *opaque, int ret)
{
VirtIOBlockDataPlane *s = opaque;
VirtIOBlockRequest *req = container_of(iocb, VirtIOBlockRequest, iocb);
VirtIOBlockRequest *req = opaque;
struct virtio_blk_inhdr hdr;
int len;
if (likely(ret >= 0)) {
if (likely(ret == 0)) {
hdr.status = VIRTIO_BLK_S_OK;
len = ret;
len = req->qiov.size;
} else {
hdr.status = VIRTIO_BLK_S_IOERR;
len = 0;
}
trace_virtio_blk_data_plane_complete_request(s, req->elem->index, ret);
trace_virtio_blk_data_plane_complete_request(req->s, req->elem->index, ret);
if (req->read_qiov) {
assert(req->bounce_iov);
qemu_iovec_from_buf(req->read_qiov, 0, req->bounce_iov->iov_base, len);
qemu_iovec_destroy(req->read_qiov);
g_slice_free(QEMUIOVector, req->read_qiov);
if (req->read && req->bounce_iov.iov_base) {
qemu_iovec_from_buf(&req->qiov, 0, req->bounce_iov.iov_base, len);
}
if (req->bounce_iov) {
qemu_vfree(req->bounce_iov->iov_base);
g_slice_free(struct iovec, req->bounce_iov);
if (req->bounce_iov.iov_base) {
qemu_vfree(req->bounce_iov.iov_base);
}
qemu_iovec_from_buf(req->inhdr, 0, &hdr, sizeof(hdr));
@@ -122,9 +101,9 @@ static void complete_request(struct iocb *iocb, ssize_t ret, void *opaque)
* written to, but for virtio-blk it seems to be the number of bytes
* transferred plus the status bytes.
*/
vring_push(&s->vring, req->elem, len + sizeof(hdr));
req->elem = NULL;
s->num_reqs--;
vring_push(&req->s->vring, req->elem, len + sizeof(hdr));
notify_guest(req->s);
g_slice_free(VirtIOBlockRequest, req);
}
static void complete_request_early(VirtIOBlockDataPlane *s, VirtQueueElement *elem,
@@ -155,51 +134,87 @@ static void do_get_id_cmd(VirtIOBlockDataPlane *s,
complete_request_early(s, elem, inhdr, VIRTIO_BLK_S_OK);
}
static int do_rdwr_cmd(VirtIOBlockDataPlane *s, bool read,
struct iovec *iov, unsigned iov_cnt,
long long offset, VirtQueueElement *elem,
QEMUIOVector *inhdr)
static void do_rdwr_cmd(VirtIOBlockDataPlane *s, bool read,
struct iovec *iov, unsigned iov_cnt,
int64_t sector_num, VirtQueueElement *elem,
QEMUIOVector *inhdr)
{
struct iocb *iocb;
QEMUIOVector qiov;
struct iovec *bounce_iov = NULL;
QEMUIOVector *read_qiov = NULL;
VirtIOBlockRequest *req = g_slice_new0(VirtIOBlockRequest);
QEMUIOVector *qiov;
int nb_sectors;
qemu_iovec_init_external(&qiov, iov, iov_cnt);
if (!bdrv_qiov_is_aligned(s->blk->conf.bs, &qiov)) {
void *bounce_buffer = qemu_blockalign(s->blk->conf.bs, qiov.size);
/* Fill in virtio block metadata needed for completion */
req->s = s;
req->elem = elem;
req->inhdr = inhdr;
req->read = read;
qemu_iovec_init_external(&req->qiov, iov, iov_cnt);
if (read) {
/* Need to copy back from bounce buffer on completion */
read_qiov = g_slice_new(QEMUIOVector);
qemu_iovec_init(read_qiov, iov_cnt);
qemu_iovec_concat_iov(read_qiov, iov, iov_cnt, 0, qiov.size);
} else {
qemu_iovec_to_buf(&qiov, 0, bounce_buffer, qiov.size);
qiov = &req->qiov;
if (!bdrv_qiov_is_aligned(s->blk->conf.bs, qiov)) {
void *bounce_buffer = qemu_blockalign(s->blk->conf.bs, qiov->size);
/* Populate bounce buffer with data for writes */
if (!read) {
qemu_iovec_to_buf(qiov, 0, bounce_buffer, qiov->size);
}
/* Redirect I/O to aligned bounce buffer */
bounce_iov = g_slice_new(struct iovec);
bounce_iov->iov_base = bounce_buffer;
bounce_iov->iov_len = qiov.size;
iov = bounce_iov;
iov_cnt = 1;
req->bounce_iov.iov_base = bounce_buffer;
req->bounce_iov.iov_len = qiov->size;
qemu_iovec_init_external(&req->bounce_qiov, &req->bounce_iov, 1);
qiov = &req->bounce_qiov;
}
iocb = ioq_rdwr(&s->ioqueue, read, iov, iov_cnt, offset);
nb_sectors = qiov->size / BDRV_SECTOR_SIZE;
/* Fill in virtio block metadata needed for completion */
VirtIOBlockRequest *req = container_of(iocb, VirtIOBlockRequest, iocb);
req->elem = elem;
req->inhdr = inhdr;
req->bounce_iov = bounce_iov;
req->read_qiov = read_qiov;
return 0;
if (read) {
bdrv_aio_readv(s->blk->conf.bs, sector_num, qiov, nb_sectors,
complete_rdwr, req);
} else {
bdrv_aio_writev(s->blk->conf.bs, sector_num, qiov, nb_sectors,
complete_rdwr, req);
}
}
static int process_request(IOQueue *ioq, VirtQueueElement *elem)
static void complete_flush(void *opaque, int ret)
{
VirtIOBlockRequest *req = opaque;
unsigned char status;
if (ret == 0) {
status = VIRTIO_BLK_S_OK;
} else {
status = VIRTIO_BLK_S_IOERR;
}
complete_request_early(req->s, req->elem, req->inhdr, status);
g_slice_free(VirtIOBlockRequest, req);
}
static void do_flush_cmd(VirtIOBlockDataPlane *s, VirtQueueElement *elem,
QEMUIOVector *inhdr)
{
VirtIOBlockRequest *req = g_slice_new(VirtIOBlockRequest);
req->s = s;
req->elem = elem;
req->inhdr = inhdr;
bdrv_aio_flush(s->blk->conf.bs, complete_flush, req);
}
static void do_scsi_cmd(VirtIOBlockDataPlane *s, VirtQueueElement *elem,
QEMUIOVector *inhdr)
{
int status;
status = virtio_blk_handle_scsi_req(VIRTIO_BLK(s->vdev), elem);
complete_request_early(s, elem, inhdr, status);
}
static int process_request(VirtIOBlockDataPlane *s, VirtQueueElement *elem)
{
VirtIOBlockDataPlane *s = container_of(ioq, VirtIOBlockDataPlane, ioqueue);
struct iovec *iov = elem->out_sg;
struct iovec *in_iov = elem->in_sg;
unsigned out_num = elem->out_num;
@@ -234,25 +249,23 @@ static int process_request(IOQueue *ioq, VirtQueueElement *elem)
switch (outhdr.type) {
case VIRTIO_BLK_T_IN:
do_rdwr_cmd(s, true, in_iov, in_num, outhdr.sector * 512, elem, inhdr);
do_rdwr_cmd(s, true, in_iov, in_num,
outhdr.sector * 512 / BDRV_SECTOR_SIZE,
elem, inhdr);
return 0;
case VIRTIO_BLK_T_OUT:
do_rdwr_cmd(s, false, iov, out_num, outhdr.sector * 512, elem, inhdr);
do_rdwr_cmd(s, false, iov, out_num,
outhdr.sector * 512 / BDRV_SECTOR_SIZE,
elem, inhdr);
return 0;
case VIRTIO_BLK_T_SCSI_CMD:
/* TODO support SCSI commands */
complete_request_early(s, elem, inhdr, VIRTIO_BLK_S_UNSUPP);
do_scsi_cmd(s, elem, inhdr);
return 0;
case VIRTIO_BLK_T_FLUSH:
/* TODO fdsync not supported by Linux AIO, do it synchronously here! */
if (qemu_fdatasync(s->fd) < 0) {
complete_request_early(s, elem, inhdr, VIRTIO_BLK_S_IOERR);
} else {
complete_request_early(s, elem, inhdr, VIRTIO_BLK_S_OK);
}
do_flush_cmd(s, elem, inhdr);
return 0;
case VIRTIO_BLK_T_GET_ID:
@@ -274,7 +287,6 @@ static void handle_notify(EventNotifier *e)
VirtQueueElement *elem;
int ret;
unsigned int num_queued;
event_notifier_test_and_clear(&s->host_notifier);
for (;;) {
@@ -291,7 +303,7 @@ static void handle_notify(EventNotifier *e)
trace_virtio_blk_data_plane_process_request(s, elem->out_num,
elem->in_num, elem->index);
if (process_request(&s->ioqueue, elem) < 0) {
if (process_request(s, elem) < 0) {
vring_set_broken(&s->vring);
vring_free_element(elem);
ret = -EFAULT;
@@ -306,44 +318,10 @@ static void handle_notify(EventNotifier *e)
if (vring_enable_notification(s->vdev, &s->vring)) {
break;
}
} else { /* ret == -ENOBUFS or fatal error, iovecs[] is depleted */
/* Since there are no iovecs[] left, stop processing for now. Do
* not re-enable guest->host notifies since the I/O completion
* handler knows to check for more vring descriptors anyway.
*/
} else { /* fatal error */
break;
}
}
num_queued = ioq_num_queued(&s->ioqueue);
if (num_queued > 0) {
s->num_reqs += num_queued;
int rc = ioq_submit(&s->ioqueue);
if (unlikely(rc < 0)) {
fprintf(stderr, "ioq_submit failed %d\n", rc);
exit(1);
}
}
}
static void handle_io(EventNotifier *e)
{
VirtIOBlockDataPlane *s = container_of(e, VirtIOBlockDataPlane,
io_notifier);
event_notifier_test_and_clear(&s->io_notifier);
if (ioq_run_completion(&s->ioqueue, complete_request, s) > 0) {
notify_guest(s);
}
/* If there were more requests than iovecs, the vring will not be empty yet
* so check again. There should now be enough resources to process more
* requests.
*/
if (unlikely(vring_more_avail(&s->vring))) {
handle_notify(&s->host_notifier);
}
}
/* Context: QEMU global mutex held */
@@ -352,7 +330,6 @@ void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *blk,
Error **errp)
{
VirtIOBlockDataPlane *s;
int fd;
Error *local_err = NULL;
*dataplane = NULL;
@@ -361,18 +338,6 @@ void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *blk,
return;
}
if (blk->scsi) {
error_setg(errp,
"device is incompatible with x-data-plane, use scsi=off");
return;
}
if (blk->config_wce) {
error_setg(errp, "device is incompatible with x-data-plane, "
"use config-wce=off");
return;
}
/* If dataplane is (re-)enabled while the guest is running there could be
* block jobs that can conflict.
*/
@@ -383,16 +348,8 @@ void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *blk,
return;
}
fd = raw_get_aio_fd(blk->conf.bs);
if (fd < 0) {
error_setg(errp, "drive is incompatible with x-data-plane, "
"use format=raw,cache=none,aio=native");
return;
}
s = g_new0(VirtIOBlockDataPlane, 1);
s->vdev = vdev;
s->fd = fd;
s->blk = blk;
if (blk->iothread) {
@@ -437,7 +394,6 @@ void virtio_blk_data_plane_start(VirtIOBlockDataPlane *s)
BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(s->vdev)));
VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
VirtQueue *vq;
int i;
if (s->started) {
return;
@@ -470,24 +426,18 @@ void virtio_blk_data_plane_start(VirtIOBlockDataPlane *s)
}
s->host_notifier = *virtio_queue_get_host_notifier(vq);
/* Set up ioqueue */
ioq_init(&s->ioqueue, s->fd, REQ_MAX);
for (i = 0; i < ARRAY_SIZE(s->requests); i++) {
ioq_put_iocb(&s->ioqueue, &s->requests[i].iocb);
}
s->io_notifier = *ioq_get_notifier(&s->ioqueue);
s->starting = false;
s->started = true;
trace_virtio_blk_data_plane_start(s);
bdrv_set_aio_context(s->blk->conf.bs, s->ctx);
/* Kick right away to begin processing requests already in vring */
event_notifier_set(virtio_queue_get_host_notifier(vq));
/* Get this show started by hooking up our callbacks */
aio_context_acquire(s->ctx);
aio_set_event_notifier(s->ctx, &s->host_notifier, handle_notify);
aio_set_event_notifier(s->ctx, &s->io_notifier, handle_io);
aio_context_release(s->ctx);
}
@@ -507,13 +457,8 @@ void virtio_blk_data_plane_stop(VirtIOBlockDataPlane *s)
/* Stop notifications for new requests from guest */
aio_set_event_notifier(s->ctx, &s->host_notifier, NULL);
/* Complete pending requests */
while (s->num_reqs > 0) {
aio_poll(s->ctx, true);
}
/* Stop ioq callbacks (there are no pending requests left) */
aio_set_event_notifier(s->ctx, &s->io_notifier, NULL);
/* Drain and switch bs back to the QEMU main loop */
bdrv_set_aio_context(s->blk->conf.bs, qemu_get_aio_context());
aio_context_release(s->ctx);
@@ -522,7 +467,6 @@ void virtio_blk_data_plane_stop(VirtIOBlockDataPlane *s)
*/
vring_teardown(&s->vring, s->vdev, 0);
ioq_cleanup(&s->ioqueue);
k->set_host_notifier(qbus->parent, 0, false);
/* Clean up guest notifier (irq) */

View File

@@ -672,8 +672,7 @@ static const VMStateDescription vmstate_fdrive_media_changed = {
.name = "fdrive/media_changed",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField[]) {
.fields = (VMStateField[]) {
VMSTATE_UINT8(media_changed, FDrive),
VMSTATE_END_OF_LIST()
}
@@ -690,8 +689,7 @@ static const VMStateDescription vmstate_fdrive_media_rate = {
.name = "fdrive/media_rate",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField[]) {
.fields = (VMStateField[]) {
VMSTATE_UINT8(media_rate, FDrive),
VMSTATE_END_OF_LIST()
}
@@ -701,8 +699,7 @@ static const VMStateDescription vmstate_fdrive = {
.name = "fdrive",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField[]) {
.fields = (VMStateField[]) {
VMSTATE_UINT8(head, FDrive),
VMSTATE_UINT8(track, FDrive),
VMSTATE_UINT8(sect, FDrive),
@@ -741,10 +738,9 @@ static const VMStateDescription vmstate_fdc = {
.name = "fdc",
.version_id = 2,
.minimum_version_id = 2,
.minimum_version_id_old = 2,
.pre_save = fdc_pre_save,
.post_load = fdc_post_load,
.fields = (VMStateField []) {
.fields = (VMStateField[]) {
/* Controller State */
VMSTATE_UINT8(sra, FDCtrl),
VMSTATE_UINT8(srb, FDCtrl),
@@ -2209,7 +2205,7 @@ static const VMStateDescription vmstate_isa_fdc ={
.name = "fdc",
.version_id = 2,
.minimum_version_id = 2,
.fields = (VMStateField []) {
.fields = (VMStateField[]) {
VMSTATE_STRUCT(state, FDCtrlISABus, 0, vmstate_fdc, FDCtrl),
VMSTATE_END_OF_LIST()
}
@@ -2251,7 +2247,7 @@ static const VMStateDescription vmstate_sysbus_fdc ={
.name = "fdc",
.version_id = 2,
.minimum_version_id = 2,
.fields = (VMStateField []) {
.fields = (VMStateField[]) {
VMSTATE_STRUCT(state, FDCtrlSysBus, 0, vmstate_fdc, FDCtrl),
VMSTATE_END_OF_LIST()
}

View File

@@ -335,9 +335,7 @@ static inline int onenand_prog_spare(OneNANDState *s, int sec, int secn,
dp, 1) < 0;
}
}
if (dp) {
g_free(dp);
}
g_free(dp);
}
return result;
}

View File

@@ -33,7 +33,6 @@ typedef struct VirtIOBlockReq
VirtQueueElement elem;
struct virtio_blk_inhdr *in;
struct virtio_blk_outhdr *out;
struct virtio_scsi_inhdr *scsi;
QEMUIOVector qiov;
struct VirtIOBlockReq *next;
BlockAcctCookie acct;
@@ -125,13 +124,15 @@ static VirtIOBlockReq *virtio_blk_get_request(VirtIOBlock *s)
return req;
}
static void virtio_blk_handle_scsi(VirtIOBlockReq *req)
int virtio_blk_handle_scsi_req(VirtIOBlock *blk,
VirtQueueElement *elem)
{
#ifdef __linux__
int ret;
int i;
#endif
int status = VIRTIO_BLK_S_OK;
struct virtio_scsi_inhdr *scsi = NULL;
#ifdef __linux__
int i;
struct sg_io_hdr hdr;
#endif
/*
* We require at least one output segment each for the virtio_blk_outhdr
@@ -140,19 +141,18 @@ static void virtio_blk_handle_scsi(VirtIOBlockReq *req)
* We also at least require the virtio_blk_inhdr, the virtio_scsi_inhdr
* and the sense buffer pointer in the input segments.
*/
if (req->elem.out_num < 2 || req->elem.in_num < 3) {
virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR);
g_free(req);
return;
if (elem->out_num < 2 || elem->in_num < 3) {
status = VIRTIO_BLK_S_IOERR;
goto fail;
}
/*
* The scsi inhdr is placed in the second-to-last input segment, just
* before the regular inhdr.
*/
req->scsi = (void *)req->elem.in_sg[req->elem.in_num - 2].iov_base;
scsi = (void *)elem->in_sg[elem->in_num - 2].iov_base;
if (!req->dev->blk.scsi) {
if (!blk->blk.scsi) {
status = VIRTIO_BLK_S_UNSUPP;
goto fail;
}
@@ -160,43 +160,42 @@ static void virtio_blk_handle_scsi(VirtIOBlockReq *req)
/*
* No support for bidirection commands yet.
*/
if (req->elem.out_num > 2 && req->elem.in_num > 3) {
if (elem->out_num > 2 && elem->in_num > 3) {
status = VIRTIO_BLK_S_UNSUPP;
goto fail;
}
#ifdef __linux__
struct sg_io_hdr hdr;
memset(&hdr, 0, sizeof(struct sg_io_hdr));
hdr.interface_id = 'S';
hdr.cmd_len = req->elem.out_sg[1].iov_len;
hdr.cmdp = req->elem.out_sg[1].iov_base;
hdr.cmd_len = elem->out_sg[1].iov_len;
hdr.cmdp = elem->out_sg[1].iov_base;
hdr.dxfer_len = 0;
if (req->elem.out_num > 2) {
if (elem->out_num > 2) {
/*
* If there are more than the minimally required 2 output segments
* there is write payload starting from the third iovec.
*/
hdr.dxfer_direction = SG_DXFER_TO_DEV;
hdr.iovec_count = req->elem.out_num - 2;
hdr.iovec_count = elem->out_num - 2;
for (i = 0; i < hdr.iovec_count; i++)
hdr.dxfer_len += req->elem.out_sg[i + 2].iov_len;
hdr.dxfer_len += elem->out_sg[i + 2].iov_len;
hdr.dxferp = req->elem.out_sg + 2;
hdr.dxferp = elem->out_sg + 2;
} else if (req->elem.in_num > 3) {
} else if (elem->in_num > 3) {
/*
* If we have more than 3 input segments the guest wants to actually
* read data.
*/
hdr.dxfer_direction = SG_DXFER_FROM_DEV;
hdr.iovec_count = req->elem.in_num - 3;
hdr.iovec_count = elem->in_num - 3;
for (i = 0; i < hdr.iovec_count; i++)
hdr.dxfer_len += req->elem.in_sg[i].iov_len;
hdr.dxfer_len += elem->in_sg[i].iov_len;
hdr.dxferp = req->elem.in_sg;
hdr.dxferp = elem->in_sg;
} else {
/*
* Some SCSI commands don't actually transfer any data.
@@ -204,11 +203,11 @@ static void virtio_blk_handle_scsi(VirtIOBlockReq *req)
hdr.dxfer_direction = SG_DXFER_NONE;
}
hdr.sbp = req->elem.in_sg[req->elem.in_num - 3].iov_base;
hdr.mx_sb_len = req->elem.in_sg[req->elem.in_num - 3].iov_len;
hdr.sbp = elem->in_sg[elem->in_num - 3].iov_base;
hdr.mx_sb_len = elem->in_sg[elem->in_num - 3].iov_len;
ret = bdrv_ioctl(req->dev->bs, SG_IO, &hdr);
if (ret) {
status = bdrv_ioctl(blk->bs, SG_IO, &hdr);
if (status) {
status = VIRTIO_BLK_S_UNSUPP;
goto fail;
}
@@ -224,23 +223,31 @@ static void virtio_blk_handle_scsi(VirtIOBlockReq *req)
hdr.status = CHECK_CONDITION;
}
stl_p(&req->scsi->errors,
stl_p(&scsi->errors,
hdr.status | (hdr.msg_status << 8) |
(hdr.host_status << 16) | (hdr.driver_status << 24));
stl_p(&req->scsi->residual, hdr.resid);
stl_p(&req->scsi->sense_len, hdr.sb_len_wr);
stl_p(&req->scsi->data_len, hdr.dxfer_len);
stl_p(&scsi->residual, hdr.resid);
stl_p(&scsi->sense_len, hdr.sb_len_wr);
stl_p(&scsi->data_len, hdr.dxfer_len);
virtio_blk_req_complete(req, status);
g_free(req);
return;
return status;
#else
abort();
#endif
fail:
/* Just put anything nonzero so that the ioctl fails in the guest. */
stl_p(&req->scsi->errors, 255);
if (scsi) {
stl_p(&scsi->errors, 255);
}
return status;
}
static void virtio_blk_handle_scsi(VirtIOBlockReq *req)
{
int status;
status = virtio_blk_handle_scsi_req(req->dev, &req->elem);
virtio_blk_req_complete(req, status);
g_free(req);
}
@@ -487,12 +494,12 @@ static void virtio_blk_update_config(VirtIODevice *vdev, uint8_t *config)
bdrv_get_geometry(s->bs, &capacity);
memset(&blkcfg, 0, sizeof(blkcfg));
stq_raw(&blkcfg.capacity, capacity);
stl_raw(&blkcfg.seg_max, 128 - 2);
stw_raw(&blkcfg.cylinders, s->conf->cyls);
stl_raw(&blkcfg.blk_size, blk_size);
stw_raw(&blkcfg.min_io_size, s->conf->min_io_size / blk_size);
stw_raw(&blkcfg.opt_io_size, s->conf->opt_io_size / blk_size);
stq_p(&blkcfg.capacity, capacity);
stl_p(&blkcfg.seg_max, 128 - 2);
stw_p(&blkcfg.cylinders, s->conf->cyls);
stl_p(&blkcfg.blk_size, blk_size);
stw_p(&blkcfg.min_io_size, s->conf->min_io_size / blk_size);
stw_p(&blkcfg.opt_io_size, s->conf->opt_io_size / blk_size);
blkcfg.heads = s->conf->heads;
/*
* We must ensure that the block device capacity is a multiple of
@@ -523,7 +530,10 @@ static void virtio_blk_set_config(VirtIODevice *vdev, const uint8_t *config)
struct virtio_blk_config blkcfg;
memcpy(&blkcfg, config, sizeof(blkcfg));
aio_context_acquire(bdrv_get_aio_context(s->bs));
bdrv_set_enable_write_cache(s->bs, blkcfg.wce != 0);
aio_context_release(bdrv_get_aio_context(s->bs));
}
static uint32_t virtio_blk_get_features(VirtIODevice *vdev, uint32_t features)
@@ -582,7 +592,10 @@ static void virtio_blk_set_status(VirtIODevice *vdev, uint8_t status)
* s->bs would erroneously be placed in writethrough mode.
*/
if (!(features & (1 << VIRTIO_BLK_F_CONFIG_WCE))) {
bdrv_set_enable_write_cache(s->bs, !!(features & (1 << VIRTIO_BLK_F_WCE)));
aio_context_acquire(bdrv_get_aio_context(s->bs));
bdrv_set_enable_write_cache(s->bs,
!!(features & (1 << VIRTIO_BLK_F_WCE)));
aio_context_release(bdrv_get_aio_context(s->bs));
}
}

View File

@@ -660,8 +660,7 @@ static const VMStateDescription vmstate_escc_chn = {
.name ="escc_chn",
.version_id = 2,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField []) {
.fields = (VMStateField[]) {
VMSTATE_UINT32(vmstate_dummy, ChannelState),
VMSTATE_UINT32(reg, ChannelState),
VMSTATE_UINT32(rxint, ChannelState),
@@ -680,8 +679,7 @@ static const VMStateDescription vmstate_escc = {
.name ="escc",
.version_id = 2,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField []) {
.fields = (VMStateField[]) {
VMSTATE_STRUCT_ARRAY(chn, ESCCState, 2, 2, vmstate_escc_chn,
ChannelState),
VMSTATE_END_OF_LIST()

View File

@@ -34,6 +34,7 @@
typedef struct PCISerialState {
PCIDevice dev;
SerialState state;
uint8_t prog_if;
} PCISerialState;
typedef struct PCIMultiSerialState {
@@ -44,6 +45,7 @@ typedef struct PCIMultiSerialState {
SerialState state[PCI_SERIAL_MAX_PORTS];
uint32_t level[PCI_SERIAL_MAX_PORTS];
qemu_irq *irqs;
uint8_t prog_if;
} PCIMultiSerialState;
static int serial_pci_init(PCIDevice *dev)
@@ -60,6 +62,7 @@ static int serial_pci_init(PCIDevice *dev)
return -1;
}
pci->dev.config[PCI_CLASS_PROG] = pci->prog_if;
pci->dev.config[PCI_INTERRUPT_PIN] = 0x01;
s->irq = pci_allocate_irq(&pci->dev);
@@ -101,6 +104,7 @@ static int multi_serial_pci_init(PCIDevice *dev)
assert(pci->ports > 0);
assert(pci->ports <= PCI_SERIAL_MAX_PORTS);
pci->dev.config[PCI_CLASS_PROG] = pci->prog_if;
pci->dev.config[PCI_INTERRUPT_PIN] = 0x01;
memory_region_init(&pci->iobar, OBJECT(pci), "multiserial", 8 * pci->ports);
pci_register_bar(&pci->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &pci->iobar);
@@ -155,7 +159,7 @@ static const VMStateDescription vmstate_pci_serial = {
.name = "pci-serial",
.version_id = 1,
.minimum_version_id = 1,
.fields = (VMStateField[]) {
.fields = (VMStateField[]) {
VMSTATE_PCI_DEVICE(dev, PCISerialState),
VMSTATE_STRUCT(state, PCISerialState, 0, vmstate_serial, SerialState),
VMSTATE_END_OF_LIST()
@@ -166,7 +170,7 @@ static const VMStateDescription vmstate_pci_multi_serial = {
.name = "pci-serial-multi",
.version_id = 1,
.minimum_version_id = 1,
.fields = (VMStateField[]) {
.fields = (VMStateField[]) {
VMSTATE_PCI_DEVICE(dev, PCIMultiSerialState),
VMSTATE_STRUCT_ARRAY(state, PCIMultiSerialState, PCI_SERIAL_MAX_PORTS,
0, vmstate_serial, SerialState),
@@ -177,12 +181,14 @@ static const VMStateDescription vmstate_pci_multi_serial = {
static Property serial_pci_properties[] = {
DEFINE_PROP_CHR("chardev", PCISerialState, state.chr),
DEFINE_PROP_UINT8("prog_if", PCISerialState, prog_if, 0x02),
DEFINE_PROP_END_OF_LIST(),
};
static Property multi_2x_serial_pci_properties[] = {
DEFINE_PROP_CHR("chardev1", PCIMultiSerialState, state[0].chr),
DEFINE_PROP_CHR("chardev2", PCIMultiSerialState, state[1].chr),
DEFINE_PROP_UINT8("prog_if", PCIMultiSerialState, prog_if, 0x02),
DEFINE_PROP_END_OF_LIST(),
};
@@ -191,6 +197,7 @@ static Property multi_4x_serial_pci_properties[] = {
DEFINE_PROP_CHR("chardev2", PCIMultiSerialState, state[1].chr),
DEFINE_PROP_CHR("chardev3", PCIMultiSerialState, state[2].chr),
DEFINE_PROP_CHR("chardev4", PCIMultiSerialState, state[3].chr),
DEFINE_PROP_UINT8("prog_if", PCIMultiSerialState, prog_if, 0x02),
DEFINE_PROP_END_OF_LIST(),
};

View File

@@ -602,7 +602,7 @@ const VMStateDescription vmstate_serial = {
.minimum_version_id = 2,
.pre_save = serial_pre_save,
.post_load = serial_post_load,
.fields = (VMStateField []) {
.fields = (VMStateField[]) {
VMSTATE_UINT16_V(divider, SerialState, 2),
VMSTATE_UINT8(rbr, SerialState),
VMSTATE_UINT8(ier, SerialState),

View File

@@ -148,8 +148,7 @@ static const VMStateDescription vmstate_spapr_vty = {
.name = "spapr_vty",
.version_id = 1,
.minimum_version_id = 1,
.minimum_version_id_old = 1,
.fields = (VMStateField []) {
.fields = (VMStateField[]) {
VMSTATE_SPAPR_VIO(sdev, VIOsPAPRVTYDevice),
VMSTATE_UINT32(in, VIOsPAPRVTYDevice),

View File

@@ -87,6 +87,11 @@ static void uart_update_status(XilinxUARTLite *s)
s->regs[R_STATUS] = r;
}
static void xilinx_uartlite_reset(DeviceState *dev)
{
uart_update_status(XILINX_UARTLITE(dev));
}
static uint64_t
uart_read(void *opaque, hwaddr addr, unsigned int size)
{
@@ -196,34 +201,39 @@ static void uart_event(void *opaque, int event)
}
static int xilinx_uartlite_init(SysBusDevice *dev)
static void xilinx_uartlite_realize(DeviceState *dev, Error **errp)
{
XilinxUARTLite *s = XILINX_UARTLITE(dev);
sysbus_init_irq(dev, &s->irq);
uart_update_status(s);
memory_region_init_io(&s->mmio, OBJECT(s), &uart_ops, s,
"xlnx.xps-uartlite", R_MAX * 4);
sysbus_init_mmio(dev, &s->mmio);
s->chr = qemu_char_get_next_serial();
if (s->chr)
qemu_chr_add_handlers(s->chr, uart_can_rx, uart_rx, uart_event, s);
return 0;
}
static void xilinx_uartlite_init(Object *obj)
{
XilinxUARTLite *s = XILINX_UARTLITE(obj);
sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
memory_region_init_io(&s->mmio, obj, &uart_ops, s,
"xlnx.xps-uartlite", R_MAX * 4);
sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
}
static void xilinx_uartlite_class_init(ObjectClass *klass, void *data)
{
SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
sdc->init = xilinx_uartlite_init;
dc->reset = xilinx_uartlite_reset;
dc->realize = xilinx_uartlite_realize;
}
static const TypeInfo xilinx_uartlite_info = {
.name = TYPE_XILINX_UARTLITE,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(XilinxUARTLite),
.instance_init = xilinx_uartlite_init,
.class_init = xilinx_uartlite_class_init,
};

View File

@@ -439,11 +439,27 @@ PropertyInfo qdev_prop_iothread = {
static int qdev_add_one_global(QemuOpts *opts, void *opaque)
{
GlobalProperty *g;
ObjectClass *oc;
g = g_malloc0(sizeof(*g));
g->driver = qemu_opt_get(opts, "driver");
g->property = qemu_opt_get(opts, "property");
g->value = qemu_opt_get(opts, "value");
oc = object_class_by_name(g->driver);
if (oc) {
DeviceClass *dc = DEVICE_CLASS(oc);
if (dc->hotpluggable) {
/* If hotpluggable then skip not_used checking. */
g->not_used = false;
} else {
/* Maybe a typo. */
g->not_used = true;
}
} else {
/* Maybe a typo. */
g->not_used = true;
}
qdev_prop_register_global(g);
return 0;
}

View File

@@ -955,6 +955,23 @@ void qdev_prop_register_global_list(GlobalProperty *props)
}
}
int qdev_prop_check_global(void)
{
GlobalProperty *prop;
int ret = 0;
QTAILQ_FOREACH(prop, &global_props, next) {
if (!prop->not_used) {
continue;
}
ret = 1;
error_report("Warning: \"-global %s.%s=%s\" not used",
prop->driver, prop->property, prop->value);
}
return ret;
}
void qdev_prop_set_globals_for_type(DeviceState *dev, const char *typename,
Error **errp)
{
@@ -966,6 +983,7 @@ void qdev_prop_set_globals_for_type(DeviceState *dev, const char *typename,
if (strcmp(typename, prop->driver) != 0) {
continue;
}
prop->not_used = false;
object_property_parse(OBJECT(dev), prop->value, prop->property, &err);
if (err != NULL) {
error_propagate(errp, err);

View File

@@ -177,7 +177,7 @@ static uint64_t cg3_reg_read(void *opaque, hwaddr addr, unsigned size)
/* monitor ID 6, board type = 1 (color) */
val = s->regs[1] | CG3_SR_1152_900_76_B | CG3_SR_ID_COLOR;
break;
case CG3_REG_FBC_CURSTART ... CG3_REG_SIZE:
case CG3_REG_FBC_CURSTART ... CG3_REG_SIZE - 1:
val = s->regs[addr - 0x10];
break;
default:
@@ -247,7 +247,7 @@ static void cg3_reg_write(void *opaque, hwaddr addr, uint64_t val,
qemu_irq_lower(s->irq);
}
break;
case CG3_REG_FBC_CURSTART ... CG3_REG_SIZE:
case CG3_REG_FBC_CURSTART ... CG3_REG_SIZE - 1:
s->regs[addr - 0x10] = val;
break;
default:
@@ -274,6 +274,20 @@ static const GraphicHwOps cg3_ops = {
.gfx_update = cg3_update_display,
};
static void cg3_initfn(Object *obj)
{
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
CG3State *s = CG3(obj);
memory_region_init_ram(&s->rom, NULL, "cg3.prom", FCODE_MAX_ROM_SIZE);
memory_region_set_readonly(&s->rom, true);
sysbus_init_mmio(sbd, &s->rom);
memory_region_init_io(&s->reg, NULL, &cg3_reg_ops, s, "cg3.reg",
CG3_REG_SIZE);
sysbus_init_mmio(sbd, &s->reg);
}
static void cg3_realizefn(DeviceState *dev, Error **errp)
{
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
@@ -282,11 +296,7 @@ static void cg3_realizefn(DeviceState *dev, Error **errp)
char *fcode_filename;
/* FCode ROM */
memory_region_init_ram(&s->rom, NULL, "cg3.prom", FCODE_MAX_ROM_SIZE);
vmstate_register_ram_global(&s->rom);
memory_region_set_readonly(&s->rom, true);
sysbus_init_mmio(sbd, &s->rom);
fcode_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, CG3_ROM_FILE);
if (fcode_filename) {
ret = load_image_targphys(fcode_filename, s->prom_addr,
@@ -296,10 +306,6 @@ static void cg3_realizefn(DeviceState *dev, Error **errp)
}
}
memory_region_init_io(&s->reg, NULL, &cg3_reg_ops, s, "cg3.reg",
CG3_REG_SIZE);
sysbus_init_mmio(sbd, &s->reg);
memory_region_init_ram(&s->vram_mem, NULL, "cg3.vram", s->vram_size);
vmstate_register_ram_global(&s->vram_mem);
sysbus_init_mmio(sbd, &s->vram_mem);
@@ -374,6 +380,7 @@ static const TypeInfo cg3_info = {
.name = TYPE_CG3,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(CG3State),
.instance_init = cg3_initfn,
.class_init = cg3_class_init,
};

Some files were not shown because too many files have changed in this diff Show More