Compare commits
252 Commits
pull-smbio
...
pull-roms-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d880b28cef | ||
|
|
db76ec6291 | ||
|
|
f30d56e7d6 | ||
|
|
cb3d83bc49 | ||
|
|
cd2b9b8680 | ||
|
|
fccae3226d | ||
|
|
41a3f3c1bc | ||
|
|
1b5498f687 | ||
|
|
e5bfd64050 | ||
|
|
7dfba6dfbf | ||
|
|
12f7fb6086 | ||
|
|
6d35556caa | ||
|
|
1b939d9227 | ||
|
|
96d0ee7f09 | ||
|
|
af3cbfbe80 | ||
|
|
cf06667428 | ||
|
|
dddbb2e1e3 | ||
|
|
eb68a4fa4e | ||
|
|
4e9cf8409a | ||
|
|
fdd8ec7184 | ||
|
|
00d7a1acab | ||
|
|
a8111212b3 | ||
|
|
6bf3e99747 | ||
|
|
5053361b3e | ||
|
|
a7f96f7666 | ||
|
|
ae0218e350 | ||
|
|
5588ff2921 | ||
|
|
8c081b1802 | ||
|
|
8587c30c3e | ||
|
|
267c931985 | ||
|
|
abce5964be | ||
|
|
38cf39f739 | ||
|
|
e083c4a233 | ||
|
|
f6bff89d06 | ||
|
|
1813e1758d | ||
|
|
52a1f64ec5 | ||
|
|
5c53bb8121 | ||
|
|
4387345a96 | ||
|
|
86360ad71d | ||
|
|
9d171bd937 | ||
|
|
2a8e6c7a85 | ||
|
|
5a007547df | ||
|
|
fd040174ac | ||
|
|
e86e869770 | ||
|
|
e940bc13ee | ||
|
|
4f11aa8a40 | ||
|
|
4557117d9e | ||
|
|
02ce232c50 | ||
|
|
b1e6fc0817 | ||
|
|
06b4f00d53 | ||
|
|
b690d679c1 | ||
|
|
cc1626556d | ||
|
|
cd0c5389dd | ||
|
|
ab31979a7e | ||
|
|
66ef8bd9c1 | ||
|
|
2767ceec4e | ||
|
|
5e54769c92 | ||
|
|
0f230bf70e | ||
|
|
ee16ce9337 | ||
|
|
196857f8bf | ||
|
|
4af8be1f88 | ||
|
|
415168e0c7 | ||
|
|
a903f40c31 | ||
|
|
64dfefed16 | ||
|
|
7daecb3065 | ||
|
|
77dbc81b0f | ||
|
|
10f08a0a34 | ||
|
|
74fe188cd1 | ||
|
|
ba0ad89e2c | ||
|
|
85f49cad87 | ||
|
|
ec209aca83 | ||
|
|
5f4d5e1aa6 | ||
|
|
1a443c1b8b | ||
|
|
f915db07ef | ||
|
|
65f33bc002 | ||
|
|
e940f543ae | ||
|
|
636713bad4 | ||
|
|
ef47827ac4 | ||
|
|
6877cff044 | ||
|
|
7d9cb533f5 | ||
|
|
7a98593b34 | ||
|
|
64135217a7 | ||
|
|
5b877045d3 | ||
|
|
f3455d4704 | ||
|
|
42ee4194f2 | ||
|
|
cd9aa33e2c | ||
|
|
665f119fba | ||
|
|
bcdcf75d62 | ||
|
|
4951013ff5 | ||
|
|
cf10a5b18f | ||
|
|
5906366ef0 | ||
|
|
e9c5c1f40c | ||
|
|
cb45de6798 | ||
|
|
a719a27c82 | ||
|
|
33aaad529e | ||
|
|
98c1200af1 | ||
|
|
0a60774906 | ||
|
|
849d8284c5 | ||
|
|
0db564eee2 | ||
|
|
264f8b4fdc | ||
|
|
8f98aeb9c0 | ||
|
|
2115182f0c | ||
|
|
d608cc5c53 | ||
|
|
5c40c7395d | ||
|
|
5a8b231e7e | ||
|
|
43cbeffb19 | ||
|
|
6b342cc9c8 | ||
|
|
a76a2f729a | ||
|
|
4f60af9ac0 | ||
|
|
ff788b6fe6 | ||
|
|
5894145a26 | ||
|
|
e00e36fb91 | ||
|
|
1dad2ce973 | ||
|
|
ef0bd3bba6 | ||
|
|
30b572efd5 | ||
|
|
b160d7f84a | ||
|
|
53158adc23 | ||
|
|
9c24a52e29 | ||
|
|
ad7443e40a | ||
|
|
7d08f0da90 | ||
|
|
8e25c274ae | ||
|
|
edc1ba7a7a | ||
|
|
307b2f0148 | ||
|
|
6ad7c326a1 | ||
|
|
797720876a | ||
|
|
a22f8f3894 | ||
|
|
f95c967a79 | ||
|
|
f33cc84dd4 | ||
|
|
69b15212d7 | ||
|
|
770e39f743 | ||
|
|
6a0a70b0f5 | ||
|
|
fbdb664cb6 | ||
|
|
6075137d94 | ||
|
|
79f320246c | ||
|
|
bfaaad0281 | ||
|
|
f73cdbc6ac | ||
|
|
f5a014d236 | ||
|
|
4798fe55c4 | ||
|
|
ad0a118fa3 | ||
|
|
8e8be266af | ||
|
|
4fc00556ab | ||
|
|
f31352041b | ||
|
|
8b6bb0ad17 | ||
|
|
04b0de0ee8 | ||
|
|
b18a990c3d | ||
|
|
cab00a5aa1 | ||
|
|
62622c11f2 | ||
|
|
ad3f7e31bf | ||
|
|
c8097612ce | ||
|
|
d5fdb85e3d | ||
|
|
046a184414 | ||
|
|
c976437c7d | ||
|
|
285364e968 | ||
|
|
fe680d0dac | ||
|
|
aa93200b88 | ||
|
|
9df11c9f08 | ||
|
|
8cbad670ce | ||
|
|
8d1dc5d188 | ||
|
|
c9541f67df | ||
|
|
7f8fea8b3d | ||
|
|
9ac1c4c07e | ||
|
|
097a97a665 | ||
|
|
7c38ecd097 | ||
|
|
56bf1a8e90 | ||
|
|
c4400206d4 | ||
|
|
422f32c5b1 | ||
|
|
951916d02c | ||
|
|
9898370497 | ||
|
|
03e2bfee37 | ||
|
|
cf972928fc | ||
|
|
8bc3923343 | ||
|
|
58570ed894 | ||
|
|
71411d3580 | ||
|
|
1534ee93cc | ||
|
|
21a246a43b | ||
|
|
d99598cc99 | ||
|
|
d97326eec2 | ||
|
|
0d6ab3ab91 | ||
|
|
e30d1d8c71 | ||
|
|
548f52ea06 | ||
|
|
ca99993adc | ||
|
|
a890a2f913 | ||
|
|
98f93ddd84 | ||
|
|
73d963c0a7 | ||
|
|
a9c380db3b | ||
|
|
767adce2d9 | ||
|
|
9f8e9895c5 | ||
|
|
3476436a44 | ||
|
|
3c3ce98142 | ||
|
|
52f91c3723 | ||
|
|
5193be3be3 | ||
|
|
ead7a57df3 | ||
|
|
caa881abe0 | ||
|
|
36cf2a3713 | ||
|
|
4b53c2c72c | ||
|
|
d2ef4b61fe | ||
|
|
d8d0a0bc7e | ||
|
|
5f691ff91d | ||
|
|
3f1c49e213 | ||
|
|
ae2158ad6c | ||
|
|
cc45995294 | ||
|
|
848696bf35 | ||
|
|
cc900d34e7 | ||
|
|
efbf5df020 | ||
|
|
fbaf445a89 | ||
|
|
8fa74c947d | ||
|
|
d7b50c0cc0 | ||
|
|
535b45631a | ||
|
|
a7d915f388 | ||
|
|
a7ded163db | ||
|
|
4688c94c1f | ||
|
|
0175ba109e | ||
|
|
65cd9064e1 | ||
|
|
a7737e4496 | ||
|
|
2f719f195c | ||
|
|
958db90cd5 | ||
|
|
f1e298794d | ||
|
|
aaa663916d | ||
|
|
00b4fbe274 | ||
|
|
9e1d668ba9 | ||
|
|
ce0abca3e3 | ||
|
|
a39fb273bd | ||
|
|
eea750a562 | ||
|
|
71f7fe48e1 | ||
|
|
4082f0889b | ||
|
|
5bf81c8d63 | ||
|
|
35fc1f7189 | ||
|
|
8ebb876357 | ||
|
|
afa82daf16 | ||
|
|
9cd04ccf75 | ||
|
|
457d397a24 | ||
|
|
2dc7fdf33d | ||
|
|
9e4eff5b54 | ||
|
|
f7eaed8555 | ||
|
|
ada435f47e | ||
|
|
1c76551fae | ||
|
|
69e25d26b4 | ||
|
|
214bb280c6 | ||
|
|
ad6919dc0a | ||
|
|
24e76ff06b | ||
|
|
2468265465 | ||
|
|
43ce393ee5 | ||
|
|
e586822a58 | ||
|
|
6d30db19ca | ||
|
|
18cb008865 | ||
|
|
7af03928b1 | ||
|
|
34d6086236 | ||
|
|
a29e5ba21f | ||
|
|
4bc2975698 | ||
|
|
52b6549442 | ||
|
|
8c0f0a60d4 | ||
|
|
aa07f5ecf9 |
22
MAINTAINERS
22
MAINTAINERS
@@ -52,6 +52,13 @@ General Project Administration
|
|||||||
------------------------------
|
------------------------------
|
||||||
M: Anthony Liguori <aliguori@amazon.com>
|
M: Anthony Liguori <aliguori@amazon.com>
|
||||||
|
|
||||||
|
Responsible Disclosure, Reporting Security Issues
|
||||||
|
------------------------------
|
||||||
|
W: http://wiki.qemu.org/SecurityProcess
|
||||||
|
M: Michael S. Tsirkin <mst@redhat.com>
|
||||||
|
M: Anthony Liguori <aliguori@amazon.com>
|
||||||
|
L: secalert@redhat.com
|
||||||
|
|
||||||
Guest CPU cores (TCG):
|
Guest CPU cores (TCG):
|
||||||
----------------------
|
----------------------
|
||||||
Alpha
|
Alpha
|
||||||
@@ -601,6 +608,7 @@ USB
|
|||||||
M: Gerd Hoffmann <kraxel@redhat.com>
|
M: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: hw/usb/*
|
F: hw/usb/*
|
||||||
|
F: tests/usb-hcd-ehci-test.c
|
||||||
|
|
||||||
VFIO
|
VFIO
|
||||||
M: Alex Williamson <alex.williamson@redhat.com>
|
M: Alex Williamson <alex.williamson@redhat.com>
|
||||||
@@ -666,6 +674,9 @@ M: Gerd Hoffmann <kraxel@redhat.com>
|
|||||||
S: Maintained
|
S: Maintained
|
||||||
F: audio/
|
F: audio/
|
||||||
F: hw/audio/
|
F: hw/audio/
|
||||||
|
F: tests/ac97-test.c
|
||||||
|
F: tests/es1370-test.c
|
||||||
|
F: tests/intel-hda-test.c
|
||||||
|
|
||||||
Block
|
Block
|
||||||
M: Kevin Wolf <kwolf@redhat.com>
|
M: Kevin Wolf <kwolf@redhat.com>
|
||||||
@@ -780,6 +791,17 @@ S: Supported
|
|||||||
F: qapi-schema.json
|
F: qapi-schema.json
|
||||||
T: git git://repo.or.cz/qemu/qmp-unstable.git queue/qmp
|
T: git git://repo.or.cz/qemu/qmp-unstable.git queue/qmp
|
||||||
|
|
||||||
|
QOM
|
||||||
|
M: Anthony Liguori <aliguori@amazon.com>
|
||||||
|
M: Andreas Färber <afaerber@suse.de>
|
||||||
|
S: Supported
|
||||||
|
T: git git://github.com/afaerber/qemu-cpu.git qom-next
|
||||||
|
F: include/qom/
|
||||||
|
X: include/qom/cpu.h
|
||||||
|
F: qom/
|
||||||
|
X: qom/cpu.c
|
||||||
|
F: tests/qom-test.c
|
||||||
|
|
||||||
QMP
|
QMP
|
||||||
M: Luiz Capitulino <lcapitulino@redhat.com>
|
M: Luiz Capitulino <lcapitulino@redhat.com>
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|||||||
46
Makefile
46
Makefile
@@ -148,10 +148,6 @@ endif
|
|||||||
|
|
||||||
all: $(DOCS) $(TOOLS) $(HELPERS-y) recurse-all modules
|
all: $(DOCS) $(TOOLS) $(HELPERS-y) recurse-all modules
|
||||||
|
|
||||||
vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
|
|
||||||
|
|
||||||
vl.o: QEMU_CFLAGS+=$(SDL_CFLAGS)
|
|
||||||
|
|
||||||
config-host.h: config-host.h-timestamp
|
config-host.h: config-host.h-timestamp
|
||||||
config-host.h-timestamp: config-host.mak
|
config-host.h-timestamp: config-host.mak
|
||||||
qemu-options.def: $(SRC_PATH)/qemu-options.hx
|
qemu-options.def: $(SRC_PATH)/qemu-options.hx
|
||||||
@@ -195,8 +191,6 @@ ALL_SUBDIRS=$(TARGET_DIRS) $(patsubst %,pc-bios/%, $(ROMS))
|
|||||||
|
|
||||||
recurse-all: $(SUBDIR_RULES) $(ROMSUBDIR_RULES)
|
recurse-all: $(SUBDIR_RULES) $(ROMSUBDIR_RULES)
|
||||||
|
|
||||||
bt-host.o: QEMU_CFLAGS += $(BLUEZ_CFLAGS)
|
|
||||||
|
|
||||||
$(BUILD_DIR)/version.o: $(SRC_PATH)/version.rc $(BUILD_DIR)/config-host.h | $(BUILD_DIR)/version.lo
|
$(BUILD_DIR)/version.o: $(SRC_PATH)/version.rc $(BUILD_DIR)/config-host.h | $(BUILD_DIR)/version.lo
|
||||||
$(call quiet-command,$(WINDRES) -I$(BUILD_DIR) -o $@ $<," RC version.o")
|
$(call quiet-command,$(WINDRES) -I$(BUILD_DIR) -o $@ $<," RC version.o")
|
||||||
$(BUILD_DIR)/version.lo: $(SRC_PATH)/version.rc $(BUILD_DIR)/config-host.h
|
$(BUILD_DIR)/version.lo: $(SRC_PATH)/version.rc $(BUILD_DIR)/config-host.h
|
||||||
@@ -238,23 +232,35 @@ qapi-py = $(SRC_PATH)/scripts/qapi.py $(SRC_PATH)/scripts/ordereddict.py
|
|||||||
|
|
||||||
qga/qapi-generated/qga-qapi-types.c qga/qapi-generated/qga-qapi-types.h :\
|
qga/qapi-generated/qga-qapi-types.c qga/qapi-generated/qga-qapi-types.h :\
|
||||||
$(SRC_PATH)/qga/qapi-schema.json $(SRC_PATH)/scripts/qapi-types.py $(qapi-py)
|
$(SRC_PATH)/qga/qapi-schema.json $(SRC_PATH)/scripts/qapi-types.py $(qapi-py)
|
||||||
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py $(gen-out-type) -o qga/qapi-generated -p "qga-" < $<, " GEN $@")
|
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py \
|
||||||
|
$(gen-out-type) -o qga/qapi-generated -p "qga-" -i $<, \
|
||||||
|
" GEN $@")
|
||||||
qga/qapi-generated/qga-qapi-visit.c qga/qapi-generated/qga-qapi-visit.h :\
|
qga/qapi-generated/qga-qapi-visit.c qga/qapi-generated/qga-qapi-visit.h :\
|
||||||
$(SRC_PATH)/qga/qapi-schema.json $(SRC_PATH)/scripts/qapi-visit.py $(qapi-py)
|
$(SRC_PATH)/qga/qapi-schema.json $(SRC_PATH)/scripts/qapi-visit.py $(qapi-py)
|
||||||
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py $(gen-out-type) -o qga/qapi-generated -p "qga-" < $<, " GEN $@")
|
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py \
|
||||||
|
$(gen-out-type) -o qga/qapi-generated -p "qga-" -i $<, \
|
||||||
|
" GEN $@")
|
||||||
qga/qapi-generated/qga-qmp-commands.h qga/qapi-generated/qga-qmp-marshal.c :\
|
qga/qapi-generated/qga-qmp-commands.h qga/qapi-generated/qga-qmp-marshal.c :\
|
||||||
$(SRC_PATH)/qga/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
|
$(SRC_PATH)/qga/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
|
||||||
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py $(gen-out-type) -o qga/qapi-generated -p "qga-" < $<, " GEN $@")
|
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py \
|
||||||
|
$(gen-out-type) -o qga/qapi-generated -p "qga-" -i $<, \
|
||||||
|
" GEN $@")
|
||||||
|
|
||||||
qapi-types.c qapi-types.h :\
|
qapi-types.c qapi-types.h :\
|
||||||
$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-types.py $(qapi-py)
|
$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-types.py $(qapi-py)
|
||||||
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py $(gen-out-type) -o "." -b < $<, " GEN $@")
|
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py \
|
||||||
|
$(gen-out-type) -o "." -b -i $<, \
|
||||||
|
" GEN $@")
|
||||||
qapi-visit.c qapi-visit.h :\
|
qapi-visit.c qapi-visit.h :\
|
||||||
$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-visit.py $(qapi-py)
|
$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-visit.py $(qapi-py)
|
||||||
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py $(gen-out-type) -o "." -b < $<, " GEN $@")
|
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py \
|
||||||
|
$(gen-out-type) -o "." -b -i $<, \
|
||||||
|
" GEN $@")
|
||||||
qmp-commands.h qmp-marshal.c :\
|
qmp-commands.h qmp-marshal.c :\
|
||||||
$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
|
$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
|
||||||
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py $(gen-out-type) -m -o "." < $<, " GEN $@")
|
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py \
|
||||||
|
$(gen-out-type) -o "." -m -i $<, \
|
||||||
|
" GEN $@")
|
||||||
|
|
||||||
QGALIB_GEN=$(addprefix qga/qapi-generated/, qga-qapi-types.h qga-qapi-visit.h qga-qmp-commands.h)
|
QGALIB_GEN=$(addprefix qga/qapi-generated/, qga-qapi-types.h qga-qapi-visit.h qga-qmp-commands.h)
|
||||||
$(qga-obj-y) qemu-ga.o: $(QGALIB_GEN)
|
$(qga-obj-y) qemu-ga.o: $(QGALIB_GEN)
|
||||||
@@ -372,17 +378,25 @@ install: all $(if $(BUILD_DOCS),install-doc) install-sysconfig \
|
|||||||
install-datadir install-localstatedir
|
install-datadir install-localstatedir
|
||||||
$(INSTALL_DIR) "$(DESTDIR)$(bindir)"
|
$(INSTALL_DIR) "$(DESTDIR)$(bindir)"
|
||||||
ifneq ($(TOOLS),)
|
ifneq ($(TOOLS),)
|
||||||
$(INSTALL_PROG) $(STRIP_OPT) $(TOOLS) "$(DESTDIR)$(bindir)"
|
$(INSTALL_PROG) $(TOOLS) "$(DESTDIR)$(bindir)"
|
||||||
|
ifneq ($(STRIP),)
|
||||||
|
$(STRIP) $(TOOLS:%="$(DESTDIR)$(bindir)/%")
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
ifneq ($(CONFIG_MODULES),)
|
ifneq ($(CONFIG_MODULES),)
|
||||||
$(INSTALL_DIR) "$(DESTDIR)$(qemu_moddir)"
|
$(INSTALL_DIR) "$(DESTDIR)$(qemu_moddir)"
|
||||||
for s in $(patsubst %.mo,%$(DSOSUF),$(modules-m)); do \
|
for s in $(modules-m:.mo=$(DSOSUF)); do \
|
||||||
$(INSTALL_PROG) $(STRIP_OPT) $$s "$(DESTDIR)$(qemu_moddir)/$$(echo $$s | tr / -)"; \
|
t="$(DESTDIR)$(qemu_moddir)/$$(echo $$s | tr / -)"; \
|
||||||
|
$(INSTALL_LIB) $$s "$$t"; \
|
||||||
|
test -z "$(STRIP)" || $(STRIP) "$$t"; \
|
||||||
done
|
done
|
||||||
endif
|
endif
|
||||||
ifneq ($(HELPERS-y),)
|
ifneq ($(HELPERS-y),)
|
||||||
$(INSTALL_DIR) "$(DESTDIR)$(libexecdir)"
|
$(INSTALL_DIR) "$(DESTDIR)$(libexecdir)"
|
||||||
$(INSTALL_PROG) $(STRIP_OPT) $(HELPERS-y) "$(DESTDIR)$(libexecdir)"
|
$(INSTALL_PROG) $(HELPERS-y) "$(DESTDIR)$(libexecdir)"
|
||||||
|
ifneq ($(STRIP),)
|
||||||
|
$(STRIP) $(HELPERS-y:%="$(DESTDIR)$(libexecdir)/%")
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
ifneq ($(BLOBS),)
|
ifneq ($(BLOBS),)
|
||||||
set -e; for x in $(BLOBS); do \
|
set -e; for x in $(BLOBS); do \
|
||||||
|
|||||||
@@ -31,6 +31,8 @@ libcacard-y += libcacard/vcard_emul_nss.o
|
|||||||
libcacard-y += libcacard/vcard_emul_type.o
|
libcacard-y += libcacard/vcard_emul_type.o
|
||||||
libcacard-y += libcacard/card_7816.o
|
libcacard-y += libcacard/card_7816.o
|
||||||
libcacard-y += libcacard/vcardt.o
|
libcacard-y += libcacard/vcardt.o
|
||||||
|
libcacard/vcard_emul_nss.o-cflags := $(NSS_CFLAGS)
|
||||||
|
libcacard/vcard_emul_nss.o-libs := $(NSS_LIBS)
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
# Target independent part of system emulation. The long term path is to
|
# Target independent part of system emulation. The long term path is to
|
||||||
@@ -64,9 +66,11 @@ common-obj-y += hw/
|
|||||||
|
|
||||||
common-obj-y += ui/
|
common-obj-y += ui/
|
||||||
common-obj-y += bt-host.o bt-vhci.o
|
common-obj-y += bt-host.o bt-vhci.o
|
||||||
|
bt-host.o-cflags := $(BLUEZ_CFLAGS)
|
||||||
|
|
||||||
common-obj-y += dma-helpers.o
|
common-obj-y += dma-helpers.o
|
||||||
common-obj-y += vl.o
|
common-obj-y += vl.o
|
||||||
|
vl.o-cflags := $(GPROF_CFLAGS) $(SDL_CFLAGS)
|
||||||
common-obj-y += tpm.o
|
common-obj-y += tpm.o
|
||||||
|
|
||||||
common-obj-$(CONFIG_SLIRP) += slirp/
|
common-obj-$(CONFIG_SLIRP) += slirp/
|
||||||
|
|||||||
@@ -16,19 +16,22 @@ QEMU_CFLAGS+=-I$(SRC_PATH)/include
|
|||||||
ifdef CONFIG_USER_ONLY
|
ifdef CONFIG_USER_ONLY
|
||||||
# user emulator name
|
# user emulator name
|
||||||
QEMU_PROG=qemu-$(TARGET_NAME)
|
QEMU_PROG=qemu-$(TARGET_NAME)
|
||||||
|
QEMU_PROG_BUILD = $(QEMU_PROG)
|
||||||
else
|
else
|
||||||
# system emulator name
|
# system emulator name
|
||||||
|
QEMU_PROG=qemu-system-$(TARGET_NAME)$(EXESUF)
|
||||||
ifneq (,$(findstring -mwindows,$(libs_softmmu)))
|
ifneq (,$(findstring -mwindows,$(libs_softmmu)))
|
||||||
# Terminate program name with a 'w' because the linker builds a windows executable.
|
# Terminate program name with a 'w' because the linker builds a windows executable.
|
||||||
QEMU_PROGW=qemu-system-$(TARGET_NAME)w$(EXESUF)
|
QEMU_PROGW=qemu-system-$(TARGET_NAME)w$(EXESUF)
|
||||||
endif # windows executable
|
$(QEMU_PROG): $(QEMU_PROGW)
|
||||||
QEMU_PROG=qemu-system-$(TARGET_NAME)$(EXESUF)
|
$(call quiet-command,$(OBJCOPY) --subsystem console $(QEMU_PROGW) $(QEMU_PROG)," GEN $(TARGET_DIR)$(QEMU_PROG)")
|
||||||
|
QEMU_PROG_BUILD = $(QEMU_PROGW)
|
||||||
|
else
|
||||||
|
QEMU_PROG_BUILD = $(QEMU_PROG)
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
PROGS=$(QEMU_PROG)
|
PROGS=$(QEMU_PROG) $(QEMU_PROGW)
|
||||||
ifdef QEMU_PROGW
|
|
||||||
PROGS+=$(QEMU_PROGW)
|
|
||||||
endif
|
|
||||||
STPFILES=
|
STPFILES=
|
||||||
|
|
||||||
config-target.h: config-target.h-timestamp
|
config-target.h: config-target.h-timestamp
|
||||||
@@ -120,8 +123,10 @@ obj-y += dump.o
|
|||||||
LIBS+=$(libs_softmmu)
|
LIBS+=$(libs_softmmu)
|
||||||
|
|
||||||
# xen support
|
# xen support
|
||||||
obj-$(CONFIG_XEN) += xen-all.o xen-mapcache.o
|
obj-$(CONFIG_XEN) += xen-common.o
|
||||||
obj-$(call lnot,$(CONFIG_XEN)) += xen-stub.o
|
obj-$(CONFIG_XEN_I386) += xen-hvm.o xen-mapcache.o
|
||||||
|
obj-$(call lnot,$(CONFIG_XEN)) += xen-common-stub.o
|
||||||
|
obj-$(call lnot,$(CONFIG_XEN_I386)) += xen-hvm-stub.o
|
||||||
|
|
||||||
# Hardware support
|
# Hardware support
|
||||||
ifeq ($(TARGET_NAME), sparc64)
|
ifeq ($(TARGET_NAME), sparc64)
|
||||||
@@ -138,10 +143,7 @@ endif # CONFIG_SOFTMMU
|
|||||||
%/translate.o: QEMU_CFLAGS += $(TRANSLATE_OPT_CFLAGS)
|
%/translate.o: QEMU_CFLAGS += $(TRANSLATE_OPT_CFLAGS)
|
||||||
|
|
||||||
dummy := $(call unnest-vars,,obj-y)
|
dummy := $(call unnest-vars,,obj-y)
|
||||||
|
all-obj-y := $(obj-y)
|
||||||
# we are making another call to unnest-vars with different vars, protect obj-y,
|
|
||||||
# it can be overriden in subdir Makefile.objs
|
|
||||||
obj-y-save := $(obj-y)
|
|
||||||
|
|
||||||
block-obj-y :=
|
block-obj-y :=
|
||||||
common-obj-y :=
|
common-obj-y :=
|
||||||
@@ -151,27 +153,16 @@ dummy := $(call unnest-vars,.., \
|
|||||||
block-obj-m \
|
block-obj-m \
|
||||||
common-obj-y \
|
common-obj-y \
|
||||||
common-obj-m)
|
common-obj-m)
|
||||||
|
all-obj-y += $(common-obj-y)
|
||||||
# Now restore obj-y
|
|
||||||
obj-y := $(obj-y-save)
|
|
||||||
|
|
||||||
all-obj-y = $(obj-y) $(common-obj-y)
|
|
||||||
all-obj-$(CONFIG_SOFTMMU) += $(block-obj-y)
|
all-obj-$(CONFIG_SOFTMMU) += $(block-obj-y)
|
||||||
|
|
||||||
ifndef CONFIG_HAIKU
|
ifndef CONFIG_HAIKU
|
||||||
LIBS+=-lm
|
LIBS+=-lm
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifdef QEMU_PROGW
|
# build either PROG or PROGW
|
||||||
# The linker builds a windows executable. Make also a console executable.
|
$(QEMU_PROG_BUILD): $(all-obj-y) ../libqemuutil.a ../libqemustub.a
|
||||||
$(QEMU_PROGW): $(all-obj-y) ../libqemuutil.a ../libqemustub.a
|
|
||||||
$(call LINK,$^)
|
$(call LINK,$^)
|
||||||
$(QEMU_PROG): $(QEMU_PROGW)
|
|
||||||
$(call quiet-command,$(OBJCOPY) --subsystem console $(QEMU_PROGW) $(QEMU_PROG)," GEN $(TARGET_DIR)$(QEMU_PROG)")
|
|
||||||
else
|
|
||||||
$(QEMU_PROG): $(all-obj-y) ../libqemuutil.a ../libqemustub.a
|
|
||||||
$(call LINK,$^)
|
|
||||||
endif
|
|
||||||
|
|
||||||
gdbstub-xml.c: $(TARGET_XML_FILES) $(SRC_PATH)/scripts/feature_to_c.sh
|
gdbstub-xml.c: $(TARGET_XML_FILES) $(SRC_PATH)/scripts/feature_to_c.sh
|
||||||
$(call quiet-command,rm -f $@ && $(SHELL) $(SRC_PATH)/scripts/feature_to_c.sh $@ $(TARGET_XML_FILES)," GEN $(TARGET_DIR)$@")
|
$(call quiet-command,rm -f $@ && $(SHELL) $(SRC_PATH)/scripts/feature_to_c.sh $@ $(TARGET_XML_FILES)," GEN $(TARGET_DIR)$@")
|
||||||
@@ -192,9 +183,9 @@ endif
|
|||||||
|
|
||||||
install: all
|
install: all
|
||||||
ifneq ($(PROGS),)
|
ifneq ($(PROGS),)
|
||||||
$(INSTALL) -m 755 $(PROGS) "$(DESTDIR)$(bindir)"
|
$(INSTALL_PROG) $(PROGS) "$(DESTDIR)$(bindir)"
|
||||||
ifneq ($(STRIP),)
|
ifneq ($(STRIP),)
|
||||||
$(STRIP) $(patsubst %,"$(DESTDIR)$(bindir)/%",$(PROGS))
|
$(STRIP) $(PROGS:%="$(DESTDIR)$(bindir)/%")
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
ifdef CONFIG_TRACE_SYSTEMTAP
|
ifdef CONFIG_TRACE_SYSTEMTAP
|
||||||
|
|||||||
214
arch_init.c
214
arch_init.c
@@ -45,6 +45,7 @@
|
|||||||
#include "hw/audio/pcspk.h"
|
#include "hw/audio/pcspk.h"
|
||||||
#include "migration/page_cache.h"
|
#include "migration/page_cache.h"
|
||||||
#include "qemu/config-file.h"
|
#include "qemu/config-file.h"
|
||||||
|
#include "qemu/error-report.h"
|
||||||
#include "qmp-commands.h"
|
#include "qmp-commands.h"
|
||||||
#include "trace.h"
|
#include "trace.h"
|
||||||
#include "exec/cpu-all.h"
|
#include "exec/cpu-all.h"
|
||||||
@@ -110,6 +111,8 @@ static bool mig_throttle_on;
|
|||||||
static int dirty_rate_high_cnt;
|
static int dirty_rate_high_cnt;
|
||||||
static void check_guest_throttling(void);
|
static void check_guest_throttling(void);
|
||||||
|
|
||||||
|
static uint64_t bitmap_sync_count;
|
||||||
|
|
||||||
/***********************************************************/
|
/***********************************************************/
|
||||||
/* ram save/restore */
|
/* ram save/restore */
|
||||||
|
|
||||||
@@ -167,11 +170,8 @@ static struct {
|
|||||||
/* Cache for XBZRLE, Protected by lock. */
|
/* Cache for XBZRLE, Protected by lock. */
|
||||||
PageCache *cache;
|
PageCache *cache;
|
||||||
QemuMutex lock;
|
QemuMutex lock;
|
||||||
} XBZRLE = {
|
} XBZRLE;
|
||||||
.encoded_buf = NULL,
|
|
||||||
.current_buf = NULL,
|
|
||||||
.cache = NULL,
|
|
||||||
};
|
|
||||||
/* buffer used for XBZRLE decoding */
|
/* buffer used for XBZRLE decoding */
|
||||||
static uint8_t *xbzrle_decoded_buf;
|
static uint8_t *xbzrle_decoded_buf;
|
||||||
|
|
||||||
@@ -187,41 +187,44 @@ static void XBZRLE_cache_unlock(void)
|
|||||||
qemu_mutex_unlock(&XBZRLE.lock);
|
qemu_mutex_unlock(&XBZRLE.lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* called from qmp_migrate_set_cache_size in main thread, possibly while
|
||||||
|
* a migration is in progress.
|
||||||
|
* A running migration maybe using the cache and might finish during this
|
||||||
|
* call, hence changes to the cache are protected by XBZRLE.lock().
|
||||||
|
*/
|
||||||
int64_t xbzrle_cache_resize(int64_t new_size)
|
int64_t xbzrle_cache_resize(int64_t new_size)
|
||||||
{
|
{
|
||||||
PageCache *new_cache, *cache_to_free;
|
PageCache *new_cache;
|
||||||
|
int64_t ret;
|
||||||
|
|
||||||
if (new_size < TARGET_PAGE_SIZE) {
|
if (new_size < TARGET_PAGE_SIZE) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* no need to lock, the current thread holds qemu big lock */
|
XBZRLE_cache_lock();
|
||||||
|
|
||||||
if (XBZRLE.cache != NULL) {
|
if (XBZRLE.cache != NULL) {
|
||||||
/* check XBZRLE.cache again later */
|
|
||||||
if (pow2floor(new_size) == migrate_xbzrle_cache_size()) {
|
if (pow2floor(new_size) == migrate_xbzrle_cache_size()) {
|
||||||
return pow2floor(new_size);
|
goto out_new_size;
|
||||||
}
|
}
|
||||||
new_cache = cache_init(new_size / TARGET_PAGE_SIZE,
|
new_cache = cache_init(new_size / TARGET_PAGE_SIZE,
|
||||||
TARGET_PAGE_SIZE);
|
TARGET_PAGE_SIZE);
|
||||||
if (!new_cache) {
|
if (!new_cache) {
|
||||||
DPRINTF("Error creating cache\n");
|
error_report("Error creating cache");
|
||||||
return -1;
|
ret = -1;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
XBZRLE_cache_lock();
|
cache_fini(XBZRLE.cache);
|
||||||
/* the XBZRLE.cache may have be destroyed, check it again */
|
XBZRLE.cache = new_cache;
|
||||||
if (XBZRLE.cache != NULL) {
|
|
||||||
cache_to_free = XBZRLE.cache;
|
|
||||||
XBZRLE.cache = new_cache;
|
|
||||||
} else {
|
|
||||||
cache_to_free = new_cache;
|
|
||||||
}
|
|
||||||
XBZRLE_cache_unlock();
|
|
||||||
|
|
||||||
cache_fini(cache_to_free);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return pow2floor(new_size);
|
out_new_size:
|
||||||
|
ret = pow2floor(new_size);
|
||||||
|
out:
|
||||||
|
XBZRLE_cache_unlock();
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* accounting for migration statistics */
|
/* accounting for migration statistics */
|
||||||
@@ -233,6 +236,7 @@ typedef struct AccountingInfo {
|
|||||||
uint64_t xbzrle_bytes;
|
uint64_t xbzrle_bytes;
|
||||||
uint64_t xbzrle_pages;
|
uint64_t xbzrle_pages;
|
||||||
uint64_t xbzrle_cache_miss;
|
uint64_t xbzrle_cache_miss;
|
||||||
|
double xbzrle_cache_miss_rate;
|
||||||
uint64_t xbzrle_overflows;
|
uint64_t xbzrle_overflows;
|
||||||
} AccountingInfo;
|
} AccountingInfo;
|
||||||
|
|
||||||
@@ -288,6 +292,11 @@ uint64_t xbzrle_mig_pages_cache_miss(void)
|
|||||||
return acct_info.xbzrle_cache_miss;
|
return acct_info.xbzrle_cache_miss;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double xbzrle_mig_cache_miss_rate(void)
|
||||||
|
{
|
||||||
|
return acct_info.xbzrle_cache_miss_rate;
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t xbzrle_mig_pages_overflow(void)
|
uint64_t xbzrle_mig_pages_overflow(void)
|
||||||
{
|
{
|
||||||
return acct_info.xbzrle_overflows;
|
return acct_info.xbzrle_overflows;
|
||||||
@@ -340,7 +349,7 @@ static void xbzrle_cache_zero_page(ram_addr_t current_addr)
|
|||||||
|
|
||||||
#define ENCODING_FLAG_XBZRLE 0x1
|
#define ENCODING_FLAG_XBZRLE 0x1
|
||||||
|
|
||||||
static int save_xbzrle_page(QEMUFile *f, uint8_t *current_data,
|
static int save_xbzrle_page(QEMUFile *f, uint8_t **current_data,
|
||||||
ram_addr_t current_addr, RAMBlock *block,
|
ram_addr_t current_addr, RAMBlock *block,
|
||||||
ram_addr_t offset, int cont, bool last_stage)
|
ram_addr_t offset, int cont, bool last_stage)
|
||||||
{
|
{
|
||||||
@@ -348,19 +357,23 @@ static int save_xbzrle_page(QEMUFile *f, uint8_t *current_data,
|
|||||||
uint8_t *prev_cached_page;
|
uint8_t *prev_cached_page;
|
||||||
|
|
||||||
if (!cache_is_cached(XBZRLE.cache, current_addr)) {
|
if (!cache_is_cached(XBZRLE.cache, current_addr)) {
|
||||||
|
acct_info.xbzrle_cache_miss++;
|
||||||
if (!last_stage) {
|
if (!last_stage) {
|
||||||
if (cache_insert(XBZRLE.cache, current_addr, current_data) == -1) {
|
if (cache_insert(XBZRLE.cache, current_addr, *current_data) == -1) {
|
||||||
return -1;
|
return -1;
|
||||||
|
} else {
|
||||||
|
/* update *current_data when the page has been
|
||||||
|
inserted into cache */
|
||||||
|
*current_data = get_cached_data(XBZRLE.cache, current_addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
acct_info.xbzrle_cache_miss++;
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
prev_cached_page = get_cached_data(XBZRLE.cache, current_addr);
|
prev_cached_page = get_cached_data(XBZRLE.cache, current_addr);
|
||||||
|
|
||||||
/* save current buffer into memory */
|
/* save current buffer into memory */
|
||||||
memcpy(XBZRLE.current_buf, current_data, TARGET_PAGE_SIZE);
|
memcpy(XBZRLE.current_buf, *current_data, TARGET_PAGE_SIZE);
|
||||||
|
|
||||||
/* XBZRLE encoding (if there is no overflow) */
|
/* XBZRLE encoding (if there is no overflow) */
|
||||||
encoded_len = xbzrle_encode_buffer(prev_cached_page, XBZRLE.current_buf,
|
encoded_len = xbzrle_encode_buffer(prev_cached_page, XBZRLE.current_buf,
|
||||||
@@ -373,7 +386,10 @@ static int save_xbzrle_page(QEMUFile *f, uint8_t *current_data,
|
|||||||
DPRINTF("Overflow\n");
|
DPRINTF("Overflow\n");
|
||||||
acct_info.xbzrle_overflows++;
|
acct_info.xbzrle_overflows++;
|
||||||
/* update data in the cache */
|
/* update data in the cache */
|
||||||
memcpy(prev_cached_page, current_data, TARGET_PAGE_SIZE);
|
if (!last_stage) {
|
||||||
|
memcpy(prev_cached_page, *current_data, TARGET_PAGE_SIZE);
|
||||||
|
*current_data = prev_cached_page;
|
||||||
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -479,6 +495,10 @@ static void migration_bitmap_sync(void)
|
|||||||
static int64_t num_dirty_pages_period;
|
static int64_t num_dirty_pages_period;
|
||||||
int64_t end_time;
|
int64_t end_time;
|
||||||
int64_t bytes_xfer_now;
|
int64_t bytes_xfer_now;
|
||||||
|
static uint64_t xbzrle_cache_miss_prev;
|
||||||
|
static uint64_t iterations_prev;
|
||||||
|
|
||||||
|
bitmap_sync_count++;
|
||||||
|
|
||||||
if (!bytes_xfer_prev) {
|
if (!bytes_xfer_prev) {
|
||||||
bytes_xfer_prev = ram_bytes_transferred();
|
bytes_xfer_prev = ram_bytes_transferred();
|
||||||
@@ -520,11 +540,22 @@ static void migration_bitmap_sync(void)
|
|||||||
} else {
|
} else {
|
||||||
mig_throttle_on = false;
|
mig_throttle_on = false;
|
||||||
}
|
}
|
||||||
|
if (migrate_use_xbzrle()) {
|
||||||
|
if (iterations_prev != 0) {
|
||||||
|
acct_info.xbzrle_cache_miss_rate =
|
||||||
|
(double)(acct_info.xbzrle_cache_miss -
|
||||||
|
xbzrle_cache_miss_prev) /
|
||||||
|
(acct_info.iterations - iterations_prev);
|
||||||
|
}
|
||||||
|
iterations_prev = acct_info.iterations;
|
||||||
|
xbzrle_cache_miss_prev = acct_info.xbzrle_cache_miss;
|
||||||
|
}
|
||||||
s->dirty_pages_rate = num_dirty_pages_period * 1000
|
s->dirty_pages_rate = num_dirty_pages_period * 1000
|
||||||
/ (end_time - start_time);
|
/ (end_time - start_time);
|
||||||
s->dirty_bytes_rate = s->dirty_pages_rate * TARGET_PAGE_SIZE;
|
s->dirty_bytes_rate = s->dirty_pages_rate * TARGET_PAGE_SIZE;
|
||||||
start_time = end_time;
|
start_time = end_time;
|
||||||
num_dirty_pages_period = 0;
|
num_dirty_pages_period = 0;
|
||||||
|
s->dirty_sync_count = bitmap_sync_count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -598,15 +629,9 @@ static int ram_save_block(QEMUFile *f, bool last_stage)
|
|||||||
*/
|
*/
|
||||||
xbzrle_cache_zero_page(current_addr);
|
xbzrle_cache_zero_page(current_addr);
|
||||||
} else if (!ram_bulk_stage && migrate_use_xbzrle()) {
|
} else if (!ram_bulk_stage && migrate_use_xbzrle()) {
|
||||||
bytes_sent = save_xbzrle_page(f, p, current_addr, block,
|
bytes_sent = save_xbzrle_page(f, &p, current_addr, block,
|
||||||
offset, cont, last_stage);
|
offset, cont, last_stage);
|
||||||
if (!last_stage) {
|
if (!last_stage) {
|
||||||
/* We must send exactly what's in the xbzrle cache
|
|
||||||
* even if the page wasn't xbzrle compressed, so that
|
|
||||||
* it's right next time.
|
|
||||||
*/
|
|
||||||
p = get_cached_data(XBZRLE.cache, current_addr);
|
|
||||||
|
|
||||||
/* Can't send this cached data async, since the cache page
|
/* Can't send this cached data async, since the cache page
|
||||||
* might get updated before it gets to the wire
|
* might get updated before it gets to the wire
|
||||||
*/
|
*/
|
||||||
@@ -726,37 +751,34 @@ static void reset_ram_globals(void)
|
|||||||
static int ram_save_setup(QEMUFile *f, void *opaque)
|
static int ram_save_setup(QEMUFile *f, void *opaque)
|
||||||
{
|
{
|
||||||
RAMBlock *block;
|
RAMBlock *block;
|
||||||
int64_t ram_pages = last_ram_offset() >> TARGET_PAGE_BITS;
|
int64_t ram_bitmap_pages; /* Size of bitmap in pages, including gaps */
|
||||||
|
|
||||||
migration_bitmap = bitmap_new(ram_pages);
|
|
||||||
bitmap_set(migration_bitmap, 0, ram_pages);
|
|
||||||
migration_dirty_pages = ram_pages;
|
|
||||||
mig_throttle_on = false;
|
mig_throttle_on = false;
|
||||||
dirty_rate_high_cnt = 0;
|
dirty_rate_high_cnt = 0;
|
||||||
|
bitmap_sync_count = 0;
|
||||||
|
|
||||||
if (migrate_use_xbzrle()) {
|
if (migrate_use_xbzrle()) {
|
||||||
qemu_mutex_lock_iothread();
|
XBZRLE_cache_lock();
|
||||||
XBZRLE.cache = cache_init(migrate_xbzrle_cache_size() /
|
XBZRLE.cache = cache_init(migrate_xbzrle_cache_size() /
|
||||||
TARGET_PAGE_SIZE,
|
TARGET_PAGE_SIZE,
|
||||||
TARGET_PAGE_SIZE);
|
TARGET_PAGE_SIZE);
|
||||||
if (!XBZRLE.cache) {
|
if (!XBZRLE.cache) {
|
||||||
qemu_mutex_unlock_iothread();
|
XBZRLE_cache_unlock();
|
||||||
DPRINTF("Error creating cache\n");
|
error_report("Error creating cache");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
qemu_mutex_init(&XBZRLE.lock);
|
XBZRLE_cache_unlock();
|
||||||
qemu_mutex_unlock_iothread();
|
|
||||||
|
|
||||||
/* We prefer not to abort if there is no memory */
|
/* We prefer not to abort if there is no memory */
|
||||||
XBZRLE.encoded_buf = g_try_malloc0(TARGET_PAGE_SIZE);
|
XBZRLE.encoded_buf = g_try_malloc0(TARGET_PAGE_SIZE);
|
||||||
if (!XBZRLE.encoded_buf) {
|
if (!XBZRLE.encoded_buf) {
|
||||||
DPRINTF("Error allocating encoded_buf\n");
|
error_report("Error allocating encoded_buf");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
XBZRLE.current_buf = g_try_malloc(TARGET_PAGE_SIZE);
|
XBZRLE.current_buf = g_try_malloc(TARGET_PAGE_SIZE);
|
||||||
if (!XBZRLE.current_buf) {
|
if (!XBZRLE.current_buf) {
|
||||||
DPRINTF("Error allocating current_buf\n");
|
error_report("Error allocating current_buf");
|
||||||
g_free(XBZRLE.encoded_buf);
|
g_free(XBZRLE.encoded_buf);
|
||||||
XBZRLE.encoded_buf = NULL;
|
XBZRLE.encoded_buf = NULL;
|
||||||
return -1;
|
return -1;
|
||||||
@@ -770,6 +792,22 @@ static int ram_save_setup(QEMUFile *f, void *opaque)
|
|||||||
bytes_transferred = 0;
|
bytes_transferred = 0;
|
||||||
reset_ram_globals();
|
reset_ram_globals();
|
||||||
|
|
||||||
|
ram_bitmap_pages = last_ram_offset() >> TARGET_PAGE_BITS;
|
||||||
|
migration_bitmap = bitmap_new(ram_bitmap_pages);
|
||||||
|
bitmap_set(migration_bitmap, 0, ram_bitmap_pages);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Count the total number of pages used by ram blocks not including any
|
||||||
|
* gaps due to alignment or unplugs.
|
||||||
|
*/
|
||||||
|
migration_dirty_pages = 0;
|
||||||
|
QTAILQ_FOREACH(block, &ram_list.blocks, next) {
|
||||||
|
uint64_t block_pages;
|
||||||
|
|
||||||
|
block_pages = block->length >> TARGET_PAGE_BITS;
|
||||||
|
migration_dirty_pages += block_pages;
|
||||||
|
}
|
||||||
|
|
||||||
memory_global_dirty_log_start();
|
memory_global_dirty_log_start();
|
||||||
migration_bitmap_sync();
|
migration_bitmap_sync();
|
||||||
qemu_mutex_unlock_iothread();
|
qemu_mutex_unlock_iothread();
|
||||||
@@ -997,8 +1035,9 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id)
|
|||||||
|
|
||||||
seq_iter++;
|
seq_iter++;
|
||||||
|
|
||||||
if (version_id < 4 || version_id > 4) {
|
if (version_id != 4) {
|
||||||
return -EINVAL;
|
ret = -EINVAL;
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
@@ -1008,44 +1047,42 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id)
|
|||||||
addr &= TARGET_PAGE_MASK;
|
addr &= TARGET_PAGE_MASK;
|
||||||
|
|
||||||
if (flags & RAM_SAVE_FLAG_MEM_SIZE) {
|
if (flags & RAM_SAVE_FLAG_MEM_SIZE) {
|
||||||
if (version_id == 4) {
|
/* Synchronize RAM block list */
|
||||||
/* Synchronize RAM block list */
|
char id[256];
|
||||||
char id[256];
|
ram_addr_t length;
|
||||||
ram_addr_t length;
|
ram_addr_t total_ram_bytes = addr;
|
||||||
ram_addr_t total_ram_bytes = addr;
|
|
||||||
|
|
||||||
while (total_ram_bytes) {
|
while (total_ram_bytes) {
|
||||||
RAMBlock *block;
|
RAMBlock *block;
|
||||||
uint8_t len;
|
uint8_t len;
|
||||||
|
|
||||||
len = qemu_get_byte(f);
|
len = qemu_get_byte(f);
|
||||||
qemu_get_buffer(f, (uint8_t *)id, len);
|
qemu_get_buffer(f, (uint8_t *)id, len);
|
||||||
id[len] = 0;
|
id[len] = 0;
|
||||||
length = qemu_get_be64(f);
|
length = qemu_get_be64(f);
|
||||||
|
|
||||||
QTAILQ_FOREACH(block, &ram_list.blocks, next) {
|
QTAILQ_FOREACH(block, &ram_list.blocks, next) {
|
||||||
if (!strncmp(id, block->idstr, sizeof(id))) {
|
if (!strncmp(id, block->idstr, sizeof(id))) {
|
||||||
if (block->length != length) {
|
if (block->length != length) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Length mismatch: %s: " RAM_ADDR_FMT
|
"Length mismatch: %s: " RAM_ADDR_FMT
|
||||||
" in != " RAM_ADDR_FMT "\n", id, length,
|
" in != " RAM_ADDR_FMT "\n", id, length,
|
||||||
block->length);
|
block->length);
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!block) {
|
|
||||||
fprintf(stderr, "Unknown ramblock \"%s\", cannot "
|
|
||||||
"accept migration\n", id);
|
|
||||||
ret = -EINVAL;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
total_ram_bytes -= length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!block) {
|
||||||
|
fprintf(stderr, "Unknown ramblock \"%s\", cannot "
|
||||||
|
"accept migration\n", id);
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
total_ram_bytes -= length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1055,7 +1092,8 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id)
|
|||||||
|
|
||||||
host = host_from_stream_offset(f, addr, flags);
|
host = host_from_stream_offset(f, addr, flags);
|
||||||
if (!host) {
|
if (!host) {
|
||||||
return -EINVAL;
|
ret = -EINVAL;
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
ch = qemu_get_byte(f);
|
ch = qemu_get_byte(f);
|
||||||
@@ -1065,14 +1103,16 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id)
|
|||||||
|
|
||||||
host = host_from_stream_offset(f, addr, flags);
|
host = host_from_stream_offset(f, addr, flags);
|
||||||
if (!host) {
|
if (!host) {
|
||||||
return -EINVAL;
|
ret = -EINVAL;
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
qemu_get_buffer(f, host, TARGET_PAGE_SIZE);
|
qemu_get_buffer(f, host, TARGET_PAGE_SIZE);
|
||||||
} else if (flags & RAM_SAVE_FLAG_XBZRLE) {
|
} else if (flags & RAM_SAVE_FLAG_XBZRLE) {
|
||||||
void *host = host_from_stream_offset(f, addr, flags);
|
void *host = host_from_stream_offset(f, addr, flags);
|
||||||
if (!host) {
|
if (!host) {
|
||||||
return -EINVAL;
|
ret = -EINVAL;
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (load_xbzrle(f, addr, host) < 0) {
|
if (load_xbzrle(f, addr, host) < 0) {
|
||||||
@@ -1095,7 +1135,7 @@ done:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
SaveVMHandlers savevm_ram_handlers = {
|
static SaveVMHandlers savevm_ram_handlers = {
|
||||||
.save_live_setup = ram_save_setup,
|
.save_live_setup = ram_save_setup,
|
||||||
.save_live_iterate = ram_save_iterate,
|
.save_live_iterate = ram_save_iterate,
|
||||||
.save_live_complete = ram_save_complete,
|
.save_live_complete = ram_save_complete,
|
||||||
@@ -1104,6 +1144,12 @@ SaveVMHandlers savevm_ram_handlers = {
|
|||||||
.cancel = ram_migration_cancel,
|
.cancel = ram_migration_cancel,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void ram_mig_init(void)
|
||||||
|
{
|
||||||
|
qemu_mutex_init(&XBZRLE.lock);
|
||||||
|
register_savevm_live(NULL, "ram", 0, 4, &savevm_ram_handlers, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
struct soundhw {
|
struct soundhw {
|
||||||
const char *name;
|
const char *name;
|
||||||
const char *descr;
|
const char *descr;
|
||||||
|
|||||||
@@ -14,4 +14,4 @@ common-obj-$(CONFIG_AUDIO_WIN_INT) += audio_win_int.o
|
|||||||
common-obj-y += wavcapture.o
|
common-obj-y += wavcapture.o
|
||||||
|
|
||||||
$(obj)/audio.o $(obj)/fmodaudio.o: QEMU_CFLAGS += $(FMOD_CFLAGS)
|
$(obj)/audio.o $(obj)/fmodaudio.o: QEMU_CFLAGS += $(FMOD_CFLAGS)
|
||||||
$(obj)/sdlaudio.o: QEMU_CFLAGS += $(SDL_CFLAGS)
|
sdlaudio.o-cflags := $(SDL_CFLAGS)
|
||||||
|
|||||||
@@ -3,6 +3,6 @@ common-obj-$(CONFIG_POSIX) += rng-random.o
|
|||||||
|
|
||||||
common-obj-y += msmouse.o
|
common-obj-y += msmouse.o
|
||||||
common-obj-$(CONFIG_BRLAPI) += baum.o
|
common-obj-$(CONFIG_BRLAPI) += baum.o
|
||||||
$(obj)/baum.o: QEMU_CFLAGS += $(SDL_CFLAGS)
|
baum.o-cflags := $(SDL_CFLAGS)
|
||||||
|
|
||||||
common-obj-$(CONFIG_TPM) += tpm.o
|
common-obj-$(CONFIG_TPM) += tpm.o
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ static void rng_backend_prop_set_opened(Object *obj, bool value, Error **errp)
|
|||||||
{
|
{
|
||||||
RngBackend *s = RNG_BACKEND(obj);
|
RngBackend *s = RNG_BACKEND(obj);
|
||||||
RngBackendClass *k = RNG_BACKEND_GET_CLASS(s);
|
RngBackendClass *k = RNG_BACKEND_GET_CLASS(s);
|
||||||
|
Error *local_err = NULL;
|
||||||
|
|
||||||
if (value == s->opened) {
|
if (value == s->opened) {
|
||||||
return;
|
return;
|
||||||
@@ -61,12 +62,14 @@ static void rng_backend_prop_set_opened(Object *obj, bool value, Error **errp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (k->opened) {
|
if (k->opened) {
|
||||||
k->opened(s, errp);
|
k->opened(s, &local_err);
|
||||||
|
if (local_err) {
|
||||||
|
error_propagate(errp, local_err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!error_is_set(errp)) {
|
s->opened = true;
|
||||||
s->opened = value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rng_backend_init(Object *obj)
|
static void rng_backend_init(Object *obj)
|
||||||
|
|||||||
@@ -112,6 +112,7 @@ static void tpm_backend_prop_set_opened(Object *obj, bool value, Error **errp)
|
|||||||
{
|
{
|
||||||
TPMBackend *s = TPM_BACKEND(obj);
|
TPMBackend *s = TPM_BACKEND(obj);
|
||||||
TPMBackendClass *k = TPM_BACKEND_GET_CLASS(s);
|
TPMBackendClass *k = TPM_BACKEND_GET_CLASS(s);
|
||||||
|
Error *local_err = NULL;
|
||||||
|
|
||||||
if (value == s->opened) {
|
if (value == s->opened) {
|
||||||
return;
|
return;
|
||||||
@@ -123,12 +124,14 @@ static void tpm_backend_prop_set_opened(Object *obj, bool value, Error **errp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (k->opened) {
|
if (k->opened) {
|
||||||
k->opened(s, errp);
|
k->opened(s, &local_err);
|
||||||
|
if (local_err) {
|
||||||
|
error_propagate(errp, local_err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!error_is_set(errp)) {
|
s->opened = true;
|
||||||
s->opened = value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tpm_backend_instance_init(Object *obj)
|
static void tpm_backend_instance_init(Object *obj)
|
||||||
|
|||||||
34
block.c
34
block.c
@@ -774,6 +774,16 @@ void bdrv_disable_copy_on_read(BlockDriverState *bs)
|
|||||||
bs->copy_on_read--;
|
bs->copy_on_read--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the flags that a temporary snapshot should get, based on the
|
||||||
|
* originally requested flags (the originally requested image will have flags
|
||||||
|
* like a backing file)
|
||||||
|
*/
|
||||||
|
static int bdrv_temp_snapshot_flags(int flags)
|
||||||
|
{
|
||||||
|
return (flags & ~BDRV_O_SNAPSHOT) | BDRV_O_TEMPORARY;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns the flags that bs->file should get, based on the given flags for
|
* Returns the flags that bs->file should get, based on the given flags for
|
||||||
* the parent BDS
|
* the parent BDS
|
||||||
@@ -787,11 +797,6 @@ static int bdrv_inherited_flags(int flags)
|
|||||||
* so we can enable both unconditionally on lower layers. */
|
* so we can enable both unconditionally on lower layers. */
|
||||||
flags |= BDRV_O_CACHE_WB | BDRV_O_UNMAP;
|
flags |= BDRV_O_CACHE_WB | BDRV_O_UNMAP;
|
||||||
|
|
||||||
/* The backing file of a temporary snapshot is read-only */
|
|
||||||
if (flags & BDRV_O_SNAPSHOT) {
|
|
||||||
flags &= ~BDRV_O_RDWR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear flags that only apply to the top layer */
|
/* Clear flags that only apply to the top layer */
|
||||||
flags &= ~(BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING | BDRV_O_COPY_ON_READ);
|
flags &= ~(BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING | BDRV_O_COPY_ON_READ);
|
||||||
|
|
||||||
@@ -817,11 +822,6 @@ static int bdrv_open_flags(BlockDriverState *bs, int flags)
|
|||||||
{
|
{
|
||||||
int open_flags = flags | BDRV_O_CACHE_WB;
|
int open_flags = flags | BDRV_O_CACHE_WB;
|
||||||
|
|
||||||
/* The backing file of a temporary snapshot is read-only */
|
|
||||||
if (flags & BDRV_O_SNAPSHOT) {
|
|
||||||
open_flags &= ~BDRV_O_RDWR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Clear flags that are internal to the block layer before opening the
|
* Clear flags that are internal to the block layer before opening the
|
||||||
* image.
|
* image.
|
||||||
@@ -1206,7 +1206,7 @@ done:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bdrv_append_temp_snapshot(BlockDriverState *bs, Error **errp)
|
void bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, Error **errp)
|
||||||
{
|
{
|
||||||
/* TODO: extra byte is a hack to ensure MAX_PATH space on Windows. */
|
/* TODO: extra byte is a hack to ensure MAX_PATH space on Windows. */
|
||||||
char *tmp_filename = g_malloc0(PATH_MAX + 1);
|
char *tmp_filename = g_malloc0(PATH_MAX + 1);
|
||||||
@@ -1262,8 +1262,7 @@ void bdrv_append_temp_snapshot(BlockDriverState *bs, Error **errp)
|
|||||||
bs_snapshot = bdrv_new("", &error_abort);
|
bs_snapshot = bdrv_new("", &error_abort);
|
||||||
|
|
||||||
ret = bdrv_open(&bs_snapshot, NULL, NULL, snapshot_options,
|
ret = bdrv_open(&bs_snapshot, NULL, NULL, snapshot_options,
|
||||||
(bs->open_flags & ~BDRV_O_SNAPSHOT) | BDRV_O_TEMPORARY,
|
flags, bdrv_qcow2, &local_err);
|
||||||
bdrv_qcow2, &local_err);
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
error_propagate(errp, local_err);
|
error_propagate(errp, local_err);
|
||||||
goto out;
|
goto out;
|
||||||
@@ -1298,6 +1297,7 @@ int bdrv_open(BlockDriverState **pbs, const char *filename,
|
|||||||
BlockDriverState *file = NULL, *bs;
|
BlockDriverState *file = NULL, *bs;
|
||||||
const char *drvname;
|
const char *drvname;
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
|
int snapshot_flags = 0;
|
||||||
|
|
||||||
assert(pbs);
|
assert(pbs);
|
||||||
|
|
||||||
@@ -1358,6 +1358,10 @@ int bdrv_open(BlockDriverState **pbs, const char *filename,
|
|||||||
if (flags & BDRV_O_RDWR) {
|
if (flags & BDRV_O_RDWR) {
|
||||||
flags |= BDRV_O_ALLOW_RDWR;
|
flags |= BDRV_O_ALLOW_RDWR;
|
||||||
}
|
}
|
||||||
|
if (flags & BDRV_O_SNAPSHOT) {
|
||||||
|
snapshot_flags = bdrv_temp_snapshot_flags(flags);
|
||||||
|
flags = bdrv_backing_flags(flags);
|
||||||
|
}
|
||||||
|
|
||||||
assert(file == NULL);
|
assert(file == NULL);
|
||||||
ret = bdrv_open_image(&file, filename, options, "file",
|
ret = bdrv_open_image(&file, filename, options, "file",
|
||||||
@@ -1417,8 +1421,8 @@ int bdrv_open(BlockDriverState **pbs, const char *filename,
|
|||||||
|
|
||||||
/* For snapshot=on, create a temporary qcow2 overlay. bs points to the
|
/* For snapshot=on, create a temporary qcow2 overlay. bs points to the
|
||||||
* temporary snapshot afterwards. */
|
* temporary snapshot afterwards. */
|
||||||
if (flags & BDRV_O_SNAPSHOT) {
|
if (snapshot_flags) {
|
||||||
bdrv_append_temp_snapshot(bs, &local_err);
|
bdrv_append_temp_snapshot(bs, snapshot_flags, &local_err);
|
||||||
if (local_err) {
|
if (local_err) {
|
||||||
error_propagate(errp, local_err);
|
error_propagate(errp, local_err);
|
||||||
goto close_and_fail;
|
goto close_and_fail;
|
||||||
|
|||||||
@@ -207,6 +207,11 @@ static struct glfs *qemu_gluster_init(GlusterConf *gconf, const char *filename,
|
|||||||
"volume=%s image=%s transport=%s", gconf->server,
|
"volume=%s image=%s transport=%s", gconf->server,
|
||||||
gconf->port, gconf->volname, gconf->image,
|
gconf->port, gconf->volname, gconf->image,
|
||||||
gconf->transport);
|
gconf->transport);
|
||||||
|
|
||||||
|
/* glfs_init sometimes doesn't set errno although docs suggest that */
|
||||||
|
if (errno == 0)
|
||||||
|
errno = EINVAL;
|
||||||
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
return glfs;
|
return glfs;
|
||||||
@@ -482,7 +487,7 @@ static int qemu_gluster_create(const char *filename,
|
|||||||
|
|
||||||
glfs = qemu_gluster_init(gconf, filename, errp);
|
glfs = qemu_gluster_init(gconf, filename, errp);
|
||||||
if (!glfs) {
|
if (!glfs) {
|
||||||
ret = -EINVAL;
|
ret = -errno;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* QEMU Block driver for iSCSI images
|
* QEMU Block driver for iSCSI images
|
||||||
*
|
*
|
||||||
* Copyright (c) 2010-2011 Ronnie Sahlberg <ronniesahlberg@gmail.com>
|
* Copyright (c) 2010-2011 Ronnie Sahlberg <ronniesahlberg@gmail.com>
|
||||||
* Copyright (c) 2012-2013 Peter Lieven <pl@kamp.de>
|
* Copyright (c) 2012-2014 Peter Lieven <pl@kamp.de>
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -256,6 +256,10 @@ static int64_t nfs_client_open(NFSClient *client, const char *filename,
|
|||||||
error_setg(errp, "Invalid URL specified");
|
error_setg(errp, "Invalid URL specified");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
if (!uri->server) {
|
||||||
|
error_setg(errp, "Invalid URL specified");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
strp = strrchr(uri->path, '/');
|
strp = strrchr(uri->path, '/');
|
||||||
if (strp == NULL) {
|
if (strp == NULL) {
|
||||||
error_setg(errp, "Invalid URL specified");
|
error_setg(errp, "Invalid URL specified");
|
||||||
|
|||||||
@@ -656,7 +656,9 @@ retry:
|
|||||||
|
|
||||||
/* Make sure that all offsets in the "allocated" range are representable
|
/* Make sure that all offsets in the "allocated" range are representable
|
||||||
* in an int64_t */
|
* in an int64_t */
|
||||||
if (s->free_cluster_index - 1 > (INT64_MAX >> s->cluster_bits)) {
|
if (s->free_cluster_index > 0 &&
|
||||||
|
s->free_cluster_index - 1 > (INT64_MAX >> s->cluster_bits))
|
||||||
|
{
|
||||||
return -EFBIG;
|
return -EFBIG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -146,6 +146,9 @@ typedef struct BDRVRawState {
|
|||||||
bool has_discard:1;
|
bool has_discard:1;
|
||||||
bool has_write_zeroes:1;
|
bool has_write_zeroes:1;
|
||||||
bool discard_zeroes:1;
|
bool discard_zeroes:1;
|
||||||
|
#ifdef CONFIG_FIEMAP
|
||||||
|
bool skip_fiemap;
|
||||||
|
#endif
|
||||||
} BDRVRawState;
|
} BDRVRawState;
|
||||||
|
|
||||||
typedef struct BDRVRawReopenState {
|
typedef struct BDRVRawReopenState {
|
||||||
@@ -1272,6 +1275,83 @@ static int raw_create(const char *filename, QEMUOptionParameter *options,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int64_t try_fiemap(BlockDriverState *bs, off_t start, off_t *data,
|
||||||
|
off_t *hole, int nb_sectors, int *pnum)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_FIEMAP
|
||||||
|
BDRVRawState *s = bs->opaque;
|
||||||
|
int64_t ret = BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID | start;
|
||||||
|
struct {
|
||||||
|
struct fiemap fm;
|
||||||
|
struct fiemap_extent fe;
|
||||||
|
} f;
|
||||||
|
|
||||||
|
if (s->skip_fiemap) {
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
f.fm.fm_start = start;
|
||||||
|
f.fm.fm_length = (int64_t)nb_sectors * BDRV_SECTOR_SIZE;
|
||||||
|
f.fm.fm_flags = 0;
|
||||||
|
f.fm.fm_extent_count = 1;
|
||||||
|
f.fm.fm_reserved = 0;
|
||||||
|
if (ioctl(s->fd, FS_IOC_FIEMAP, &f) == -1) {
|
||||||
|
s->skip_fiemap = true;
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (f.fm.fm_mapped_extents == 0) {
|
||||||
|
/* No extents found, data is beyond f.fm.fm_start + f.fm.fm_length.
|
||||||
|
* f.fm.fm_start + f.fm.fm_length must be clamped to the file size!
|
||||||
|
*/
|
||||||
|
off_t length = lseek(s->fd, 0, SEEK_END);
|
||||||
|
*hole = f.fm.fm_start;
|
||||||
|
*data = MIN(f.fm.fm_start + f.fm.fm_length, length);
|
||||||
|
} else {
|
||||||
|
*data = f.fe.fe_logical;
|
||||||
|
*hole = f.fe.fe_logical + f.fe.fe_length;
|
||||||
|
if (f.fe.fe_flags & FIEMAP_EXTENT_UNWRITTEN) {
|
||||||
|
ret |= BDRV_BLOCK_ZERO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
#else
|
||||||
|
return -ENOTSUP;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static int64_t try_seek_hole(BlockDriverState *bs, off_t start, off_t *data,
|
||||||
|
off_t *hole, int *pnum)
|
||||||
|
{
|
||||||
|
#if defined SEEK_HOLE && defined SEEK_DATA
|
||||||
|
BDRVRawState *s = bs->opaque;
|
||||||
|
|
||||||
|
*hole = lseek(s->fd, start, SEEK_HOLE);
|
||||||
|
if (*hole == -1) {
|
||||||
|
/* -ENXIO indicates that sector_num was past the end of the file.
|
||||||
|
* There is a virtual hole there. */
|
||||||
|
assert(errno != -ENXIO);
|
||||||
|
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*hole > start) {
|
||||||
|
*data = start;
|
||||||
|
} else {
|
||||||
|
/* On a hole. We need another syscall to find its end. */
|
||||||
|
*data = lseek(s->fd, start, SEEK_DATA);
|
||||||
|
if (*data == -1) {
|
||||||
|
*data = lseek(s->fd, 0, SEEK_END);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID | start;
|
||||||
|
#else
|
||||||
|
return -ENOTSUP;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns true iff the specified sector is present in the disk image. Drivers
|
* Returns true iff the specified sector is present in the disk image. Drivers
|
||||||
* not implementing the functionality are assumed to not support backing files,
|
* not implementing the functionality are assumed to not support backing files,
|
||||||
@@ -1288,10 +1368,10 @@ static int raw_create(const char *filename, QEMUOptionParameter *options,
|
|||||||
* beyond the end of the disk image it will be clamped.
|
* beyond the end of the disk image it will be clamped.
|
||||||
*/
|
*/
|
||||||
static int64_t coroutine_fn raw_co_get_block_status(BlockDriverState *bs,
|
static int64_t coroutine_fn raw_co_get_block_status(BlockDriverState *bs,
|
||||||
int64_t sector_num,
|
int64_t sector_num,
|
||||||
int nb_sectors, int *pnum)
|
int nb_sectors, int *pnum)
|
||||||
{
|
{
|
||||||
off_t start, data, hole;
|
off_t start, data = 0, hole = 0;
|
||||||
int64_t ret;
|
int64_t ret;
|
||||||
|
|
||||||
ret = fd_open(bs);
|
ret = fd_open(bs);
|
||||||
@@ -1300,71 +1380,18 @@ static int64_t coroutine_fn raw_co_get_block_status(BlockDriverState *bs,
|
|||||||
}
|
}
|
||||||
|
|
||||||
start = sector_num * BDRV_SECTOR_SIZE;
|
start = sector_num * BDRV_SECTOR_SIZE;
|
||||||
ret = BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID | start;
|
|
||||||
|
|
||||||
#ifdef CONFIG_FIEMAP
|
ret = try_fiemap(bs, start, &data, &hole, nb_sectors, pnum);
|
||||||
|
if (ret < 0) {
|
||||||
BDRVRawState *s = bs->opaque;
|
ret = try_seek_hole(bs, start, &data, &hole, pnum);
|
||||||
struct {
|
if (ret < 0) {
|
||||||
struct fiemap fm;
|
/* Assume everything is allocated. */
|
||||||
struct fiemap_extent fe;
|
data = 0;
|
||||||
} f;
|
hole = start + nb_sectors * BDRV_SECTOR_SIZE;
|
||||||
|
ret = BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID | start;
|
||||||
f.fm.fm_start = start;
|
|
||||||
f.fm.fm_length = (int64_t)nb_sectors * BDRV_SECTOR_SIZE;
|
|
||||||
f.fm.fm_flags = 0;
|
|
||||||
f.fm.fm_extent_count = 1;
|
|
||||||
f.fm.fm_reserved = 0;
|
|
||||||
if (ioctl(s->fd, FS_IOC_FIEMAP, &f) == -1) {
|
|
||||||
/* Assume everything is allocated. */
|
|
||||||
*pnum = nb_sectors;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (f.fm.fm_mapped_extents == 0) {
|
|
||||||
/* No extents found, data is beyond f.fm.fm_start + f.fm.fm_length.
|
|
||||||
* f.fm.fm_start + f.fm.fm_length must be clamped to the file size!
|
|
||||||
*/
|
|
||||||
off_t length = lseek(s->fd, 0, SEEK_END);
|
|
||||||
hole = f.fm.fm_start;
|
|
||||||
data = MIN(f.fm.fm_start + f.fm.fm_length, length);
|
|
||||||
} else {
|
|
||||||
data = f.fe.fe_logical;
|
|
||||||
hole = f.fe.fe_logical + f.fe.fe_length;
|
|
||||||
if (f.fe.fe_flags & FIEMAP_EXTENT_UNWRITTEN) {
|
|
||||||
ret |= BDRV_BLOCK_ZERO;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined SEEK_HOLE && defined SEEK_DATA
|
|
||||||
|
|
||||||
BDRVRawState *s = bs->opaque;
|
|
||||||
|
|
||||||
hole = lseek(s->fd, start, SEEK_HOLE);
|
|
||||||
if (hole == -1) {
|
|
||||||
/* -ENXIO indicates that sector_num was past the end of the file.
|
|
||||||
* There is a virtual hole there. */
|
|
||||||
assert(errno != -ENXIO);
|
|
||||||
|
|
||||||
/* Most likely EINVAL. Assume everything is allocated. */
|
|
||||||
*pnum = nb_sectors;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hole > start) {
|
|
||||||
data = start;
|
|
||||||
} else {
|
|
||||||
/* On a hole. We need another syscall to find its end. */
|
|
||||||
data = lseek(s->fd, start, SEEK_DATA);
|
|
||||||
if (data == -1) {
|
|
||||||
data = lseek(s->fd, 0, SEEK_END);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
data = 0;
|
|
||||||
hole = start + nb_sectors * BDRV_SECTOR_SIZE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (data <= start) {
|
if (data <= start) {
|
||||||
/* On a data extent, compute sectors to the end of the extent. */
|
/* On a data extent, compute sectors to the end of the extent. */
|
||||||
*pnum = MIN(nb_sectors, (hole - start) / BDRV_SECTOR_SIZE);
|
*pnum = MIN(nb_sectors, (hole - start) / BDRV_SECTOR_SIZE);
|
||||||
|
|||||||
35
block/vmdk.c
35
block/vmdk.c
@@ -1496,6 +1496,19 @@ static coroutine_fn int vmdk_co_write(BlockDriverState *bs, int64_t sector_num,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int vmdk_write_compressed(BlockDriverState *bs,
|
||||||
|
int64_t sector_num,
|
||||||
|
const uint8_t *buf,
|
||||||
|
int nb_sectors)
|
||||||
|
{
|
||||||
|
BDRVVmdkState *s = bs->opaque;
|
||||||
|
if (s->num_extents == 1 && s->extents[0].compressed) {
|
||||||
|
return vmdk_write(bs, sector_num, buf, nb_sectors, false, false);
|
||||||
|
} else {
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int coroutine_fn vmdk_co_write_zeroes(BlockDriverState *bs,
|
static int coroutine_fn vmdk_co_write_zeroes(BlockDriverState *bs,
|
||||||
int64_t sector_num,
|
int64_t sector_num,
|
||||||
int nb_sectors,
|
int nb_sectors,
|
||||||
@@ -2063,6 +2076,26 @@ static ImageInfoSpecific *vmdk_get_specific_info(BlockDriverState *bs)
|
|||||||
return spec_info;
|
return spec_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int vmdk_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
BDRVVmdkState *s = bs->opaque;
|
||||||
|
assert(s->num_extents);
|
||||||
|
bdi->needs_compressed_writes = s->extents[0].compressed;
|
||||||
|
if (!s->extents[0].flat) {
|
||||||
|
bdi->cluster_size = s->extents[0].cluster_sectors << BDRV_SECTOR_BITS;
|
||||||
|
}
|
||||||
|
/* See if we have multiple extents but they have different cases */
|
||||||
|
for (i = 1; i < s->num_extents; i++) {
|
||||||
|
if (bdi->needs_compressed_writes != s->extents[i].compressed ||
|
||||||
|
(bdi->cluster_size && bdi->cluster_size !=
|
||||||
|
s->extents[i].cluster_sectors << BDRV_SECTOR_BITS)) {
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static QEMUOptionParameter vmdk_create_options[] = {
|
static QEMUOptionParameter vmdk_create_options[] = {
|
||||||
{
|
{
|
||||||
.name = BLOCK_OPT_SIZE,
|
.name = BLOCK_OPT_SIZE,
|
||||||
@@ -2109,6 +2142,7 @@ static BlockDriver bdrv_vmdk = {
|
|||||||
.bdrv_reopen_prepare = vmdk_reopen_prepare,
|
.bdrv_reopen_prepare = vmdk_reopen_prepare,
|
||||||
.bdrv_read = vmdk_co_read,
|
.bdrv_read = vmdk_co_read,
|
||||||
.bdrv_write = vmdk_co_write,
|
.bdrv_write = vmdk_co_write,
|
||||||
|
.bdrv_write_compressed = vmdk_write_compressed,
|
||||||
.bdrv_co_write_zeroes = vmdk_co_write_zeroes,
|
.bdrv_co_write_zeroes = vmdk_co_write_zeroes,
|
||||||
.bdrv_close = vmdk_close,
|
.bdrv_close = vmdk_close,
|
||||||
.bdrv_create = vmdk_create,
|
.bdrv_create = vmdk_create,
|
||||||
@@ -2118,6 +2152,7 @@ static BlockDriver bdrv_vmdk = {
|
|||||||
.bdrv_has_zero_init = vmdk_has_zero_init,
|
.bdrv_has_zero_init = vmdk_has_zero_init,
|
||||||
.bdrv_get_specific_info = vmdk_get_specific_info,
|
.bdrv_get_specific_info = vmdk_get_specific_info,
|
||||||
.bdrv_refresh_limits = vmdk_refresh_limits,
|
.bdrv_refresh_limits = vmdk_refresh_limits,
|
||||||
|
.bdrv_get_info = vmdk_get_info,
|
||||||
|
|
||||||
.create_options = vmdk_create_options,
|
.create_options = vmdk_create_options,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ unsigned long reserved_va;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX;
|
static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX;
|
||||||
const char *qemu_uname_release = CONFIG_UNAME_RELEASE;
|
const char *qemu_uname_release;
|
||||||
extern char **environ;
|
extern char **environ;
|
||||||
enum BSDType bsd_type;
|
enum BSDType bsd_type;
|
||||||
|
|
||||||
|
|||||||
47
configure
vendored
47
configure
vendored
@@ -285,7 +285,6 @@ softmmu="yes"
|
|||||||
linux_user="no"
|
linux_user="no"
|
||||||
bsd_user="no"
|
bsd_user="no"
|
||||||
guest_base="yes"
|
guest_base="yes"
|
||||||
uname_release=""
|
|
||||||
aix="no"
|
aix="no"
|
||||||
blobs="yes"
|
blobs="yes"
|
||||||
pkgversion=""
|
pkgversion=""
|
||||||
@@ -404,6 +403,14 @@ fi
|
|||||||
# make source path absolute
|
# make source path absolute
|
||||||
source_path=`cd "$source_path"; pwd`
|
source_path=`cd "$source_path"; pwd`
|
||||||
|
|
||||||
|
# running configure in the source tree?
|
||||||
|
# we know that's the case if configure is there.
|
||||||
|
if test -f "./configure"; then
|
||||||
|
pwd_is_source_path="y"
|
||||||
|
else
|
||||||
|
pwd_is_source_path="n"
|
||||||
|
fi
|
||||||
|
|
||||||
check_define() {
|
check_define() {
|
||||||
cat > $TMPC <<EOF
|
cat > $TMPC <<EOF
|
||||||
#if !defined($1)
|
#if !defined($1)
|
||||||
@@ -945,8 +952,6 @@ for opt do
|
|||||||
;;
|
;;
|
||||||
--disable-pie) pie="no"
|
--disable-pie) pie="no"
|
||||||
;;
|
;;
|
||||||
--enable-uname-release=*) uname_release="$optarg"
|
|
||||||
;;
|
|
||||||
--enable-werror) werror="yes"
|
--enable-werror) werror="yes"
|
||||||
;;
|
;;
|
||||||
--disable-werror) werror="no"
|
--disable-werror) werror="no"
|
||||||
@@ -1295,7 +1300,6 @@ Advanced options (experts only):
|
|||||||
--fmod-lib path to FMOD library
|
--fmod-lib path to FMOD library
|
||||||
--fmod-inc path to FMOD includes
|
--fmod-inc path to FMOD includes
|
||||||
--oss-lib path to OSS library
|
--oss-lib path to OSS library
|
||||||
--enable-uname-release=R Return R for uname -r in usermode emulation
|
|
||||||
--cpu=CPU Build for host CPU [$cpu]
|
--cpu=CPU Build for host CPU [$cpu]
|
||||||
--disable-uuid disable uuid support
|
--disable-uuid disable uuid support
|
||||||
--enable-uuid enable uuid support
|
--enable-uuid enable uuid support
|
||||||
@@ -2628,7 +2632,7 @@ done
|
|||||||
if test "$modules" = yes; then
|
if test "$modules" = yes; then
|
||||||
shacmd_probe="sha1sum sha1 shasum"
|
shacmd_probe="sha1sum sha1 shasum"
|
||||||
for c in $shacmd_probe; do
|
for c in $shacmd_probe; do
|
||||||
if which $c &>/dev/null; then
|
if which $c >/dev/null 2>&1; then
|
||||||
shacmd="$c"
|
shacmd="$c"
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
@@ -2944,7 +2948,7 @@ EOF
|
|||||||
fdt=yes
|
fdt=yes
|
||||||
dtc_internal="yes"
|
dtc_internal="yes"
|
||||||
mkdir -p dtc
|
mkdir -p dtc
|
||||||
if [ "$source_path" != `pwd` ] ; then
|
if [ "$pwd_is_source_path" != "y" ] ; then
|
||||||
symlink "$source_path/dtc/Makefile" "dtc/Makefile"
|
symlink "$source_path/dtc/Makefile" "dtc/Makefile"
|
||||||
symlink "$source_path/dtc/scripts" "dtc/scripts"
|
symlink "$source_path/dtc/scripts" "dtc/scripts"
|
||||||
fi
|
fi
|
||||||
@@ -3466,10 +3470,10 @@ if test "$smartcard_nss" != "no"; then
|
|||||||
#include <pk11pub.h>
|
#include <pk11pub.h>
|
||||||
int main(void) { PK11_FreeSlot(0); return 0; }
|
int main(void) { PK11_FreeSlot(0); return 0; }
|
||||||
EOF
|
EOF
|
||||||
smartcard_includes="-I\$(SRC_PATH)/libcacard"
|
# FIXME: do not include $glib_* in here
|
||||||
libcacard_libs="$($pkg_config --libs nss 2>/dev/null) $glib_libs"
|
nss_libs="$($pkg_config --libs nss 2>/dev/null) $glib_libs"
|
||||||
libcacard_cflags="$($pkg_config --cflags nss 2>/dev/null) $glib_cflags"
|
nss_cflags="$($pkg_config --cflags nss 2>/dev/null) $glib_cflags"
|
||||||
test_cflags="$libcacard_cflags"
|
test_cflags="$nss_cflags"
|
||||||
# The header files in nss < 3.13.3 have a bug which causes them to
|
# The header files in nss < 3.13.3 have a bug which causes them to
|
||||||
# emit a warning. If we're going to compile QEMU with -Werror, then
|
# emit a warning. If we're going to compile QEMU with -Werror, then
|
||||||
# test that the headers don't have this bug. Otherwise we would pass
|
# test that the headers don't have this bug. Otherwise we would pass
|
||||||
@@ -3479,11 +3483,8 @@ EOF
|
|||||||
fi
|
fi
|
||||||
if test -n "$libtool" &&
|
if test -n "$libtool" &&
|
||||||
$pkg_config --atleast-version=3.12.8 nss && \
|
$pkg_config --atleast-version=3.12.8 nss && \
|
||||||
compile_prog "$test_cflags" "$libcacard_libs"; then
|
compile_prog "$test_cflags" "$nss_libs"; then
|
||||||
smartcard_nss="yes"
|
smartcard_nss="yes"
|
||||||
QEMU_CFLAGS="$QEMU_CFLAGS $libcacard_cflags"
|
|
||||||
QEMU_INCLUDES="$QEMU_INCLUDES $smartcard_includes"
|
|
||||||
libs_softmmu="$libcacard_libs $libs_softmmu"
|
|
||||||
else
|
else
|
||||||
if test "$smartcard_nss" = "yes"; then
|
if test "$smartcard_nss" = "yes"; then
|
||||||
feature_not_found "nss"
|
feature_not_found "nss"
|
||||||
@@ -4128,8 +4129,6 @@ echo "xen support $xen"
|
|||||||
echo "brlapi support $brlapi"
|
echo "brlapi support $brlapi"
|
||||||
echo "bluez support $bluez"
|
echo "bluez support $bluez"
|
||||||
echo "Documentation $docs"
|
echo "Documentation $docs"
|
||||||
[ ! -z "$uname_release" ] && \
|
|
||||||
echo "uname -r $uname_release"
|
|
||||||
echo "GUEST_BASE $guest_base"
|
echo "GUEST_BASE $guest_base"
|
||||||
echo "PIE $pie"
|
echo "PIE $pie"
|
||||||
echo "vde support $vde"
|
echo "vde support $vde"
|
||||||
@@ -4151,7 +4150,9 @@ echo "libcap-ng support $cap_ng"
|
|||||||
echo "vhost-net support $vhost_net"
|
echo "vhost-net support $vhost_net"
|
||||||
echo "vhost-scsi support $vhost_scsi"
|
echo "vhost-scsi support $vhost_scsi"
|
||||||
echo "Trace backend $trace_backend"
|
echo "Trace backend $trace_backend"
|
||||||
|
if test "$trace_backend" = "simple"; then
|
||||||
echo "Trace output file $trace_file-<pid>"
|
echo "Trace output file $trace_file-<pid>"
|
||||||
|
fi
|
||||||
if test "$spice" = "yes"; then
|
if test "$spice" = "yes"; then
|
||||||
echo "spice support $spice ($spice_protocol_version/$spice_server_version)"
|
echo "spice support $spice ($spice_protocol_version/$spice_server_version)"
|
||||||
else
|
else
|
||||||
@@ -4497,8 +4498,8 @@ fi
|
|||||||
|
|
||||||
if test "$smartcard_nss" = "yes" ; then
|
if test "$smartcard_nss" = "yes" ; then
|
||||||
echo "CONFIG_SMARTCARD_NSS=y" >> $config_host_mak
|
echo "CONFIG_SMARTCARD_NSS=y" >> $config_host_mak
|
||||||
echo "libcacard_libs=$libcacard_libs" >> $config_host_mak
|
echo "NSS_LIBS=$nss_libs" >> $config_host_mak
|
||||||
echo "libcacard_cflags=$libcacard_cflags" >> $config_host_mak
|
echo "NSS_CFLAGS=$nss_cflags" >> $config_host_mak
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "$libusb" = "yes" ; then
|
if test "$libusb" = "yes" ; then
|
||||||
@@ -4544,8 +4545,6 @@ if [ "$bsd" = "yes" ] ; then
|
|||||||
echo "CONFIG_BSD=y" >> $config_host_mak
|
echo "CONFIG_BSD=y" >> $config_host_mak
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "CONFIG_UNAME_RELEASE=\"$uname_release\"" >> $config_host_mak
|
|
||||||
|
|
||||||
if test "$zero_malloc" = "yes" ; then
|
if test "$zero_malloc" = "yes" ; then
|
||||||
echo "CONFIG_ZERO_MALLOC=y" >> $config_host_mak
|
echo "CONFIG_ZERO_MALLOC=y" >> $config_host_mak
|
||||||
fi
|
fi
|
||||||
@@ -4769,6 +4768,12 @@ if test "$gcov" = "yes" ; then
|
|||||||
echo "GCOV=$gcov_tool" >> $config_host_mak
|
echo "GCOV=$gcov_tool" >> $config_host_mak
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
iotests_common_env="tests/qemu-iotests/common.env"
|
||||||
|
|
||||||
|
echo "# Automatically generated by configure - do not modify" > $iotests_common_env
|
||||||
|
echo >> $iotests_common_env
|
||||||
|
echo "PYTHON='$python'" >> $iotests_common_env
|
||||||
|
|
||||||
# use included Linux headers
|
# use included Linux headers
|
||||||
if test "$linux" = "yes" ; then
|
if test "$linux" = "yes" ; then
|
||||||
mkdir -p linux-headers
|
mkdir -p linux-headers
|
||||||
@@ -5184,7 +5189,7 @@ do
|
|||||||
done
|
done
|
||||||
mkdir -p $DIRS
|
mkdir -p $DIRS
|
||||||
for f in $FILES ; do
|
for f in $FILES ; do
|
||||||
if [ -e "$source_path/$f" ] && [ "$source_path" != `pwd` ]; then
|
if [ -e "$source_path/$f" ] && [ "$pwd_is_source_path" != "y" ]; then
|
||||||
symlink "$source_path/$f" "$f"
|
symlink "$source_path/$f" "$f"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|||||||
@@ -115,14 +115,11 @@ static inline GThread *create_thread(GThreadFunc func, gpointer data)
|
|||||||
|
|
||||||
static void __attribute__((constructor)) coroutine_init(void)
|
static void __attribute__((constructor)) coroutine_init(void)
|
||||||
{
|
{
|
||||||
if (!g_thread_supported()) {
|
|
||||||
#if !GLIB_CHECK_VERSION(2, 31, 0)
|
#if !GLIB_CHECK_VERSION(2, 31, 0)
|
||||||
|
if (!g_thread_supported()) {
|
||||||
g_thread_init(NULL);
|
g_thread_init(NULL);
|
||||||
#else
|
|
||||||
fprintf(stderr, "glib threading failed to initialize.\n");
|
|
||||||
exit(1);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
init_coroutine_cond();
|
init_coroutine_cond();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ DriveInfo *add_init_drive(const char *optstr)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
mc = MACHINE_GET_CLASS(current_machine);
|
mc = MACHINE_GET_CLASS(current_machine);
|
||||||
dinfo = drive_init(opts, mc->qemu_machine->block_default_type);
|
dinfo = drive_init(opts, mc->block_default_type);
|
||||||
if (!dinfo) {
|
if (!dinfo) {
|
||||||
qemu_opts_del(opts);
|
qemu_opts_del(opts);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ common-obj-$(CONFIG_ARM_DIS) += arm.o
|
|||||||
common-obj-$(CONFIG_ARM_A64_DIS) += arm-a64.o
|
common-obj-$(CONFIG_ARM_A64_DIS) += arm-a64.o
|
||||||
common-obj-$(CONFIG_ARM_A64_DIS) += libvixl/
|
common-obj-$(CONFIG_ARM_A64_DIS) += libvixl/
|
||||||
libvixldir = $(SRC_PATH)/disas/libvixl
|
libvixldir = $(SRC_PATH)/disas/libvixl
|
||||||
$(obj)/arm-a64.o: QEMU_CFLAGS += -I$(libvixldir)
|
arm-a64.o-cflags := -I$(libvixldir)
|
||||||
common-obj-$(CONFIG_CRIS_DIS) += cris.o
|
common-obj-$(CONFIG_CRIS_DIS) += cris.o
|
||||||
common-obj-$(CONFIG_HPPA_DIS) += hppa.o
|
common-obj-$(CONFIG_HPPA_DIS) += hppa.o
|
||||||
common-obj-$(CONFIG_I386_DIS) += i386.o
|
common-obj-$(CONFIG_I386_DIS) += i386.o
|
||||||
|
|||||||
@@ -232,8 +232,8 @@ various constraints can be supplied to control how these callbacks are called:
|
|||||||
(in bytes) supported by the *implementation*; other access sizes will be
|
(in bytes) supported by the *implementation*; other access sizes will be
|
||||||
emulated using the ones available. For example a 4-byte write will be
|
emulated using the ones available. For example a 4-byte write will be
|
||||||
emulated using four 1-byte writes, if .impl.max_access_size = 1.
|
emulated using four 1-byte writes, if .impl.max_access_size = 1.
|
||||||
- .impl.valid specifies that the *implementation* only supports unaligned
|
- .impl.unaligned specifies that the *implementation* supports unaligned
|
||||||
accesses; unaligned accesses will be emulated by two aligned accesses.
|
accesses; if false, unaligned accesses will be emulated by two aligned
|
||||||
- .old_portio and .old_mmio can be used to ease porting from code using
|
accesses.
|
||||||
cpu_register_io_memory() and register_ioport(). They should not be used
|
- .old_mmio can be used to ease porting from code using
|
||||||
in new code.
|
cpu_register_io_memory(). It should not be used in new code.
|
||||||
|
|||||||
@@ -139,7 +139,6 @@ static const VMStateDescription vmstate_kbd = {
|
|||||||
.name = "pckbd",
|
.name = "pckbd",
|
||||||
.version_id = 3,
|
.version_id = 3,
|
||||||
.minimum_version_id = 3,
|
.minimum_version_id = 3,
|
||||||
.minimum_version_id_old = 3,
|
|
||||||
.fields = (VMStateField []) {
|
.fields = (VMStateField []) {
|
||||||
VMSTATE_UINT8(write_cmd, KBDState),
|
VMSTATE_UINT8(write_cmd, KBDState),
|
||||||
VMSTATE_UINT8(status, KBDState),
|
VMSTATE_UINT8(status, KBDState),
|
||||||
@@ -168,12 +167,13 @@ You can see that there are several version fields:
|
|||||||
- minimum_version_id: the minimum version_id that VMState is able to understand
|
- minimum_version_id: the minimum version_id that VMState is able to understand
|
||||||
for that device.
|
for that device.
|
||||||
- minimum_version_id_old: For devices that were not able to port to vmstate, we can
|
- minimum_version_id_old: For devices that were not able to port to vmstate, we can
|
||||||
assign a function that knows how to read this old state.
|
assign a function that knows how to read this old state. This field is
|
||||||
|
ignored if there is no load_state_old handler.
|
||||||
|
|
||||||
So, VMState is able to read versions from minimum_version_id to
|
So, VMState is able to read versions from minimum_version_id to
|
||||||
version_id. And the function load_state_old() is able to load state
|
version_id. And the function load_state_old() (if present) is able to
|
||||||
from minimum_version_id_old to minimum_version_id. This function is
|
load state from minimum_version_id_old to minimum_version_id. This
|
||||||
deprecated and will be removed when no more users are left.
|
function is deprecated and will be removed when no more users are left.
|
||||||
|
|
||||||
=== Massaging functions ===
|
=== Massaging functions ===
|
||||||
|
|
||||||
@@ -255,7 +255,6 @@ const VMStateDescription vmstate_ide_drive_pio_state = {
|
|||||||
.name = "ide_drive/pio_state",
|
.name = "ide_drive/pio_state",
|
||||||
.version_id = 1,
|
.version_id = 1,
|
||||||
.minimum_version_id = 1,
|
.minimum_version_id = 1,
|
||||||
.minimum_version_id_old = 1,
|
|
||||||
.pre_save = ide_drive_pio_pre_save,
|
.pre_save = ide_drive_pio_pre_save,
|
||||||
.post_load = ide_drive_pio_post_load,
|
.post_load = ide_drive_pio_post_load,
|
||||||
.fields = (VMStateField []) {
|
.fields = (VMStateField []) {
|
||||||
@@ -275,7 +274,6 @@ const VMStateDescription vmstate_ide_drive = {
|
|||||||
.name = "ide_drive",
|
.name = "ide_drive",
|
||||||
.version_id = 3,
|
.version_id = 3,
|
||||||
.minimum_version_id = 0,
|
.minimum_version_id = 0,
|
||||||
.minimum_version_id_old = 0,
|
|
||||||
.post_load = ide_drive_post_load,
|
.post_load = ide_drive_post_load,
|
||||||
.fields = (VMStateField []) {
|
.fields = (VMStateField []) {
|
||||||
.... several fields ....
|
.... several fields ....
|
||||||
|
|||||||
@@ -40,6 +40,17 @@ enumeration types and union types.
|
|||||||
Generally speaking, types definitions should always use CamelCase for the type
|
Generally speaking, types definitions should always use CamelCase for the type
|
||||||
names. Command names should be all lower case with words separated by a hyphen.
|
names. Command names should be all lower case with words separated by a hyphen.
|
||||||
|
|
||||||
|
|
||||||
|
=== Includes ===
|
||||||
|
|
||||||
|
The QAPI schema definitions can be modularized using the 'include' directive:
|
||||||
|
|
||||||
|
{ 'include': 'path/to/file.json'}
|
||||||
|
|
||||||
|
The directive is evaluated recursively, and include paths are relative to the
|
||||||
|
file using the directive.
|
||||||
|
|
||||||
|
|
||||||
=== Complex types ===
|
=== Complex types ===
|
||||||
|
|
||||||
A complex type is a dictionary containing a single key whose value is a
|
A complex type is a dictionary containing a single key whose value is a
|
||||||
@@ -49,10 +60,34 @@ example of a complex type is:
|
|||||||
{ 'type': 'MyType',
|
{ 'type': 'MyType',
|
||||||
'data': { 'member1': 'str', 'member2': 'int', '*member3': 'str' } }
|
'data': { 'member1': 'str', 'member2': 'int', '*member3': 'str' } }
|
||||||
|
|
||||||
The use of '*' as a prefix to the name means the member is optional. Optional
|
The use of '*' as a prefix to the name means the member is optional.
|
||||||
members should always be added to the end of the dictionary to preserve
|
|
||||||
backwards compatibility.
|
|
||||||
|
|
||||||
|
The default initialization value of an optional argument should not be changed
|
||||||
|
between versions of QEMU unless the new default maintains backward
|
||||||
|
compatibility to the user-visible behavior of the old default.
|
||||||
|
|
||||||
|
With proper documentation, this policy still allows some flexibility; for
|
||||||
|
example, documenting that a default of 0 picks an optimal buffer size allows
|
||||||
|
one release to declare the optimal size at 512 while another release declares
|
||||||
|
the optimal size at 4096 - the user-visible behavior is not the bytes used by
|
||||||
|
the buffer, but the fact that the buffer was optimal size.
|
||||||
|
|
||||||
|
On input structures (only mentioned in the 'data' side of a command), changing
|
||||||
|
from mandatory to optional is safe (older clients will supply the option, and
|
||||||
|
newer clients can benefit from the default); changing from optional to
|
||||||
|
mandatory is backwards incompatible (older clients may be omitting the option,
|
||||||
|
and must continue to work).
|
||||||
|
|
||||||
|
On output structures (only mentioned in the 'returns' side of a command),
|
||||||
|
changing from mandatory to optional is in general unsafe (older clients may be
|
||||||
|
expecting the field, and could crash if it is missing), although it can be done
|
||||||
|
if the only way that the optional argument will be omitted is when it is
|
||||||
|
triggered by the presence of a new input flag to the command that older clients
|
||||||
|
don't know to send. Changing from optional to mandatory is safe.
|
||||||
|
|
||||||
|
A structure that is used in both input and output of various commands
|
||||||
|
must consider the backwards compatibility constraints of both directions
|
||||||
|
of use.
|
||||||
|
|
||||||
A complex type definition can specify another complex type as its base.
|
A complex type definition can specify another complex type as its base.
|
||||||
In this case, the fields of the base type are included as top-level fields
|
In this case, the fields of the base type are included as top-level fields
|
||||||
@@ -221,7 +256,7 @@ created code.
|
|||||||
Example:
|
Example:
|
||||||
|
|
||||||
mdroth@illuin:~/w/qemu2.git$ python scripts/qapi-types.py \
|
mdroth@illuin:~/w/qemu2.git$ python scripts/qapi-types.py \
|
||||||
--output-dir="qapi-generated" --prefix="example-" < example-schema.json
|
--output-dir="qapi-generated" --prefix="example-" --input-file=example-schema.json
|
||||||
mdroth@illuin:~/w/qemu2.git$ cat qapi-generated/example-qapi-types.c
|
mdroth@illuin:~/w/qemu2.git$ cat qapi-generated/example-qapi-types.c
|
||||||
/* AUTOMATICALLY GENERATED, DO NOT MODIFY */
|
/* AUTOMATICALLY GENERATED, DO NOT MODIFY */
|
||||||
|
|
||||||
@@ -291,7 +326,7 @@ $(prefix)qapi-visit.h: declarations for previously mentioned visitor
|
|||||||
Example:
|
Example:
|
||||||
|
|
||||||
mdroth@illuin:~/w/qemu2.git$ python scripts/qapi-visit.py \
|
mdroth@illuin:~/w/qemu2.git$ python scripts/qapi-visit.py \
|
||||||
--output-dir="qapi-generated" --prefix="example-" < example-schema.json
|
--output-dir="qapi-generated" --prefix="example-" --input-file=example-schema.json
|
||||||
mdroth@illuin:~/w/qemu2.git$ cat qapi-generated/example-qapi-visit.c
|
mdroth@illuin:~/w/qemu2.git$ cat qapi-generated/example-qapi-visit.c
|
||||||
/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
|
/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT MODIFY */
|
||||||
|
|
||||||
|
|||||||
@@ -308,12 +308,12 @@ Here's the implementation of the "hello-world" HMP command:
|
|||||||
void hmp_hello_world(Monitor *mon, const QDict *qdict)
|
void hmp_hello_world(Monitor *mon, const QDict *qdict)
|
||||||
{
|
{
|
||||||
const char *message = qdict_get_try_str(qdict, "message");
|
const char *message = qdict_get_try_str(qdict, "message");
|
||||||
Error *errp = NULL;
|
Error *err = NULL;
|
||||||
|
|
||||||
qmp_hello_world(!!message, message, &errp);
|
qmp_hello_world(!!message, message, &err);
|
||||||
if (errp) {
|
if (err) {
|
||||||
monitor_printf(mon, "%s\n", error_get_pretty(errp));
|
monitor_printf(mon, "%s\n", error_get_pretty(err));
|
||||||
error_free(errp);
|
error_free(err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -328,7 +328,7 @@ There are three important points to be noticed:
|
|||||||
2. hmp_hello_world() performs error checking. In this example we just print
|
2. hmp_hello_world() performs error checking. In this example we just print
|
||||||
the error description to the user, but we could do more, like taking
|
the error description to the user, but we could do more, like taking
|
||||||
different actions depending on the error qmp_hello_world() returns
|
different actions depending on the error qmp_hello_world() returns
|
||||||
3. The "errp" variable must be initialized to NULL before performing the
|
3. The "err" variable must be initialized to NULL before performing the
|
||||||
QMP call
|
QMP call
|
||||||
|
|
||||||
There's one last step to actually make the command available to monitor users,
|
There's one last step to actually make the command available to monitor users,
|
||||||
@@ -480,12 +480,12 @@ Here's the HMP counterpart of the query-alarm-clock command:
|
|||||||
void hmp_info_alarm_clock(Monitor *mon)
|
void hmp_info_alarm_clock(Monitor *mon)
|
||||||
{
|
{
|
||||||
QemuAlarmClock *clock;
|
QemuAlarmClock *clock;
|
||||||
Error *errp = NULL;
|
Error *err = NULL;
|
||||||
|
|
||||||
clock = qmp_query_alarm_clock(&errp);
|
clock = qmp_query_alarm_clock(&err);
|
||||||
if (errp) {
|
if (err) {
|
||||||
monitor_printf(mon, "Could not query alarm clock information\n");
|
monitor_printf(mon, "Could not query alarm clock information\n");
|
||||||
error_free(errp);
|
error_free(err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -631,12 +631,12 @@ has to traverse the list, it's shown below for reference:
|
|||||||
void hmp_info_alarm_methods(Monitor *mon)
|
void hmp_info_alarm_methods(Monitor *mon)
|
||||||
{
|
{
|
||||||
TimerAlarmMethodList *method_list, *method;
|
TimerAlarmMethodList *method_list, *method;
|
||||||
Error *errp = NULL;
|
Error *err = NULL;
|
||||||
|
|
||||||
method_list = qmp_query_alarm_methods(&errp);
|
method_list = qmp_query_alarm_methods(&err);
|
||||||
if (errp) {
|
if (err) {
|
||||||
monitor_printf(mon, "Could not query alarm methods\n");
|
monitor_printf(mon, "Could not query alarm methods\n");
|
||||||
error_free(errp);
|
error_free(err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
6
dump.c
6
dump.c
@@ -86,7 +86,6 @@ typedef struct DumpState {
|
|||||||
bool has_filter;
|
bool has_filter;
|
||||||
int64_t begin;
|
int64_t begin;
|
||||||
int64_t length;
|
int64_t length;
|
||||||
Error **errp;
|
|
||||||
|
|
||||||
uint8_t *note_buf; /* buffer for notes */
|
uint8_t *note_buf; /* buffer for notes */
|
||||||
size_t note_buf_offset; /* the writing place in note_buf */
|
size_t note_buf_offset; /* the writing place in note_buf */
|
||||||
@@ -1570,7 +1569,6 @@ static int dump_init(DumpState *s, int fd, bool has_format,
|
|||||||
nr_cpus++;
|
nr_cpus++;
|
||||||
}
|
}
|
||||||
|
|
||||||
s->errp = errp;
|
|
||||||
s->fd = fd;
|
s->fd = fd;
|
||||||
s->has_filter = has_filter;
|
s->has_filter = has_filter;
|
||||||
s->begin = begin;
|
s->begin = begin;
|
||||||
@@ -1780,11 +1778,11 @@ void qmp_dump_guest_memory(bool paging, const char *file, bool has_begin,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (has_format && format != DUMP_GUEST_MEMORY_FORMAT_ELF) {
|
if (has_format && format != DUMP_GUEST_MEMORY_FORMAT_ELF) {
|
||||||
if (create_kdump_vmcore(s) < 0 && !error_is_set(s->errp)) {
|
if (create_kdump_vmcore(s) < 0) {
|
||||||
error_set(errp, QERR_IO_ERROR);
|
error_set(errp, QERR_IO_ERROR);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (create_vmcore(s) < 0 && !error_is_set(s->errp)) {
|
if (create_vmcore(s) < 0) {
|
||||||
error_set(errp, QERR_IO_ERROR);
|
error_set(errp, QERR_IO_ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
2
exec.c
2
exec.c
@@ -380,7 +380,7 @@ MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr,
|
|||||||
as = iotlb.target_as;
|
as = iotlb.target_as;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (memory_access_is_direct(mr, is_write)) {
|
if (xen_enabled() && memory_access_is_direct(mr, is_write)) {
|
||||||
hwaddr page = ((addr & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE) - addr;
|
hwaddr page = ((addr & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE) - addr;
|
||||||
len = MIN(page, len);
|
len = MIN(page, len);
|
||||||
}
|
}
|
||||||
|
|||||||
145
hmp.c
145
hmp.c
@@ -28,7 +28,8 @@
|
|||||||
|
|
||||||
static void hmp_handle_error(Monitor *mon, Error **errp)
|
static void hmp_handle_error(Monitor *mon, Error **errp)
|
||||||
{
|
{
|
||||||
if (error_is_set(errp)) {
|
assert(errp);
|
||||||
|
if (*errp) {
|
||||||
monitor_printf(mon, "%s\n", error_get_pretty(*errp));
|
monitor_printf(mon, "%s\n", error_get_pretty(*errp));
|
||||||
error_free(*errp);
|
error_free(*errp);
|
||||||
}
|
}
|
||||||
@@ -188,6 +189,8 @@ void hmp_info_migrate(Monitor *mon, const QDict *qdict)
|
|||||||
info->ram->normal);
|
info->ram->normal);
|
||||||
monitor_printf(mon, "normal bytes: %" PRIu64 " kbytes\n",
|
monitor_printf(mon, "normal bytes: %" PRIu64 " kbytes\n",
|
||||||
info->ram->normal_bytes >> 10);
|
info->ram->normal_bytes >> 10);
|
||||||
|
monitor_printf(mon, "dirty sync count: %" PRIu64 "\n",
|
||||||
|
info->ram->dirty_sync_count);
|
||||||
if (info->ram->dirty_pages_rate) {
|
if (info->ram->dirty_pages_rate) {
|
||||||
monitor_printf(mon, "dirty pages rate: %" PRIu64 " pages\n",
|
monitor_printf(mon, "dirty pages rate: %" PRIu64 " pages\n",
|
||||||
info->ram->dirty_pages_rate);
|
info->ram->dirty_pages_rate);
|
||||||
@@ -212,6 +215,8 @@ void hmp_info_migrate(Monitor *mon, const QDict *qdict)
|
|||||||
info->xbzrle_cache->pages);
|
info->xbzrle_cache->pages);
|
||||||
monitor_printf(mon, "xbzrle cache miss: %" PRIu64 "\n",
|
monitor_printf(mon, "xbzrle cache miss: %" PRIu64 "\n",
|
||||||
info->xbzrle_cache->cache_miss);
|
info->xbzrle_cache->cache_miss);
|
||||||
|
monitor_printf(mon, "xbzrle cache miss rate: %0.2f\n",
|
||||||
|
info->xbzrle_cache->cache_miss_rate);
|
||||||
monitor_printf(mon, "xbzrle overflow : %" PRIu64 "\n",
|
monitor_printf(mon, "xbzrle overflow : %" PRIu64 "\n",
|
||||||
info->xbzrle_cache->overflow);
|
info->xbzrle_cache->overflow);
|
||||||
}
|
}
|
||||||
@@ -750,10 +755,10 @@ void hmp_memsave(Monitor *mon, const QDict *qdict)
|
|||||||
uint32_t size = qdict_get_int(qdict, "size");
|
uint32_t size = qdict_get_int(qdict, "size");
|
||||||
const char *filename = qdict_get_str(qdict, "filename");
|
const char *filename = qdict_get_str(qdict, "filename");
|
||||||
uint64_t addr = qdict_get_int(qdict, "val");
|
uint64_t addr = qdict_get_int(qdict, "val");
|
||||||
Error *errp = NULL;
|
Error *err = NULL;
|
||||||
|
|
||||||
qmp_memsave(addr, size, filename, true, monitor_get_cpu_index(), &errp);
|
qmp_memsave(addr, size, filename, true, monitor_get_cpu_index(), &err);
|
||||||
hmp_handle_error(mon, &errp);
|
hmp_handle_error(mon, &err);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hmp_pmemsave(Monitor *mon, const QDict *qdict)
|
void hmp_pmemsave(Monitor *mon, const QDict *qdict)
|
||||||
@@ -761,21 +766,21 @@ void hmp_pmemsave(Monitor *mon, const QDict *qdict)
|
|||||||
uint32_t size = qdict_get_int(qdict, "size");
|
uint32_t size = qdict_get_int(qdict, "size");
|
||||||
const char *filename = qdict_get_str(qdict, "filename");
|
const char *filename = qdict_get_str(qdict, "filename");
|
||||||
uint64_t addr = qdict_get_int(qdict, "val");
|
uint64_t addr = qdict_get_int(qdict, "val");
|
||||||
Error *errp = NULL;
|
Error *err = NULL;
|
||||||
|
|
||||||
qmp_pmemsave(addr, size, filename, &errp);
|
qmp_pmemsave(addr, size, filename, &err);
|
||||||
hmp_handle_error(mon, &errp);
|
hmp_handle_error(mon, &err);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hmp_ringbuf_write(Monitor *mon, const QDict *qdict)
|
void hmp_ringbuf_write(Monitor *mon, const QDict *qdict)
|
||||||
{
|
{
|
||||||
const char *chardev = qdict_get_str(qdict, "device");
|
const char *chardev = qdict_get_str(qdict, "device");
|
||||||
const char *data = qdict_get_str(qdict, "data");
|
const char *data = qdict_get_str(qdict, "data");
|
||||||
Error *errp = NULL;
|
Error *err = NULL;
|
||||||
|
|
||||||
qmp_ringbuf_write(chardev, data, false, 0, &errp);
|
qmp_ringbuf_write(chardev, data, false, 0, &err);
|
||||||
|
|
||||||
hmp_handle_error(mon, &errp);
|
hmp_handle_error(mon, &err);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hmp_ringbuf_read(Monitor *mon, const QDict *qdict)
|
void hmp_ringbuf_read(Monitor *mon, const QDict *qdict)
|
||||||
@@ -783,13 +788,13 @@ void hmp_ringbuf_read(Monitor *mon, const QDict *qdict)
|
|||||||
uint32_t size = qdict_get_int(qdict, "size");
|
uint32_t size = qdict_get_int(qdict, "size");
|
||||||
const char *chardev = qdict_get_str(qdict, "device");
|
const char *chardev = qdict_get_str(qdict, "device");
|
||||||
char *data;
|
char *data;
|
||||||
Error *errp = NULL;
|
Error *err = NULL;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
data = qmp_ringbuf_read(chardev, size, false, 0, &errp);
|
data = qmp_ringbuf_read(chardev, size, false, 0, &err);
|
||||||
if (errp) {
|
if (err) {
|
||||||
monitor_printf(mon, "%s\n", error_get_pretty(errp));
|
monitor_printf(mon, "%s\n", error_get_pretty(err));
|
||||||
error_free(errp);
|
error_free(err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -824,7 +829,7 @@ static bool key_is_missing(const BlockInfo *bdev)
|
|||||||
void hmp_cont(Monitor *mon, const QDict *qdict)
|
void hmp_cont(Monitor *mon, const QDict *qdict)
|
||||||
{
|
{
|
||||||
BlockInfoList *bdev_list, *bdev;
|
BlockInfoList *bdev_list, *bdev;
|
||||||
Error *errp = NULL;
|
Error *err = NULL;
|
||||||
|
|
||||||
bdev_list = qmp_query_block(NULL);
|
bdev_list = qmp_query_block(NULL);
|
||||||
for (bdev = bdev_list; bdev; bdev = bdev->next) {
|
for (bdev = bdev_list; bdev; bdev = bdev->next) {
|
||||||
@@ -835,8 +840,8 @@ void hmp_cont(Monitor *mon, const QDict *qdict)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
qmp_cont(&errp);
|
qmp_cont(&err);
|
||||||
hmp_handle_error(mon, &errp);
|
hmp_handle_error(mon, &err);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
qapi_free_BlockInfoList(bdev_list);
|
qapi_free_BlockInfoList(bdev_list);
|
||||||
@@ -849,41 +854,41 @@ void hmp_system_wakeup(Monitor *mon, const QDict *qdict)
|
|||||||
|
|
||||||
void hmp_inject_nmi(Monitor *mon, const QDict *qdict)
|
void hmp_inject_nmi(Monitor *mon, const QDict *qdict)
|
||||||
{
|
{
|
||||||
Error *errp = NULL;
|
Error *err = NULL;
|
||||||
|
|
||||||
qmp_inject_nmi(&errp);
|
qmp_inject_nmi(&err);
|
||||||
hmp_handle_error(mon, &errp);
|
hmp_handle_error(mon, &err);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hmp_set_link(Monitor *mon, const QDict *qdict)
|
void hmp_set_link(Monitor *mon, const QDict *qdict)
|
||||||
{
|
{
|
||||||
const char *name = qdict_get_str(qdict, "name");
|
const char *name = qdict_get_str(qdict, "name");
|
||||||
int up = qdict_get_bool(qdict, "up");
|
int up = qdict_get_bool(qdict, "up");
|
||||||
Error *errp = NULL;
|
Error *err = NULL;
|
||||||
|
|
||||||
qmp_set_link(name, up, &errp);
|
qmp_set_link(name, up, &err);
|
||||||
hmp_handle_error(mon, &errp);
|
hmp_handle_error(mon, &err);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hmp_block_passwd(Monitor *mon, const QDict *qdict)
|
void hmp_block_passwd(Monitor *mon, const QDict *qdict)
|
||||||
{
|
{
|
||||||
const char *device = qdict_get_str(qdict, "device");
|
const char *device = qdict_get_str(qdict, "device");
|
||||||
const char *password = qdict_get_str(qdict, "password");
|
const char *password = qdict_get_str(qdict, "password");
|
||||||
Error *errp = NULL;
|
Error *err = NULL;
|
||||||
|
|
||||||
qmp_block_passwd(true, device, false, NULL, password, &errp);
|
qmp_block_passwd(true, device, false, NULL, password, &err);
|
||||||
hmp_handle_error(mon, &errp);
|
hmp_handle_error(mon, &err);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hmp_balloon(Monitor *mon, const QDict *qdict)
|
void hmp_balloon(Monitor *mon, const QDict *qdict)
|
||||||
{
|
{
|
||||||
int64_t value = qdict_get_int(qdict, "value");
|
int64_t value = qdict_get_int(qdict, "value");
|
||||||
Error *errp = NULL;
|
Error *err = NULL;
|
||||||
|
|
||||||
qmp_balloon(value, &errp);
|
qmp_balloon(value, &err);
|
||||||
if (errp) {
|
if (err) {
|
||||||
monitor_printf(mon, "balloon: %s\n", error_get_pretty(errp));
|
monitor_printf(mon, "balloon: %s\n", error_get_pretty(err));
|
||||||
error_free(errp);
|
error_free(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -891,10 +896,10 @@ void hmp_block_resize(Monitor *mon, const QDict *qdict)
|
|||||||
{
|
{
|
||||||
const char *device = qdict_get_str(qdict, "device");
|
const char *device = qdict_get_str(qdict, "device");
|
||||||
int64_t size = qdict_get_int(qdict, "size");
|
int64_t size = qdict_get_int(qdict, "size");
|
||||||
Error *errp = NULL;
|
Error *err = NULL;
|
||||||
|
|
||||||
qmp_block_resize(true, device, false, NULL, size, &errp);
|
qmp_block_resize(true, device, false, NULL, size, &err);
|
||||||
hmp_handle_error(mon, &errp);
|
hmp_handle_error(mon, &err);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hmp_drive_mirror(Monitor *mon, const QDict *qdict)
|
void hmp_drive_mirror(Monitor *mon, const QDict *qdict)
|
||||||
@@ -905,11 +910,11 @@ void hmp_drive_mirror(Monitor *mon, const QDict *qdict)
|
|||||||
int reuse = qdict_get_try_bool(qdict, "reuse", 0);
|
int reuse = qdict_get_try_bool(qdict, "reuse", 0);
|
||||||
int full = qdict_get_try_bool(qdict, "full", 0);
|
int full = qdict_get_try_bool(qdict, "full", 0);
|
||||||
enum NewImageMode mode;
|
enum NewImageMode mode;
|
||||||
Error *errp = NULL;
|
Error *err = NULL;
|
||||||
|
|
||||||
if (!filename) {
|
if (!filename) {
|
||||||
error_set(&errp, QERR_MISSING_PARAMETER, "target");
|
error_set(&err, QERR_MISSING_PARAMETER, "target");
|
||||||
hmp_handle_error(mon, &errp);
|
hmp_handle_error(mon, &err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -922,8 +927,8 @@ void hmp_drive_mirror(Monitor *mon, const QDict *qdict)
|
|||||||
qmp_drive_mirror(device, filename, !!format, format,
|
qmp_drive_mirror(device, filename, !!format, format,
|
||||||
full ? MIRROR_SYNC_MODE_FULL : MIRROR_SYNC_MODE_TOP,
|
full ? MIRROR_SYNC_MODE_FULL : MIRROR_SYNC_MODE_TOP,
|
||||||
true, mode, false, 0, false, 0, false, 0,
|
true, mode, false, 0, false, 0, false, 0,
|
||||||
false, 0, false, 0, &errp);
|
false, 0, false, 0, &err);
|
||||||
hmp_handle_error(mon, &errp);
|
hmp_handle_error(mon, &err);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hmp_drive_backup(Monitor *mon, const QDict *qdict)
|
void hmp_drive_backup(Monitor *mon, const QDict *qdict)
|
||||||
@@ -934,11 +939,11 @@ void hmp_drive_backup(Monitor *mon, const QDict *qdict)
|
|||||||
int reuse = qdict_get_try_bool(qdict, "reuse", 0);
|
int reuse = qdict_get_try_bool(qdict, "reuse", 0);
|
||||||
int full = qdict_get_try_bool(qdict, "full", 0);
|
int full = qdict_get_try_bool(qdict, "full", 0);
|
||||||
enum NewImageMode mode;
|
enum NewImageMode mode;
|
||||||
Error *errp = NULL;
|
Error *err = NULL;
|
||||||
|
|
||||||
if (!filename) {
|
if (!filename) {
|
||||||
error_set(&errp, QERR_MISSING_PARAMETER, "target");
|
error_set(&err, QERR_MISSING_PARAMETER, "target");
|
||||||
hmp_handle_error(mon, &errp);
|
hmp_handle_error(mon, &err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -950,8 +955,8 @@ void hmp_drive_backup(Monitor *mon, const QDict *qdict)
|
|||||||
|
|
||||||
qmp_drive_backup(device, filename, !!format, format,
|
qmp_drive_backup(device, filename, !!format, format,
|
||||||
full ? MIRROR_SYNC_MODE_FULL : MIRROR_SYNC_MODE_TOP,
|
full ? MIRROR_SYNC_MODE_FULL : MIRROR_SYNC_MODE_TOP,
|
||||||
true, mode, false, 0, false, 0, false, 0, &errp);
|
true, mode, false, 0, false, 0, false, 0, &err);
|
||||||
hmp_handle_error(mon, &errp);
|
hmp_handle_error(mon, &err);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict)
|
void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict)
|
||||||
@@ -961,13 +966,13 @@ void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict)
|
|||||||
const char *format = qdict_get_try_str(qdict, "format");
|
const char *format = qdict_get_try_str(qdict, "format");
|
||||||
int reuse = qdict_get_try_bool(qdict, "reuse", 0);
|
int reuse = qdict_get_try_bool(qdict, "reuse", 0);
|
||||||
enum NewImageMode mode;
|
enum NewImageMode mode;
|
||||||
Error *errp = NULL;
|
Error *err = NULL;
|
||||||
|
|
||||||
if (!filename) {
|
if (!filename) {
|
||||||
/* In the future, if 'snapshot-file' is not specified, the snapshot
|
/* In the future, if 'snapshot-file' is not specified, the snapshot
|
||||||
will be taken internally. Today it's actually required. */
|
will be taken internally. Today it's actually required. */
|
||||||
error_set(&errp, QERR_MISSING_PARAMETER, "snapshot-file");
|
error_set(&err, QERR_MISSING_PARAMETER, "snapshot-file");
|
||||||
hmp_handle_error(mon, &errp);
|
hmp_handle_error(mon, &err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -975,18 +980,18 @@ void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict)
|
|||||||
qmp_blockdev_snapshot_sync(true, device, false, NULL,
|
qmp_blockdev_snapshot_sync(true, device, false, NULL,
|
||||||
filename, false, NULL,
|
filename, false, NULL,
|
||||||
!!format, format,
|
!!format, format,
|
||||||
true, mode, &errp);
|
true, mode, &err);
|
||||||
hmp_handle_error(mon, &errp);
|
hmp_handle_error(mon, &err);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hmp_snapshot_blkdev_internal(Monitor *mon, const QDict *qdict)
|
void hmp_snapshot_blkdev_internal(Monitor *mon, const QDict *qdict)
|
||||||
{
|
{
|
||||||
const char *device = qdict_get_str(qdict, "device");
|
const char *device = qdict_get_str(qdict, "device");
|
||||||
const char *name = qdict_get_str(qdict, "name");
|
const char *name = qdict_get_str(qdict, "name");
|
||||||
Error *errp = NULL;
|
Error *err = NULL;
|
||||||
|
|
||||||
qmp_blockdev_snapshot_internal_sync(device, name, &errp);
|
qmp_blockdev_snapshot_internal_sync(device, name, &err);
|
||||||
hmp_handle_error(mon, &errp);
|
hmp_handle_error(mon, &err);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hmp_snapshot_delete_blkdev_internal(Monitor *mon, const QDict *qdict)
|
void hmp_snapshot_delete_blkdev_internal(Monitor *mon, const QDict *qdict)
|
||||||
@@ -994,11 +999,11 @@ void hmp_snapshot_delete_blkdev_internal(Monitor *mon, const QDict *qdict)
|
|||||||
const char *device = qdict_get_str(qdict, "device");
|
const char *device = qdict_get_str(qdict, "device");
|
||||||
const char *name = qdict_get_str(qdict, "name");
|
const char *name = qdict_get_str(qdict, "name");
|
||||||
const char *id = qdict_get_try_str(qdict, "id");
|
const char *id = qdict_get_try_str(qdict, "id");
|
||||||
Error *errp = NULL;
|
Error *err = NULL;
|
||||||
|
|
||||||
qmp_blockdev_snapshot_delete_internal_sync(device, !!id, id,
|
qmp_blockdev_snapshot_delete_internal_sync(device, !!id, id,
|
||||||
true, name, &errp);
|
true, name, &err);
|
||||||
hmp_handle_error(mon, &errp);
|
hmp_handle_error(mon, &err);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hmp_migrate_cancel(Monitor *mon, const QDict *qdict)
|
void hmp_migrate_cancel(Monitor *mon, const QDict *qdict)
|
||||||
@@ -1306,7 +1311,7 @@ void hmp_device_del(Monitor *mon, const QDict *qdict)
|
|||||||
|
|
||||||
void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict)
|
void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict)
|
||||||
{
|
{
|
||||||
Error *errp = NULL;
|
Error *err = NULL;
|
||||||
int paging = qdict_get_try_bool(qdict, "paging", 0);
|
int paging = qdict_get_try_bool(qdict, "paging", 0);
|
||||||
int zlib = qdict_get_try_bool(qdict, "zlib", 0);
|
int zlib = qdict_get_try_bool(qdict, "zlib", 0);
|
||||||
int lzo = qdict_get_try_bool(qdict, "lzo", 0);
|
int lzo = qdict_get_try_bool(qdict, "lzo", 0);
|
||||||
@@ -1320,8 +1325,8 @@ void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict)
|
|||||||
char *prot;
|
char *prot;
|
||||||
|
|
||||||
if (zlib + lzo + snappy > 1) {
|
if (zlib + lzo + snappy > 1) {
|
||||||
error_setg(&errp, "only one of '-z|-l|-s' can be set");
|
error_setg(&err, "only one of '-z|-l|-s' can be set");
|
||||||
hmp_handle_error(mon, &errp);
|
hmp_handle_error(mon, &err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1347,8 +1352,8 @@ void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict)
|
|||||||
prot = g_strconcat("file:", file, NULL);
|
prot = g_strconcat("file:", file, NULL);
|
||||||
|
|
||||||
qmp_dump_guest_memory(paging, prot, has_begin, begin, has_length, length,
|
qmp_dump_guest_memory(paging, prot, has_begin, begin, has_length, length,
|
||||||
true, dump_format, &errp);
|
true, dump_format, &err);
|
||||||
hmp_handle_error(mon, &errp);
|
hmp_handle_error(mon, &err);
|
||||||
g_free(prot);
|
g_free(prot);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1440,19 +1445,19 @@ out:
|
|||||||
void hmp_getfd(Monitor *mon, const QDict *qdict)
|
void hmp_getfd(Monitor *mon, const QDict *qdict)
|
||||||
{
|
{
|
||||||
const char *fdname = qdict_get_str(qdict, "fdname");
|
const char *fdname = qdict_get_str(qdict, "fdname");
|
||||||
Error *errp = NULL;
|
Error *err = NULL;
|
||||||
|
|
||||||
qmp_getfd(fdname, &errp);
|
qmp_getfd(fdname, &err);
|
||||||
hmp_handle_error(mon, &errp);
|
hmp_handle_error(mon, &err);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hmp_closefd(Monitor *mon, const QDict *qdict)
|
void hmp_closefd(Monitor *mon, const QDict *qdict)
|
||||||
{
|
{
|
||||||
const char *fdname = qdict_get_str(qdict, "fdname");
|
const char *fdname = qdict_get_str(qdict, "fdname");
|
||||||
Error *errp = NULL;
|
Error *err = NULL;
|
||||||
|
|
||||||
qmp_closefd(fdname, &errp);
|
qmp_closefd(fdname, &err);
|
||||||
hmp_handle_error(mon, &errp);
|
hmp_handle_error(mon, &err);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hmp_send_key(Monitor *mon, const QDict *qdict)
|
void hmp_send_key(Monitor *mon, const QDict *qdict)
|
||||||
@@ -1602,10 +1607,10 @@ void hmp_nbd_server_add(Monitor *mon, const QDict *qdict)
|
|||||||
|
|
||||||
void hmp_nbd_server_stop(Monitor *mon, const QDict *qdict)
|
void hmp_nbd_server_stop(Monitor *mon, const QDict *qdict)
|
||||||
{
|
{
|
||||||
Error *errp = NULL;
|
Error *err = NULL;
|
||||||
|
|
||||||
qmp_nbd_server_stop(&errp);
|
qmp_nbd_server_stop(&err);
|
||||||
hmp_handle_error(mon, &errp);
|
hmp_handle_error(mon, &err);
|
||||||
}
|
}
|
||||||
|
|
||||||
void hmp_cpu_add(Monitor *mon, const QDict *qdict)
|
void hmp_cpu_add(Monitor *mon, const QDict *qdict)
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#include "hw/virtio/virtio.h"
|
#include "hw/virtio/virtio.h"
|
||||||
#include "virtio-9p.h"
|
#include "virtio-9p.h"
|
||||||
#include "virtio-9p-xattr.h"
|
#include "virtio-9p-xattr.h"
|
||||||
|
#include "fsdev/qemu-fsdev.h" /* local_ops */
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <grp.h>
|
#include <grp.h>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
/* Root node for synth file system */
|
/* Root node for synth file system */
|
||||||
V9fsSynthNode v9fs_synth_root = {
|
static V9fsSynthNode v9fs_synth_root = {
|
||||||
.name = "/",
|
.name = "/",
|
||||||
.actual_attr = {
|
.actual_attr = {
|
||||||
.mode = 0555 | S_IFDIR,
|
.mode = 0555 | S_IFDIR,
|
||||||
|
|||||||
@@ -63,16 +63,18 @@ typedef struct AcpiPciHpFind {
|
|||||||
|
|
||||||
static int acpi_pcihp_get_bsel(PCIBus *bus)
|
static int acpi_pcihp_get_bsel(PCIBus *bus)
|
||||||
{
|
{
|
||||||
QObject *o = object_property_get_qobject(OBJECT(bus),
|
Error *local_err = NULL;
|
||||||
ACPI_PCIHP_PROP_BSEL, NULL);
|
int64_t bsel = object_property_get_int(OBJECT(bus), ACPI_PCIHP_PROP_BSEL,
|
||||||
int64_t bsel = -1;
|
&local_err);
|
||||||
if (o) {
|
|
||||||
bsel = qint_get_int(qobject_to_qint(o));
|
if (local_err || bsel < 0 || bsel >= ACPI_PCIHP_MAX_HOTPLUG_BUS) {
|
||||||
}
|
if (local_err) {
|
||||||
if (bsel < 0) {
|
error_free(local_err);
|
||||||
|
}
|
||||||
return -1;
|
return -1;
|
||||||
|
} else {
|
||||||
|
return bsel;
|
||||||
}
|
}
|
||||||
return bsel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void acpi_pcihp_test_hotplug_bus(PCIBus *bus, void *opaque)
|
static void acpi_pcihp_test_hotplug_bus(PCIBus *bus, void *opaque)
|
||||||
|
|||||||
@@ -732,7 +732,7 @@ static void pxa2xx_ssp_save(QEMUFile *f, void *opaque)
|
|||||||
static int pxa2xx_ssp_load(QEMUFile *f, void *opaque, int version_id)
|
static int pxa2xx_ssp_load(QEMUFile *f, void *opaque, int version_id)
|
||||||
{
|
{
|
||||||
PXA2xxSSPState *s = (PXA2xxSSPState *) opaque;
|
PXA2xxSSPState *s = (PXA2xxSSPState *) opaque;
|
||||||
int i;
|
int i, v;
|
||||||
|
|
||||||
s->enable = qemu_get_be32(f);
|
s->enable = qemu_get_be32(f);
|
||||||
|
|
||||||
@@ -746,7 +746,11 @@ static int pxa2xx_ssp_load(QEMUFile *f, void *opaque, int version_id)
|
|||||||
qemu_get_8s(f, &s->ssrsa);
|
qemu_get_8s(f, &s->ssrsa);
|
||||||
qemu_get_8s(f, &s->ssacd);
|
qemu_get_8s(f, &s->ssacd);
|
||||||
|
|
||||||
s->rx_level = qemu_get_byte(f);
|
v = qemu_get_byte(f);
|
||||||
|
if (v < 0 || v > ARRAY_SIZE(s->rx_fifo)) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
s->rx_level = v;
|
||||||
s->rx_start = 0;
|
s->rx_start = 0;
|
||||||
for (i = 0; i < s->rx_level; i ++)
|
for (i = 0; i < s->rx_level; i ++)
|
||||||
s->rx_fifo[i] = qemu_get_byte(f);
|
s->rx_fifo[i] = qemu_get_byte(f);
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ typedef struct {
|
|||||||
#ifndef HAS_YMF262
|
#ifndef HAS_YMF262
|
||||||
FM_OPL *opl;
|
FM_OPL *opl;
|
||||||
#endif
|
#endif
|
||||||
|
PortioList port_list;
|
||||||
} AdlibState;
|
} AdlibState;
|
||||||
|
|
||||||
static AdlibState *glob_adlib;
|
static AdlibState *glob_adlib;
|
||||||
@@ -293,7 +294,6 @@ static MemoryRegionPortio adlib_portio_list[] = {
|
|||||||
static void adlib_realizefn (DeviceState *dev, Error **errp)
|
static void adlib_realizefn (DeviceState *dev, Error **errp)
|
||||||
{
|
{
|
||||||
AdlibState *s = ADLIB(dev);
|
AdlibState *s = ADLIB(dev);
|
||||||
PortioList *port_list = g_new(PortioList, 1);
|
|
||||||
struct audsettings as;
|
struct audsettings as;
|
||||||
|
|
||||||
if (glob_adlib) {
|
if (glob_adlib) {
|
||||||
@@ -349,8 +349,8 @@ static void adlib_realizefn (DeviceState *dev, Error **errp)
|
|||||||
|
|
||||||
adlib_portio_list[0].offset = s->port;
|
adlib_portio_list[0].offset = s->port;
|
||||||
adlib_portio_list[1].offset = s->port + 8;
|
adlib_portio_list[1].offset = s->port + 8;
|
||||||
portio_list_init (port_list, OBJECT(s), adlib_portio_list, s, "adlib");
|
portio_list_init (&s->port_list, OBJECT(s), adlib_portio_list, s, "adlib");
|
||||||
portio_list_add (port_list, isa_address_space_io(&s->parent_obj), 0);
|
portio_list_add (&s->port_list, isa_address_space_io(&s->parent_obj), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Property adlib_properties[] = {
|
static Property adlib_properties[] = {
|
||||||
|
|||||||
@@ -79,6 +79,12 @@ static inline void blkif_get_x86_32_req(blkif_request_t *dst, blkif_x86_32_reque
|
|||||||
dst->handle = src->handle;
|
dst->handle = src->handle;
|
||||||
dst->id = src->id;
|
dst->id = src->id;
|
||||||
dst->sector_number = src->sector_number;
|
dst->sector_number = src->sector_number;
|
||||||
|
if (src->operation == BLKIF_OP_DISCARD) {
|
||||||
|
struct blkif_request_discard *s = (void *)src;
|
||||||
|
struct blkif_request_discard *d = (void *)dst;
|
||||||
|
d->nr_sectors = s->nr_sectors;
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (n > src->nr_segments)
|
if (n > src->nr_segments)
|
||||||
n = src->nr_segments;
|
n = src->nr_segments;
|
||||||
for (i = 0; i < n; i++)
|
for (i = 0; i < n; i++)
|
||||||
@@ -94,6 +100,12 @@ static inline void blkif_get_x86_64_req(blkif_request_t *dst, blkif_x86_64_reque
|
|||||||
dst->handle = src->handle;
|
dst->handle = src->handle;
|
||||||
dst->id = src->id;
|
dst->id = src->id;
|
||||||
dst->sector_number = src->sector_number;
|
dst->sector_number = src->sector_number;
|
||||||
|
if (src->operation == BLKIF_OP_DISCARD) {
|
||||||
|
struct blkif_request_discard *s = (void *)src;
|
||||||
|
struct blkif_request_discard *d = (void *)dst;
|
||||||
|
d->nr_sectors = s->nr_sectors;
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (n > src->nr_segments)
|
if (n > src->nr_segments)
|
||||||
n = src->nr_segments;
|
n = src->nr_segments;
|
||||||
for (i = 0; i < n; i++)
|
for (i = 0; i < n; i++)
|
||||||
|
|||||||
@@ -114,6 +114,7 @@ struct XenBlkDev {
|
|||||||
int requests_finished;
|
int requests_finished;
|
||||||
|
|
||||||
/* Persistent grants extension */
|
/* Persistent grants extension */
|
||||||
|
gboolean feature_discard;
|
||||||
gboolean feature_persistent;
|
gboolean feature_persistent;
|
||||||
GTree *persistent_gnts;
|
GTree *persistent_gnts;
|
||||||
unsigned int persistent_gnt_count;
|
unsigned int persistent_gnt_count;
|
||||||
@@ -253,6 +254,8 @@ static int ioreq_parse(struct ioreq *ioreq)
|
|||||||
case BLKIF_OP_WRITE:
|
case BLKIF_OP_WRITE:
|
||||||
ioreq->prot = PROT_READ; /* from memory */
|
ioreq->prot = PROT_READ; /* from memory */
|
||||||
break;
|
break;
|
||||||
|
case BLKIF_OP_DISCARD:
|
||||||
|
return 0;
|
||||||
default:
|
default:
|
||||||
xen_be_printf(&blkdev->xendev, 0, "error: unknown operation (%d)\n",
|
xen_be_printf(&blkdev->xendev, 0, "error: unknown operation (%d)\n",
|
||||||
ioreq->req.operation);
|
ioreq->req.operation);
|
||||||
@@ -492,6 +495,7 @@ static void qemu_aio_complete(void *opaque, int ret)
|
|||||||
case BLKIF_OP_READ:
|
case BLKIF_OP_READ:
|
||||||
bdrv_acct_done(ioreq->blkdev->bs, &ioreq->acct);
|
bdrv_acct_done(ioreq->blkdev->bs, &ioreq->acct);
|
||||||
break;
|
break;
|
||||||
|
case BLKIF_OP_DISCARD:
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -532,6 +536,15 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq)
|
|||||||
&ioreq->v, ioreq->v.size / BLOCK_SIZE,
|
&ioreq->v, ioreq->v.size / BLOCK_SIZE,
|
||||||
qemu_aio_complete, ioreq);
|
qemu_aio_complete, ioreq);
|
||||||
break;
|
break;
|
||||||
|
case BLKIF_OP_DISCARD:
|
||||||
|
{
|
||||||
|
struct blkif_request_discard *discard_req = (void *)&ioreq->req;
|
||||||
|
ioreq->aio_inflight++;
|
||||||
|
bdrv_aio_discard(blkdev->bs,
|
||||||
|
discard_req->sector_number, discard_req->nr_sectors,
|
||||||
|
qemu_aio_complete, ioreq);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
/* unknown operation (shouldn't happen -- parse catches this) */
|
/* unknown operation (shouldn't happen -- parse catches this) */
|
||||||
goto err;
|
goto err;
|
||||||
@@ -710,6 +723,21 @@ static void blk_alloc(struct XenDevice *xendev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void blk_parse_discard(struct XenBlkDev *blkdev)
|
||||||
|
{
|
||||||
|
int enable;
|
||||||
|
|
||||||
|
blkdev->feature_discard = true;
|
||||||
|
|
||||||
|
if (xenstore_read_be_int(&blkdev->xendev, "discard-enable", &enable) == 0) {
|
||||||
|
blkdev->feature_discard = !!enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blkdev->feature_discard) {
|
||||||
|
xenstore_write_be_int(&blkdev->xendev, "feature-discard", 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int blk_init(struct XenDevice *xendev)
|
static int blk_init(struct XenDevice *xendev)
|
||||||
{
|
{
|
||||||
struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
|
struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
|
||||||
@@ -777,6 +805,8 @@ static int blk_init(struct XenDevice *xendev)
|
|||||||
xenstore_write_be_int(&blkdev->xendev, "feature-persistent", 1);
|
xenstore_write_be_int(&blkdev->xendev, "feature-persistent", 1);
|
||||||
xenstore_write_be_int(&blkdev->xendev, "info", info);
|
xenstore_write_be_int(&blkdev->xendev, "info", info);
|
||||||
|
|
||||||
|
blk_parse_discard(blkdev);
|
||||||
|
|
||||||
g_free(directiosafe);
|
g_free(directiosafe);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -812,6 +842,9 @@ static int blk_connect(struct XenDevice *xendev)
|
|||||||
qflags |= BDRV_O_RDWR;
|
qflags |= BDRV_O_RDWR;
|
||||||
readonly = false;
|
readonly = false;
|
||||||
}
|
}
|
||||||
|
if (blkdev->feature_discard) {
|
||||||
|
qflags |= BDRV_O_UNMAP;
|
||||||
|
}
|
||||||
|
|
||||||
/* init qemu block driver */
|
/* init qemu block driver */
|
||||||
index = (blkdev->xendev.dev - 202 * 256) / 16;
|
index = (blkdev->xendev.dev - 202 * 256) / 16;
|
||||||
|
|||||||
@@ -338,13 +338,13 @@ PropertyInfo qdev_prop_vlan = {
|
|||||||
int qdev_prop_set_drive(DeviceState *dev, const char *name,
|
int qdev_prop_set_drive(DeviceState *dev, const char *name,
|
||||||
BlockDriverState *value)
|
BlockDriverState *value)
|
||||||
{
|
{
|
||||||
Error *errp = NULL;
|
Error *err = NULL;
|
||||||
const char *bdrv_name = value ? bdrv_get_device_name(value) : "";
|
const char *bdrv_name = value ? bdrv_get_device_name(value) : "";
|
||||||
object_property_set_str(OBJECT(dev), bdrv_name,
|
object_property_set_str(OBJECT(dev), bdrv_name,
|
||||||
name, &errp);
|
name, &err);
|
||||||
if (errp) {
|
if (err) {
|
||||||
qerror_report_err(errp);
|
qerror_report_err(err);
|
||||||
error_free(errp);
|
error_free(err);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -751,6 +751,7 @@ static void set_prop_arraylen(Object *obj, Visitor *v, void *opaque,
|
|||||||
Property *prop = opaque;
|
Property *prop = opaque;
|
||||||
uint32_t *alenptr = qdev_get_prop_ptr(dev, prop);
|
uint32_t *alenptr = qdev_get_prop_ptr(dev, prop);
|
||||||
void **arrayptr = (void *)dev + prop->arrayoffset;
|
void **arrayptr = (void *)dev + prop->arrayoffset;
|
||||||
|
Error *local_err = NULL;
|
||||||
void *eltptr;
|
void *eltptr;
|
||||||
const char *arrayname;
|
const char *arrayname;
|
||||||
int i;
|
int i;
|
||||||
@@ -764,8 +765,9 @@ static void set_prop_arraylen(Object *obj, Visitor *v, void *opaque,
|
|||||||
name);
|
name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
visit_type_uint32(v, alenptr, name, errp);
|
visit_type_uint32(v, alenptr, name, &local_err);
|
||||||
if (error_is_set(errp)) {
|
if (local_err) {
|
||||||
|
error_propagate(errp, local_err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!*alenptr) {
|
if (!*alenptr) {
|
||||||
@@ -802,8 +804,9 @@ static void set_prop_arraylen(Object *obj, Visitor *v, void *opaque,
|
|||||||
arrayprop->prop.info->get,
|
arrayprop->prop.info->get,
|
||||||
arrayprop->prop.info->set,
|
arrayprop->prop.info->set,
|
||||||
array_element_release,
|
array_element_release,
|
||||||
arrayprop, errp);
|
arrayprop, &local_err);
|
||||||
if (error_is_set(errp)) {
|
if (local_err) {
|
||||||
|
error_propagate(errp, local_err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -174,14 +174,14 @@ int qdev_init(DeviceState *dev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void device_realize(DeviceState *dev, Error **err)
|
static void device_realize(DeviceState *dev, Error **errp)
|
||||||
{
|
{
|
||||||
DeviceClass *dc = DEVICE_GET_CLASS(dev);
|
DeviceClass *dc = DEVICE_GET_CLASS(dev);
|
||||||
|
|
||||||
if (dc->init) {
|
if (dc->init) {
|
||||||
int rc = dc->init(dev);
|
int rc = dc->init(dev);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
error_setg(err, "Device initialization failed.");
|
error_setg(errp, "Device initialization failed.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -504,14 +504,14 @@ static void bus_unparent(Object *obj)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool bus_get_realized(Object *obj, Error **err)
|
static bool bus_get_realized(Object *obj, Error **errp)
|
||||||
{
|
{
|
||||||
BusState *bus = BUS(obj);
|
BusState *bus = BUS(obj);
|
||||||
|
|
||||||
return bus->realized;
|
return bus->realized;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bus_set_realized(Object *obj, bool value, Error **err)
|
static void bus_set_realized(Object *obj, bool value, Error **errp)
|
||||||
{
|
{
|
||||||
BusState *bus = BUS(obj);
|
BusState *bus = BUS(obj);
|
||||||
BusClass *bc = BUS_GET_CLASS(bus);
|
BusClass *bc = BUS_GET_CLASS(bus);
|
||||||
@@ -540,7 +540,7 @@ static void bus_set_realized(Object *obj, bool value, Error **err)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
error_propagate(err, local_err);
|
error_propagate(errp, local_err);
|
||||||
}
|
}
|
||||||
|
|
||||||
void qbus_create_inplace(void *bus, size_t size, const char *typename,
|
void qbus_create_inplace(void *bus, size_t size, const char *typename,
|
||||||
@@ -660,8 +660,8 @@ static void qdev_get_legacy_property(Object *obj, Visitor *v, void *opaque,
|
|||||||
* Legacy properties are string versions of other OOM properties. The format
|
* Legacy properties are string versions of other OOM properties. The format
|
||||||
* of the string depends on the property type.
|
* of the string depends on the property type.
|
||||||
*/
|
*/
|
||||||
void qdev_property_add_legacy(DeviceState *dev, Property *prop,
|
static void qdev_property_add_legacy(DeviceState *dev, Property *prop,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
gchar *name;
|
gchar *name;
|
||||||
|
|
||||||
@@ -724,13 +724,13 @@ void qdev_property_add_static(DeviceState *dev, Property *prop,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool device_get_realized(Object *obj, Error **err)
|
static bool device_get_realized(Object *obj, Error **errp)
|
||||||
{
|
{
|
||||||
DeviceState *dev = DEVICE(obj);
|
DeviceState *dev = DEVICE(obj);
|
||||||
return dev->realized;
|
return dev->realized;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void device_set_realized(Object *obj, bool value, Error **err)
|
static void device_set_realized(Object *obj, bool value, Error **errp)
|
||||||
{
|
{
|
||||||
DeviceState *dev = DEVICE(obj);
|
DeviceState *dev = DEVICE(obj);
|
||||||
DeviceClass *dc = DEVICE_GET_CLASS(dev);
|
DeviceClass *dc = DEVICE_GET_CLASS(dev);
|
||||||
@@ -738,7 +738,7 @@ static void device_set_realized(Object *obj, bool value, Error **err)
|
|||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
|
|
||||||
if (dev->hotplugged && !dc->hotpluggable) {
|
if (dev->hotplugged && !dc->hotpluggable) {
|
||||||
error_set(err, QERR_DEVICE_NO_HOTPLUG, object_get_typename(obj));
|
error_set(errp, QERR_DEVICE_NO_HOTPLUG, object_get_typename(obj));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -797,14 +797,14 @@ static void device_set_realized(Object *obj, bool value, Error **err)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (local_err != NULL) {
|
if (local_err != NULL) {
|
||||||
error_propagate(err, local_err);
|
error_propagate(errp, local_err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev->realized = value;
|
dev->realized = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool device_get_hotpluggable(Object *obj, Error **err)
|
static bool device_get_hotpluggable(Object *obj, Error **errp)
|
||||||
{
|
{
|
||||||
DeviceClass *dc = DEVICE_GET_CLASS(obj);
|
DeviceClass *dc = DEVICE_GET_CLASS(obj);
|
||||||
DeviceState *dev = DEVICE(obj);
|
DeviceState *dev = DEVICE(obj);
|
||||||
|
|||||||
@@ -2055,7 +2055,6 @@ static int qxl_init_primary(PCIDevice *dev)
|
|||||||
{
|
{
|
||||||
PCIQXLDevice *qxl = DO_UPCAST(PCIQXLDevice, pci, dev);
|
PCIQXLDevice *qxl = DO_UPCAST(PCIQXLDevice, pci, dev);
|
||||||
VGACommonState *vga = &qxl->vga;
|
VGACommonState *vga = &qxl->vga;
|
||||||
PortioList *qxl_vga_port_list = g_new(PortioList, 1);
|
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
qxl->id = 0;
|
qxl->id = 0;
|
||||||
@@ -2064,10 +2063,10 @@ static int qxl_init_primary(PCIDevice *dev)
|
|||||||
vga_common_init(vga, OBJECT(dev), true);
|
vga_common_init(vga, OBJECT(dev), true);
|
||||||
vga_init(vga, OBJECT(dev),
|
vga_init(vga, OBJECT(dev),
|
||||||
pci_address_space(dev), pci_address_space_io(dev), false);
|
pci_address_space(dev), pci_address_space_io(dev), false);
|
||||||
portio_list_init(qxl_vga_port_list, OBJECT(dev), qxl_vga_portio_list,
|
portio_list_init(&qxl->vga_port_list, OBJECT(dev), qxl_vga_portio_list,
|
||||||
vga, "vga");
|
vga, "vga");
|
||||||
portio_list_set_flush_coalesced(qxl_vga_port_list);
|
portio_list_set_flush_coalesced(&qxl->vga_port_list);
|
||||||
portio_list_add(qxl_vga_port_list, pci_address_space_io(dev), 0x3b0);
|
portio_list_add(&qxl->vga_port_list, pci_address_space_io(dev), 0x3b0);
|
||||||
|
|
||||||
vga->con = graphic_console_init(DEVICE(dev), 0, &qxl_ops, qxl);
|
vga->con = graphic_console_init(DEVICE(dev), 0, &qxl_ops, qxl);
|
||||||
qemu_spice_display_init_common(&qxl->ssd);
|
qemu_spice_display_init_common(&qxl->ssd);
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ enum qxl_mode {
|
|||||||
|
|
||||||
typedef struct PCIQXLDevice {
|
typedef struct PCIQXLDevice {
|
||||||
PCIDevice pci;
|
PCIDevice pci;
|
||||||
|
PortioList vga_port_list;
|
||||||
SimpleSpiceDisplay ssd;
|
SimpleSpiceDisplay ssd;
|
||||||
int id;
|
int id;
|
||||||
uint32_t debug;
|
uint32_t debug;
|
||||||
|
|||||||
@@ -312,18 +312,42 @@ static int ssd0323_load(QEMUFile *f, void *opaque, int version_id)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
s->cmd_len = qemu_get_be32(f);
|
s->cmd_len = qemu_get_be32(f);
|
||||||
|
if (s->cmd_len < 0 || s->cmd_len > ARRAY_SIZE(s->cmd_data)) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
s->cmd = qemu_get_be32(f);
|
s->cmd = qemu_get_be32(f);
|
||||||
for (i = 0; i < 8; i++)
|
for (i = 0; i < 8; i++)
|
||||||
s->cmd_data[i] = qemu_get_be32(f);
|
s->cmd_data[i] = qemu_get_be32(f);
|
||||||
s->row = qemu_get_be32(f);
|
s->row = qemu_get_be32(f);
|
||||||
|
if (s->row < 0 || s->row >= 80) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
s->row_start = qemu_get_be32(f);
|
s->row_start = qemu_get_be32(f);
|
||||||
|
if (s->row_start < 0 || s->row_start >= 80) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
s->row_end = qemu_get_be32(f);
|
s->row_end = qemu_get_be32(f);
|
||||||
|
if (s->row_end < 0 || s->row_end >= 80) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
s->col = qemu_get_be32(f);
|
s->col = qemu_get_be32(f);
|
||||||
|
if (s->col < 0 || s->col >= 64) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
s->col_start = qemu_get_be32(f);
|
s->col_start = qemu_get_be32(f);
|
||||||
|
if (s->col_start < 0 || s->col_start >= 64) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
s->col_end = qemu_get_be32(f);
|
s->col_end = qemu_get_be32(f);
|
||||||
|
if (s->col_end < 0 || s->col_end >= 64) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
s->redraw = qemu_get_be32(f);
|
s->redraw = qemu_get_be32(f);
|
||||||
s->remap = qemu_get_be32(f);
|
s->remap = qemu_get_be32(f);
|
||||||
s->mode = qemu_get_be32(f);
|
s->mode = qemu_get_be32(f);
|
||||||
|
if (s->mode != SSD0323_CMD && s->mode != SSD0323_DATA) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
qemu_get_buffer(f, s->framebuffer, sizeof(s->framebuffer));
|
qemu_get_buffer(f, s->framebuffer, sizeof(s->framebuffer));
|
||||||
|
|
||||||
ss->cs = qemu_get_be32(f);
|
ss->cs = qemu_get_be32(f);
|
||||||
|
|||||||
@@ -2355,8 +2355,6 @@ void vga_init(VGACommonState *s, Object *obj, MemoryRegion *address_space,
|
|||||||
{
|
{
|
||||||
MemoryRegion *vga_io_memory;
|
MemoryRegion *vga_io_memory;
|
||||||
const MemoryRegionPortio *vga_ports, *vbe_ports;
|
const MemoryRegionPortio *vga_ports, *vbe_ports;
|
||||||
PortioList *vga_port_list = g_new(PortioList, 1);
|
|
||||||
PortioList *vbe_port_list = g_new(PortioList, 1);
|
|
||||||
|
|
||||||
qemu_register_reset(vga_reset, s);
|
qemu_register_reset(vga_reset, s);
|
||||||
|
|
||||||
@@ -2371,13 +2369,13 @@ void vga_init(VGACommonState *s, Object *obj, MemoryRegion *address_space,
|
|||||||
1);
|
1);
|
||||||
memory_region_set_coalescing(vga_io_memory);
|
memory_region_set_coalescing(vga_io_memory);
|
||||||
if (init_vga_ports) {
|
if (init_vga_ports) {
|
||||||
portio_list_init(vga_port_list, obj, vga_ports, s, "vga");
|
portio_list_init(&s->vga_port_list, obj, vga_ports, s, "vga");
|
||||||
portio_list_set_flush_coalesced(vga_port_list);
|
portio_list_set_flush_coalesced(&s->vga_port_list);
|
||||||
portio_list_add(vga_port_list, address_space_io, 0x3b0);
|
portio_list_add(&s->vga_port_list, address_space_io, 0x3b0);
|
||||||
}
|
}
|
||||||
if (vbe_ports) {
|
if (vbe_ports) {
|
||||||
portio_list_init(vbe_port_list, obj, vbe_ports, s, "vbe");
|
portio_list_init(&s->vbe_port_list, obj, vbe_ports, s, "vbe");
|
||||||
portio_list_add(vbe_port_list, address_space_io, 0x1ce);
|
portio_list_add(&s->vbe_port_list, address_space_io, 0x1ce);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -124,6 +124,8 @@ typedef struct VGACommonState {
|
|||||||
void (*get_resolution)(struct VGACommonState *s,
|
void (*get_resolution)(struct VGACommonState *s,
|
||||||
int *pwidth,
|
int *pwidth,
|
||||||
int *pheight);
|
int *pheight);
|
||||||
|
PortioList vga_port_list;
|
||||||
|
PortioList vbe_port_list;
|
||||||
/* bochs vbe state */
|
/* bochs vbe state */
|
||||||
uint16_t vbe_index;
|
uint16_t vbe_index;
|
||||||
uint16_t vbe_regs[VBE_DISPI_INDEX_NB];
|
uint16_t vbe_regs[VBE_DISPI_INDEX_NB];
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ do { fprintf(stderr, "i82374 ERROR: " fmt , ## __VA_ARGS__); } while (0)
|
|||||||
typedef struct I82374State {
|
typedef struct I82374State {
|
||||||
uint8_t commands[8];
|
uint8_t commands[8];
|
||||||
qemu_irq out;
|
qemu_irq out;
|
||||||
|
PortioList port_list;
|
||||||
} I82374State;
|
} I82374State;
|
||||||
|
|
||||||
static const VMStateDescription vmstate_i82374 = {
|
static const VMStateDescription vmstate_i82374 = {
|
||||||
@@ -137,10 +138,10 @@ static void i82374_isa_realize(DeviceState *dev, Error **errp)
|
|||||||
{
|
{
|
||||||
ISAi82374State *isa = I82374(dev);
|
ISAi82374State *isa = I82374(dev);
|
||||||
I82374State *s = &isa->state;
|
I82374State *s = &isa->state;
|
||||||
PortioList *port_list = g_new(PortioList, 1);
|
|
||||||
|
|
||||||
portio_list_init(port_list, OBJECT(isa), i82374_portio_list, s, "i82374");
|
portio_list_init(&s->port_list, OBJECT(isa), i82374_portio_list, s,
|
||||||
portio_list_add(port_list, isa_address_space_io(&isa->parent_obj),
|
"i82374");
|
||||||
|
portio_list_add(&s->port_list, isa_address_space_io(&isa->parent_obj),
|
||||||
isa->iobase);
|
isa->iobase);
|
||||||
|
|
||||||
i82374_realize(s, errp);
|
i82374_realize(s, errp);
|
||||||
|
|||||||
@@ -534,24 +534,24 @@ static void xilinx_axidma_realize(DeviceState *dev, Error **errp)
|
|||||||
XilinxAXIDMAStreamSlave *ds = XILINX_AXI_DMA_DATA_STREAM(&s->rx_data_dev);
|
XilinxAXIDMAStreamSlave *ds = XILINX_AXI_DMA_DATA_STREAM(&s->rx_data_dev);
|
||||||
XilinxAXIDMAStreamSlave *cs = XILINX_AXI_DMA_CONTROL_STREAM(
|
XilinxAXIDMAStreamSlave *cs = XILINX_AXI_DMA_CONTROL_STREAM(
|
||||||
&s->rx_control_dev);
|
&s->rx_control_dev);
|
||||||
Error *local_errp = NULL;
|
Error *local_err = NULL;
|
||||||
|
|
||||||
object_property_add_link(OBJECT(ds), "dma", TYPE_XILINX_AXI_DMA,
|
object_property_add_link(OBJECT(ds), "dma", TYPE_XILINX_AXI_DMA,
|
||||||
(Object **)&ds->dma,
|
(Object **)&ds->dma,
|
||||||
object_property_allow_set_link,
|
object_property_allow_set_link,
|
||||||
OBJ_PROP_LINK_UNREF_ON_RELEASE,
|
OBJ_PROP_LINK_UNREF_ON_RELEASE,
|
||||||
&local_errp);
|
&local_err);
|
||||||
object_property_add_link(OBJECT(cs), "dma", TYPE_XILINX_AXI_DMA,
|
object_property_add_link(OBJECT(cs), "dma", TYPE_XILINX_AXI_DMA,
|
||||||
(Object **)&cs->dma,
|
(Object **)&cs->dma,
|
||||||
object_property_allow_set_link,
|
object_property_allow_set_link,
|
||||||
OBJ_PROP_LINK_UNREF_ON_RELEASE,
|
OBJ_PROP_LINK_UNREF_ON_RELEASE,
|
||||||
&local_errp);
|
&local_err);
|
||||||
if (local_errp) {
|
if (local_err) {
|
||||||
goto xilinx_axidma_realize_fail;
|
goto xilinx_axidma_realize_fail;
|
||||||
}
|
}
|
||||||
object_property_set_link(OBJECT(ds), OBJECT(s), "dma", &local_errp);
|
object_property_set_link(OBJECT(ds), OBJECT(s), "dma", &local_err);
|
||||||
object_property_set_link(OBJECT(cs), OBJECT(s), "dma", &local_errp);
|
object_property_set_link(OBJECT(cs), OBJECT(s), "dma", &local_err);
|
||||||
if (local_errp) {
|
if (local_err) {
|
||||||
goto xilinx_axidma_realize_fail;
|
goto xilinx_axidma_realize_fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -567,7 +567,7 @@ static void xilinx_axidma_realize(DeviceState *dev, Error **errp)
|
|||||||
|
|
||||||
xilinx_axidma_realize_fail:
|
xilinx_axidma_realize_fail:
|
||||||
if (!*errp) {
|
if (!*errp) {
|
||||||
*errp = local_errp;
|
*errp = local_err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -203,6 +203,15 @@ static bool is_version_0 (void *opaque, int version_id)
|
|||||||
return version_id == 0;
|
return version_id == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool vmstate_scoop_validate(void *opaque, int version_id)
|
||||||
|
{
|
||||||
|
ScoopInfo *s = opaque;
|
||||||
|
|
||||||
|
return !(s->prev_level & 0xffff0000) &&
|
||||||
|
!(s->gpio_level & 0xffff0000) &&
|
||||||
|
!(s->gpio_dir & 0xffff0000);
|
||||||
|
}
|
||||||
|
|
||||||
static const VMStateDescription vmstate_scoop_regs = {
|
static const VMStateDescription vmstate_scoop_regs = {
|
||||||
.name = "scoop",
|
.name = "scoop",
|
||||||
.version_id = 1,
|
.version_id = 1,
|
||||||
@@ -215,6 +224,7 @@ static const VMStateDescription vmstate_scoop_regs = {
|
|||||||
VMSTATE_UINT32(gpio_level, ScoopInfo),
|
VMSTATE_UINT32(gpio_level, ScoopInfo),
|
||||||
VMSTATE_UINT32(gpio_dir, ScoopInfo),
|
VMSTATE_UINT32(gpio_dir, ScoopInfo),
|
||||||
VMSTATE_UINT32(prev_level, ScoopInfo),
|
VMSTATE_UINT32(prev_level, ScoopInfo),
|
||||||
|
VMSTATE_VALIDATE("irq levels are 16 bit", vmstate_scoop_validate),
|
||||||
VMSTATE_UINT16(mcr, ScoopInfo),
|
VMSTATE_UINT16(mcr, ScoopInfo),
|
||||||
VMSTATE_UINT16(cdr, ScoopInfo),
|
VMSTATE_UINT16(cdr, ScoopInfo),
|
||||||
VMSTATE_UINT16(ccr, ScoopInfo),
|
VMSTATE_UINT16(ccr, ScoopInfo),
|
||||||
|
|||||||
@@ -60,59 +60,78 @@ static void smb_transaction(PMSMBus *s)
|
|||||||
uint8_t cmd = s->smb_cmd;
|
uint8_t cmd = s->smb_cmd;
|
||||||
uint8_t addr = s->smb_addr >> 1;
|
uint8_t addr = s->smb_addr >> 1;
|
||||||
I2CBus *bus = s->smbus;
|
I2CBus *bus = s->smbus;
|
||||||
|
int ret;
|
||||||
|
|
||||||
SMBUS_DPRINTF("SMBus trans addr=0x%02x prot=0x%02x\n", addr, prot);
|
SMBUS_DPRINTF("SMBus trans addr=0x%02x prot=0x%02x\n", addr, prot);
|
||||||
/* Transaction isn't exec if STS_DEV_ERR bit set */
|
/* Transaction isn't exec if STS_DEV_ERR bit set */
|
||||||
if ((s->smb_stat & STS_DEV_ERR) != 0) {
|
if ((s->smb_stat & STS_DEV_ERR) != 0) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
switch(prot) {
|
switch(prot) {
|
||||||
case 0x0:
|
case 0x0:
|
||||||
smbus_quick_command(bus, addr, read);
|
ret = smbus_quick_command(bus, addr, read);
|
||||||
s->smb_stat |= STS_BYTE_DONE | STS_INTR;
|
goto done;
|
||||||
break;
|
|
||||||
case 0x1:
|
case 0x1:
|
||||||
if (read) {
|
if (read) {
|
||||||
s->smb_data0 = smbus_receive_byte(bus, addr);
|
ret = smbus_receive_byte(bus, addr);
|
||||||
|
goto data8;
|
||||||
} else {
|
} else {
|
||||||
smbus_send_byte(bus, addr, cmd);
|
ret = smbus_send_byte(bus, addr, cmd);
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
s->smb_stat |= STS_BYTE_DONE | STS_INTR;
|
|
||||||
break;
|
|
||||||
case 0x2:
|
case 0x2:
|
||||||
if (read) {
|
if (read) {
|
||||||
s->smb_data0 = smbus_read_byte(bus, addr, cmd);
|
ret = smbus_read_byte(bus, addr, cmd);
|
||||||
|
goto data8;
|
||||||
} else {
|
} else {
|
||||||
smbus_write_byte(bus, addr, cmd, s->smb_data0);
|
ret = smbus_write_byte(bus, addr, cmd, s->smb_data0);
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
s->smb_stat |= STS_BYTE_DONE | STS_INTR;
|
|
||||||
break;
|
break;
|
||||||
case 0x3:
|
case 0x3:
|
||||||
if (read) {
|
if (read) {
|
||||||
uint16_t val;
|
ret = smbus_read_word(bus, addr, cmd);
|
||||||
val = smbus_read_word(bus, addr, cmd);
|
goto data16;
|
||||||
s->smb_data0 = val;
|
|
||||||
s->smb_data1 = val >> 8;
|
|
||||||
} else {
|
} else {
|
||||||
smbus_write_word(bus, addr, cmd, (s->smb_data1 << 8) | s->smb_data0);
|
ret = smbus_write_word(bus, addr, cmd, (s->smb_data1 << 8) | s->smb_data0);
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
s->smb_stat |= STS_BYTE_DONE | STS_INTR;
|
|
||||||
break;
|
break;
|
||||||
case 0x5:
|
case 0x5:
|
||||||
if (read) {
|
if (read) {
|
||||||
s->smb_data0 = smbus_read_block(bus, addr, cmd, s->smb_data);
|
ret = smbus_read_block(bus, addr, cmd, s->smb_data);
|
||||||
|
goto data8;
|
||||||
} else {
|
} else {
|
||||||
smbus_write_block(bus, addr, cmd, s->smb_data, s->smb_data0);
|
ret = smbus_write_block(bus, addr, cmd, s->smb_data, s->smb_data0);
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
s->smb_stat |= STS_BYTE_DONE | STS_INTR;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
abort();
|
||||||
|
|
||||||
|
data16:
|
||||||
|
if (ret < 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
s->smb_data1 = ret >> 8;
|
||||||
|
data8:
|
||||||
|
if (ret < 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
s->smb_data0 = ret;
|
||||||
|
done:
|
||||||
|
if (ret < 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
s->smb_stat |= STS_BYTE_DONE | STS_INTR;
|
||||||
return;
|
return;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
s->smb_stat |= STS_DEV_ERR;
|
s->smb_stat |= STS_DEV_ERR;
|
||||||
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void smb_ioport_writeb(void *opaque, hwaddr addr, uint64_t val,
|
static void smb_ioport_writeb(void *opaque, hwaddr addr, uint64_t val,
|
||||||
|
|||||||
@@ -208,34 +208,44 @@ static int smbus_device_init(I2CSlave *i2c)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Master device commands. */
|
/* Master device commands. */
|
||||||
void smbus_quick_command(I2CBus *bus, uint8_t addr, int read)
|
int smbus_quick_command(I2CBus *bus, uint8_t addr, int read)
|
||||||
{
|
{
|
||||||
i2c_start_transfer(bus, addr, read);
|
if (i2c_start_transfer(bus, addr, read)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
i2c_end_transfer(bus);
|
i2c_end_transfer(bus);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t smbus_receive_byte(I2CBus *bus, uint8_t addr)
|
int smbus_receive_byte(I2CBus *bus, uint8_t addr)
|
||||||
{
|
{
|
||||||
uint8_t data;
|
uint8_t data;
|
||||||
|
|
||||||
i2c_start_transfer(bus, addr, 1);
|
if (i2c_start_transfer(bus, addr, 1)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
data = i2c_recv(bus);
|
data = i2c_recv(bus);
|
||||||
i2c_nack(bus);
|
i2c_nack(bus);
|
||||||
i2c_end_transfer(bus);
|
i2c_end_transfer(bus);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void smbus_send_byte(I2CBus *bus, uint8_t addr, uint8_t data)
|
int smbus_send_byte(I2CBus *bus, uint8_t addr, uint8_t data)
|
||||||
{
|
{
|
||||||
i2c_start_transfer(bus, addr, 0);
|
if (i2c_start_transfer(bus, addr, 0)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
i2c_send(bus, data);
|
i2c_send(bus, data);
|
||||||
i2c_end_transfer(bus);
|
i2c_end_transfer(bus);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t smbus_read_byte(I2CBus *bus, uint8_t addr, uint8_t command)
|
int smbus_read_byte(I2CBus *bus, uint8_t addr, uint8_t command)
|
||||||
{
|
{
|
||||||
uint8_t data;
|
uint8_t data;
|
||||||
i2c_start_transfer(bus, addr, 0);
|
if (i2c_start_transfer(bus, addr, 0)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
i2c_send(bus, command);
|
i2c_send(bus, command);
|
||||||
i2c_start_transfer(bus, addr, 1);
|
i2c_start_transfer(bus, addr, 1);
|
||||||
data = i2c_recv(bus);
|
data = i2c_recv(bus);
|
||||||
@@ -244,18 +254,23 @@ uint8_t smbus_read_byte(I2CBus *bus, uint8_t addr, uint8_t command)
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void smbus_write_byte(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t data)
|
int smbus_write_byte(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t data)
|
||||||
{
|
{
|
||||||
i2c_start_transfer(bus, addr, 0);
|
if (i2c_start_transfer(bus, addr, 0)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
i2c_send(bus, command);
|
i2c_send(bus, command);
|
||||||
i2c_send(bus, data);
|
i2c_send(bus, data);
|
||||||
i2c_end_transfer(bus);
|
i2c_end_transfer(bus);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t smbus_read_word(I2CBus *bus, uint8_t addr, uint8_t command)
|
int smbus_read_word(I2CBus *bus, uint8_t addr, uint8_t command)
|
||||||
{
|
{
|
||||||
uint16_t data;
|
uint16_t data;
|
||||||
i2c_start_transfer(bus, addr, 0);
|
if (i2c_start_transfer(bus, addr, 0)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
i2c_send(bus, command);
|
i2c_send(bus, command);
|
||||||
i2c_start_transfer(bus, addr, 1);
|
i2c_start_transfer(bus, addr, 1);
|
||||||
data = i2c_recv(bus);
|
data = i2c_recv(bus);
|
||||||
@@ -265,13 +280,16 @@ uint16_t smbus_read_word(I2CBus *bus, uint8_t addr, uint8_t command)
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void smbus_write_word(I2CBus *bus, uint8_t addr, uint8_t command, uint16_t data)
|
int smbus_write_word(I2CBus *bus, uint8_t addr, uint8_t command, uint16_t data)
|
||||||
{
|
{
|
||||||
i2c_start_transfer(bus, addr, 0);
|
if (i2c_start_transfer(bus, addr, 0)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
i2c_send(bus, command);
|
i2c_send(bus, command);
|
||||||
i2c_send(bus, data & 0xff);
|
i2c_send(bus, data & 0xff);
|
||||||
i2c_send(bus, data >> 8);
|
i2c_send(bus, data >> 8);
|
||||||
i2c_end_transfer(bus);
|
i2c_end_transfer(bus);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int smbus_read_block(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t *data)
|
int smbus_read_block(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t *data)
|
||||||
@@ -279,33 +297,41 @@ int smbus_read_block(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t *data)
|
|||||||
int len;
|
int len;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
i2c_start_transfer(bus, addr, 0);
|
if (i2c_start_transfer(bus, addr, 0)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
i2c_send(bus, command);
|
i2c_send(bus, command);
|
||||||
i2c_start_transfer(bus, addr, 1);
|
i2c_start_transfer(bus, addr, 1);
|
||||||
len = i2c_recv(bus);
|
len = i2c_recv(bus);
|
||||||
if (len > 32)
|
if (len > 32) {
|
||||||
len = 0;
|
len = 0;
|
||||||
for (i = 0; i < len; i++)
|
}
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
data[i] = i2c_recv(bus);
|
data[i] = i2c_recv(bus);
|
||||||
|
}
|
||||||
i2c_nack(bus);
|
i2c_nack(bus);
|
||||||
i2c_end_transfer(bus);
|
i2c_end_transfer(bus);
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
void smbus_write_block(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t *data,
|
int smbus_write_block(I2CBus *bus, uint8_t addr, uint8_t command, uint8_t *data,
|
||||||
int len)
|
int len)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (len > 32)
|
if (len > 32)
|
||||||
len = 32;
|
len = 32;
|
||||||
|
|
||||||
i2c_start_transfer(bus, addr, 0);
|
if (i2c_start_transfer(bus, addr, 0)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
i2c_send(bus, command);
|
i2c_send(bus, command);
|
||||||
i2c_send(bus, len);
|
i2c_send(bus, len);
|
||||||
for (i = 0; i < len; i++)
|
for (i = 0; i < len; i++) {
|
||||||
i2c_send(bus, data[i]);
|
i2c_send(bus, data[i]);
|
||||||
|
}
|
||||||
i2c_end_transfer(bus);
|
i2c_end_transfer(bus);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void smbus_device_class_init(ObjectClass *klass, void *data)
|
static void smbus_device_class_init(ObjectClass *klass, void *data)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ obj-$(CONFIG_KVM) += kvm/
|
|||||||
obj-y += multiboot.o smbios.o
|
obj-y += multiboot.o smbios.o
|
||||||
obj-y += pc.o pc_piix.o pc_q35.o
|
obj-y += pc.o pc_piix.o pc_q35.o
|
||||||
obj-y += pc_sysfw.o
|
obj-y += pc_sysfw.o
|
||||||
obj-$(CONFIG_XEN) += xen_domainbuild.o xen_machine_pv.o
|
obj-$(CONFIG_XEN) += ../xenpv/ xen/
|
||||||
|
|
||||||
obj-y += kvmvapic.o
|
obj-y += kvmvapic.o
|
||||||
obj-y += acpi-build.o
|
obj-y += acpi-build.o
|
||||||
|
|||||||
@@ -156,18 +156,21 @@ static void acpi_get_pm_info(AcpiPmInfo *pm)
|
|||||||
} else {
|
} else {
|
||||||
pm->s3_disabled = false;
|
pm->s3_disabled = false;
|
||||||
}
|
}
|
||||||
|
qobject_decref(o);
|
||||||
o = object_property_get_qobject(obj, ACPI_PM_PROP_S4_DISABLED, NULL);
|
o = object_property_get_qobject(obj, ACPI_PM_PROP_S4_DISABLED, NULL);
|
||||||
if (o) {
|
if (o) {
|
||||||
pm->s4_disabled = qint_get_int(qobject_to_qint(o));
|
pm->s4_disabled = qint_get_int(qobject_to_qint(o));
|
||||||
} else {
|
} else {
|
||||||
pm->s4_disabled = false;
|
pm->s4_disabled = false;
|
||||||
}
|
}
|
||||||
|
qobject_decref(o);
|
||||||
o = object_property_get_qobject(obj, ACPI_PM_PROP_S4_VAL, NULL);
|
o = object_property_get_qobject(obj, ACPI_PM_PROP_S4_VAL, NULL);
|
||||||
if (o) {
|
if (o) {
|
||||||
pm->s4_val = qint_get_int(qobject_to_qint(o));
|
pm->s4_val = qint_get_int(qobject_to_qint(o));
|
||||||
} else {
|
} else {
|
||||||
pm->s4_val = false;
|
pm->s4_val = false;
|
||||||
}
|
}
|
||||||
|
qobject_decref(o);
|
||||||
|
|
||||||
/* Fill in mandatory properties */
|
/* Fill in mandatory properties */
|
||||||
pm->sci_int = object_property_get_int(obj, ACPI_PM_PROP_SCI_INT, NULL);
|
pm->sci_int = object_property_get_int(obj, ACPI_PM_PROP_SCI_INT, NULL);
|
||||||
@@ -973,6 +976,7 @@ static void build_pci_bus_end(PCIBus *bus, void *bus_state)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qobject_decref(bsel);
|
||||||
build_free_array(bus_table);
|
build_free_array(bus_table);
|
||||||
build_pci_bus_state_cleanup(child);
|
build_pci_bus_state_cleanup(child);
|
||||||
g_free(child);
|
g_free(child);
|
||||||
@@ -1362,10 +1366,12 @@ static bool acpi_get_mcfg(AcpiMcfgInfo *mcfg)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
mcfg->mcfg_base = qint_get_int(qobject_to_qint(o));
|
mcfg->mcfg_base = qint_get_int(qobject_to_qint(o));
|
||||||
|
qobject_decref(o);
|
||||||
|
|
||||||
o = object_property_get_qobject(pci_host, PCIE_HOST_MCFG_SIZE, NULL);
|
o = object_property_get_qobject(pci_host, PCIE_HOST_MCFG_SIZE, NULL);
|
||||||
assert(o);
|
assert(o);
|
||||||
mcfg->mcfg_size = qint_get_int(qobject_to_qint(o));
|
mcfg->mcfg_size = qint_get_int(qobject_to_qint(o));
|
||||||
|
qobject_decref(o);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1410,15 +1416,16 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
|
|||||||
/* ACPI tables pointed to by RSDT */
|
/* ACPI tables pointed to by RSDT */
|
||||||
acpi_add_table(table_offsets, tables->table_data);
|
acpi_add_table(table_offsets, tables->table_data);
|
||||||
build_fadt(tables->table_data, tables->linker, &pm, facs, dsdt);
|
build_fadt(tables->table_data, tables->linker, &pm, facs, dsdt);
|
||||||
acpi_add_table(table_offsets, tables->table_data);
|
|
||||||
|
|
||||||
|
acpi_add_table(table_offsets, tables->table_data);
|
||||||
build_ssdt(tables->table_data, tables->linker, &cpu, &pm, &misc, &pci,
|
build_ssdt(tables->table_data, tables->linker, &cpu, &pm, &misc, &pci,
|
||||||
guest_info);
|
guest_info);
|
||||||
acpi_add_table(table_offsets, tables->table_data);
|
|
||||||
|
|
||||||
build_madt(tables->table_data, tables->linker, &cpu, guest_info);
|
|
||||||
acpi_add_table(table_offsets, tables->table_data);
|
acpi_add_table(table_offsets, tables->table_data);
|
||||||
|
build_madt(tables->table_data, tables->linker, &cpu, guest_info);
|
||||||
|
|
||||||
if (misc.has_hpet) {
|
if (misc.has_hpet) {
|
||||||
|
acpi_add_table(table_offsets, tables->table_data);
|
||||||
build_hpet(tables->table_data, tables->linker);
|
build_hpet(tables->table_data, tables->linker);
|
||||||
}
|
}
|
||||||
if (guest_info->numa_nodes) {
|
if (guest_info->numa_nodes) {
|
||||||
|
|||||||
@@ -394,9 +394,10 @@ static uint8_t pci_find_cap_offset(PCIDevice *d, uint8_t cap, uint8_t start)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int assigned_dev_register_regions(PCIRegion *io_regions,
|
static void assigned_dev_register_regions(PCIRegion *io_regions,
|
||||||
unsigned long regions_num,
|
unsigned long regions_num,
|
||||||
AssignedDevice *pci_dev)
|
AssignedDevice *pci_dev,
|
||||||
|
Error **errp)
|
||||||
{
|
{
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
PCIRegion *cur_region = io_regions;
|
PCIRegion *cur_region = io_regions;
|
||||||
@@ -425,9 +426,9 @@ static int assigned_dev_register_regions(PCIRegion *io_regions,
|
|||||||
|
|
||||||
if (pci_dev->v_addrs[i].u.r_virtbase == MAP_FAILED) {
|
if (pci_dev->v_addrs[i].u.r_virtbase == MAP_FAILED) {
|
||||||
pci_dev->v_addrs[i].u.r_virtbase = NULL;
|
pci_dev->v_addrs[i].u.r_virtbase = NULL;
|
||||||
error_report("%s: Error: Couldn't mmap 0x%" PRIx64 "!",
|
error_setg_errno(errp, errno, "Couldn't mmap 0x%" PRIx64 "!",
|
||||||
__func__, cur_region->base_addr);
|
cur_region->base_addr);
|
||||||
return -1;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pci_dev->v_addrs[i].r_size = cur_region->size;
|
pci_dev->v_addrs[i].r_size = cur_region->size;
|
||||||
@@ -496,10 +497,10 @@ static int assigned_dev_register_regions(PCIRegion *io_regions,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* success */
|
/* success */
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_real_id(const char *devpath, const char *idname, uint16_t *val)
|
static void get_real_id(const char *devpath, const char *idname, uint16_t *val,
|
||||||
|
Error **errp)
|
||||||
{
|
{
|
||||||
FILE *f;
|
FILE *f;
|
||||||
char name[128];
|
char name[128];
|
||||||
@@ -508,39 +509,39 @@ static int get_real_id(const char *devpath, const char *idname, uint16_t *val)
|
|||||||
snprintf(name, sizeof(name), "%s%s", devpath, idname);
|
snprintf(name, sizeof(name), "%s%s", devpath, idname);
|
||||||
f = fopen(name, "r");
|
f = fopen(name, "r");
|
||||||
if (f == NULL) {
|
if (f == NULL) {
|
||||||
error_report("%s: %s: %m", __func__, name);
|
error_setg_file_open(errp, errno, name);
|
||||||
return -1;
|
return;
|
||||||
}
|
}
|
||||||
if (fscanf(f, "%li\n", &id) == 1) {
|
if (fscanf(f, "%li\n", &id) == 1) {
|
||||||
*val = id;
|
*val = id;
|
||||||
} else {
|
} else {
|
||||||
fclose(f);
|
error_setg(errp, "Failed to parse contents of '%s'", name);
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_real_vendor_id(const char *devpath, uint16_t *val)
|
static void get_real_vendor_id(const char *devpath, uint16_t *val,
|
||||||
|
Error **errp)
|
||||||
{
|
{
|
||||||
return get_real_id(devpath, "vendor", val);
|
get_real_id(devpath, "vendor", val, errp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_real_device_id(const char *devpath, uint16_t *val)
|
static void get_real_device_id(const char *devpath, uint16_t *val,
|
||||||
|
Error **errp)
|
||||||
{
|
{
|
||||||
return get_real_id(devpath, "device", val);
|
get_real_id(devpath, "device", val, errp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_real_device(AssignedDevice *pci_dev)
|
static void get_real_device(AssignedDevice *pci_dev, Error **errp)
|
||||||
{
|
{
|
||||||
char dir[128], name[128];
|
char dir[128], name[128];
|
||||||
int fd, r = 0, v;
|
int fd, r = 0;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
uint64_t start, end, size, flags;
|
uint64_t start, end, size, flags;
|
||||||
uint16_t id;
|
uint16_t id;
|
||||||
PCIRegion *rp;
|
PCIRegion *rp;
|
||||||
PCIDevRegions *dev = &pci_dev->real_device;
|
PCIDevRegions *dev = &pci_dev->real_device;
|
||||||
|
Error *local_err = NULL;
|
||||||
|
|
||||||
dev->region_number = 0;
|
dev->region_number = 0;
|
||||||
|
|
||||||
@@ -551,16 +552,19 @@ static int get_real_device(AssignedDevice *pci_dev)
|
|||||||
snprintf(name, sizeof(name), "%sconfig", dir);
|
snprintf(name, sizeof(name), "%sconfig", dir);
|
||||||
|
|
||||||
if (pci_dev->configfd_name && *pci_dev->configfd_name) {
|
if (pci_dev->configfd_name && *pci_dev->configfd_name) {
|
||||||
dev->config_fd = monitor_handle_fd_param(cur_mon, pci_dev->configfd_name);
|
dev->config_fd = monitor_handle_fd_param2(cur_mon,
|
||||||
if (dev->config_fd < 0) {
|
pci_dev->configfd_name,
|
||||||
return 1;
|
&local_err);
|
||||||
|
if (local_err) {
|
||||||
|
error_propagate(errp, local_err);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
dev->config_fd = open(name, O_RDWR);
|
dev->config_fd = open(name, O_RDWR);
|
||||||
|
|
||||||
if (dev->config_fd == -1) {
|
if (dev->config_fd == -1) {
|
||||||
error_report("%s: %s: %m", __func__, name);
|
error_setg_file_open(errp, errno, name);
|
||||||
return 1;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
again:
|
again:
|
||||||
@@ -570,7 +574,10 @@ again:
|
|||||||
if (errno == EINTR || errno == EAGAIN) {
|
if (errno == EINTR || errno == EAGAIN) {
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
error_report("%s: read failed, errno = %d", __func__, errno);
|
error_setg_errno(errp, errno, "read(\"%s\")",
|
||||||
|
(pci_dev->configfd_name && *pci_dev->configfd_name) ?
|
||||||
|
pci_dev->configfd_name : name);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Restore or clear multifunction, this is always controlled by qemu */
|
/* Restore or clear multifunction, this is always controlled by qemu */
|
||||||
@@ -590,8 +597,8 @@ again:
|
|||||||
|
|
||||||
f = fopen(name, "r");
|
f = fopen(name, "r");
|
||||||
if (f == NULL) {
|
if (f == NULL) {
|
||||||
error_report("%s: %s: %m", __func__, name);
|
error_setg_file_open(errp, errno, name);
|
||||||
return 1;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (r = 0; r < PCI_ROM_SLOT; r++) {
|
for (r = 0; r < PCI_ROM_SLOT; r++) {
|
||||||
@@ -634,17 +641,19 @@ again:
|
|||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
/* read and fill vendor ID */
|
/* read and fill vendor ID */
|
||||||
v = get_real_vendor_id(dir, &id);
|
get_real_vendor_id(dir, &id, &local_err);
|
||||||
if (v) {
|
if (local_err) {
|
||||||
return 1;
|
error_propagate(errp, local_err);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
pci_dev->dev.config[0] = id & 0xff;
|
pci_dev->dev.config[0] = id & 0xff;
|
||||||
pci_dev->dev.config[1] = (id & 0xff00) >> 8;
|
pci_dev->dev.config[1] = (id & 0xff00) >> 8;
|
||||||
|
|
||||||
/* read and fill device ID */
|
/* read and fill device ID */
|
||||||
v = get_real_device_id(dir, &id);
|
get_real_device_id(dir, &id, &local_err);
|
||||||
if (v) {
|
if (local_err) {
|
||||||
return 1;
|
error_propagate(errp, local_err);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
pci_dev->dev.config[2] = id & 0xff;
|
pci_dev->dev.config[2] = id & 0xff;
|
||||||
pci_dev->dev.config[3] = (id & 0xff00) >> 8;
|
pci_dev->dev.config[3] = (id & 0xff00) >> 8;
|
||||||
@@ -653,7 +662,6 @@ again:
|
|||||||
PCI_COMMAND_MASTER | PCI_COMMAND_INTX_DISABLE);
|
PCI_COMMAND_MASTER | PCI_COMMAND_INTX_DISABLE);
|
||||||
|
|
||||||
dev->region_number = r;
|
dev->region_number = r;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void free_msi_virqs(AssignedDevice *dev)
|
static void free_msi_virqs(AssignedDevice *dev)
|
||||||
@@ -726,11 +734,17 @@ static void free_assigned_device(AssignedDevice *dev)
|
|||||||
free_msi_virqs(dev);
|
free_msi_virqs(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void assign_failed_examine(AssignedDevice *dev)
|
/* This function tries to determine the cause of the PCI assignment failure. It
|
||||||
|
* always returns the cause as a dynamically allocated, human readable string.
|
||||||
|
* If the function fails to determine the cause for any internal reason, then
|
||||||
|
* the returned string will state that fact.
|
||||||
|
*/
|
||||||
|
static char *assign_failed_examine(const AssignedDevice *dev)
|
||||||
{
|
{
|
||||||
char name[PATH_MAX], dir[PATH_MAX], driver[PATH_MAX] = {}, *ns;
|
char name[PATH_MAX], dir[PATH_MAX], driver[PATH_MAX] = {}, *ns;
|
||||||
uint16_t vendor_id, device_id;
|
uint16_t vendor_id, device_id;
|
||||||
int r;
|
int r;
|
||||||
|
Error *local_err = NULL;
|
||||||
|
|
||||||
snprintf(dir, sizeof(dir), "/sys/bus/pci/devices/%04x:%02x:%02x.%01x/",
|
snprintf(dir, sizeof(dir), "/sys/bus/pci/devices/%04x:%02x:%02x.%01x/",
|
||||||
dev->host.domain, dev->host.bus, dev->host.slot,
|
dev->host.domain, dev->host.bus, dev->host.slot,
|
||||||
@@ -751,13 +765,17 @@ static void assign_failed_examine(AssignedDevice *dev)
|
|||||||
|
|
||||||
ns++;
|
ns++;
|
||||||
|
|
||||||
if (get_real_vendor_id(dir, &vendor_id) ||
|
if ((get_real_vendor_id(dir, &vendor_id, &local_err), local_err) ||
|
||||||
get_real_device_id(dir, &device_id)) {
|
(get_real_device_id(dir, &device_id, &local_err), local_err)) {
|
||||||
|
/* We're already analyzing an assignment error, so we suppress this
|
||||||
|
* one just like the others above.
|
||||||
|
*/
|
||||||
|
error_free(local_err);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
error_printf("*** The driver '%s' is occupying your device "
|
return g_strdup_printf(
|
||||||
"%04x:%02x:%02x.%x.\n"
|
"*** The driver '%s' is occupying your device %04x:%02x:%02x.%x.\n"
|
||||||
"***\n"
|
"***\n"
|
||||||
"*** You can try the following commands to free it:\n"
|
"*** You can try the following commands to free it:\n"
|
||||||
"***\n"
|
"***\n"
|
||||||
@@ -773,13 +791,11 @@ static void assign_failed_examine(AssignedDevice *dev)
|
|||||||
ns, dev->host.domain, dev->host.bus, dev->host.slot,
|
ns, dev->host.domain, dev->host.bus, dev->host.slot,
|
||||||
dev->host.function, vendor_id, device_id);
|
dev->host.function, vendor_id, device_id);
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
error_report("Couldn't find out why.");
|
return g_strdup("Couldn't find out why.");
|
||||||
}
|
}
|
||||||
|
|
||||||
static int assign_device(AssignedDevice *dev)
|
static void assign_device(AssignedDevice *dev, Error **errp)
|
||||||
{
|
{
|
||||||
uint32_t flags = KVM_DEV_ASSIGN_ENABLE_IOMMU;
|
uint32_t flags = KVM_DEV_ASSIGN_ENABLE_IOMMU;
|
||||||
int r;
|
int r;
|
||||||
@@ -787,15 +803,15 @@ static int assign_device(AssignedDevice *dev)
|
|||||||
/* Only pass non-zero PCI segment to capable module */
|
/* Only pass non-zero PCI segment to capable module */
|
||||||
if (!kvm_check_extension(kvm_state, KVM_CAP_PCI_SEGMENT) &&
|
if (!kvm_check_extension(kvm_state, KVM_CAP_PCI_SEGMENT) &&
|
||||||
dev->host.domain) {
|
dev->host.domain) {
|
||||||
error_report("Can't assign device inside non-zero PCI segment "
|
error_setg(errp, "Can't assign device inside non-zero PCI segment "
|
||||||
"as this KVM module doesn't support it.");
|
"as this KVM module doesn't support it.");
|
||||||
return -ENODEV;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!kvm_check_extension(kvm_state, KVM_CAP_IOMMU)) {
|
if (!kvm_check_extension(kvm_state, KVM_CAP_IOMMU)) {
|
||||||
error_report("No IOMMU found. Unable to assign device \"%s\"",
|
error_setg(errp, "No IOMMU found. Unable to assign device \"%s\"",
|
||||||
dev->dev.qdev.id);
|
dev->dev.qdev.id);
|
||||||
return -ENODEV;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dev->features & ASSIGNED_DEVICE_SHARE_INTX_MASK &&
|
if (dev->features & ASSIGNED_DEVICE_SHARE_INTX_MASK &&
|
||||||
@@ -805,36 +821,39 @@ static int assign_device(AssignedDevice *dev)
|
|||||||
|
|
||||||
r = kvm_device_pci_assign(kvm_state, &dev->host, flags, &dev->dev_id);
|
r = kvm_device_pci_assign(kvm_state, &dev->host, flags, &dev->dev_id);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
error_report("Failed to assign device \"%s\" : %s",
|
|
||||||
dev->dev.qdev.id, strerror(-r));
|
|
||||||
|
|
||||||
switch (r) {
|
switch (r) {
|
||||||
case -EBUSY:
|
case -EBUSY: {
|
||||||
assign_failed_examine(dev);
|
char *cause;
|
||||||
|
|
||||||
|
cause = assign_failed_examine(dev);
|
||||||
|
error_setg_errno(errp, -r, "Failed to assign device \"%s\"\n%s",
|
||||||
|
dev->dev.qdev.id, cause);
|
||||||
|
g_free(cause);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
|
error_setg_errno(errp, -r, "Failed to assign device \"%s\"",
|
||||||
|
dev->dev.qdev.id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool check_irqchip_in_kernel(void)
|
static void verify_irqchip_in_kernel(Error **errp)
|
||||||
{
|
{
|
||||||
if (kvm_irqchip_in_kernel()) {
|
if (kvm_irqchip_in_kernel()) {
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
error_report("pci-assign: error: requires KVM with in-kernel irqchip "
|
error_setg(errp, "pci-assign requires KVM with in-kernel irqchip enabled");
|
||||||
"enabled");
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int assign_intx(AssignedDevice *dev)
|
static int assign_intx(AssignedDevice *dev, Error **errp)
|
||||||
{
|
{
|
||||||
AssignedIRQType new_type;
|
AssignedIRQType new_type;
|
||||||
PCIINTxRoute intx_route;
|
PCIINTxRoute intx_route;
|
||||||
bool intx_host_msi;
|
bool intx_host_msi;
|
||||||
int r;
|
int r;
|
||||||
|
Error *local_err = NULL;
|
||||||
|
|
||||||
/* Interrupt PIN 0 means don't use INTx */
|
/* Interrupt PIN 0 means don't use INTx */
|
||||||
if (assigned_dev_pci_read_byte(&dev->dev, PCI_INTERRUPT_PIN) == 0) {
|
if (assigned_dev_pci_read_byte(&dev->dev, PCI_INTERRUPT_PIN) == 0) {
|
||||||
@@ -842,7 +861,9 @@ static int assign_intx(AssignedDevice *dev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!check_irqchip_in_kernel()) {
|
verify_irqchip_in_kernel(&local_err);
|
||||||
|
if (local_err) {
|
||||||
|
error_propagate(errp, local_err);
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -905,10 +926,11 @@ retry:
|
|||||||
dev->features |= ASSIGNED_DEVICE_PREFER_MSI_MASK;
|
dev->features |= ASSIGNED_DEVICE_PREFER_MSI_MASK;
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
error_report("Failed to assign irq for \"%s\": %s",
|
error_setg_errno(errp, -r,
|
||||||
dev->dev.qdev.id, strerror(-r));
|
"Failed to assign irq for \"%s\"\n"
|
||||||
error_report("Perhaps you are assigning a device "
|
"Perhaps you are assigning a device "
|
||||||
"that shares an IRQ with another device?");
|
"that shares an IRQ with another device?",
|
||||||
|
dev->dev.qdev.id);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -934,8 +956,11 @@ static void assigned_dev_update_irq_routing(PCIDevice *dev)
|
|||||||
Error *err = NULL;
|
Error *err = NULL;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
r = assign_intx(assigned_dev);
|
r = assign_intx(assigned_dev, &err);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
|
error_report("%s", error_get_pretty(err));
|
||||||
|
error_free(err);
|
||||||
|
err = NULL;
|
||||||
qdev_unplug(&dev->qdev, &err);
|
qdev_unplug(&dev->qdev, &err);
|
||||||
assert(!err);
|
assert(!err);
|
||||||
}
|
}
|
||||||
@@ -986,7 +1011,13 @@ static void assigned_dev_update_msi(PCIDevice *pci_dev)
|
|||||||
assigned_dev->intx_route.irq = -1;
|
assigned_dev->intx_route.irq = -1;
|
||||||
assigned_dev->assigned_irq_type = ASSIGNED_IRQ_MSI;
|
assigned_dev->assigned_irq_type = ASSIGNED_IRQ_MSI;
|
||||||
} else {
|
} else {
|
||||||
assign_intx(assigned_dev);
|
Error *local_err = NULL;
|
||||||
|
|
||||||
|
assign_intx(assigned_dev, &local_err);
|
||||||
|
if (local_err) {
|
||||||
|
error_report("%s", error_get_pretty(local_err));
|
||||||
|
error_free(local_err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1128,7 +1159,13 @@ static void assigned_dev_update_msix(PCIDevice *pci_dev)
|
|||||||
assigned_dev->intx_route.irq = -1;
|
assigned_dev->intx_route.irq = -1;
|
||||||
assigned_dev->assigned_irq_type = ASSIGNED_IRQ_MSIX;
|
assigned_dev->assigned_irq_type = ASSIGNED_IRQ_MSIX;
|
||||||
} else {
|
} else {
|
||||||
assign_intx(assigned_dev);
|
Error *local_err = NULL;
|
||||||
|
|
||||||
|
assign_intx(assigned_dev, &local_err);
|
||||||
|
if (local_err) {
|
||||||
|
error_report("%s", error_get_pretty(local_err));
|
||||||
|
error_free(local_err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1214,11 +1251,12 @@ static void assigned_dev_setup_cap_read(AssignedDevice *dev, uint32_t offset,
|
|||||||
assigned_dev_emulate_config_read(dev, offset + PCI_CAP_LIST_NEXT, 1);
|
assigned_dev_emulate_config_read(dev, offset + PCI_CAP_LIST_NEXT, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int assigned_device_pci_cap_init(PCIDevice *pci_dev)
|
static int assigned_device_pci_cap_init(PCIDevice *pci_dev, Error **errp)
|
||||||
{
|
{
|
||||||
AssignedDevice *dev = DO_UPCAST(AssignedDevice, dev, pci_dev);
|
AssignedDevice *dev = DO_UPCAST(AssignedDevice, dev, pci_dev);
|
||||||
PCIRegion *pci_region = dev->real_device.regions;
|
PCIRegion *pci_region = dev->real_device.regions;
|
||||||
int ret, pos;
|
int ret, pos;
|
||||||
|
Error *local_err = NULL;
|
||||||
|
|
||||||
/* Clear initial capabilities pointer and status copied from hw */
|
/* Clear initial capabilities pointer and status copied from hw */
|
||||||
pci_set_byte(pci_dev->config + PCI_CAPABILITY_LIST, 0);
|
pci_set_byte(pci_dev->config + PCI_CAPABILITY_LIST, 0);
|
||||||
@@ -1230,13 +1268,17 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev)
|
|||||||
* MSI capability is the 1st capability in capability config */
|
* MSI capability is the 1st capability in capability config */
|
||||||
pos = pci_find_cap_offset(pci_dev, PCI_CAP_ID_MSI, 0);
|
pos = pci_find_cap_offset(pci_dev, PCI_CAP_ID_MSI, 0);
|
||||||
if (pos != 0 && kvm_check_extension(kvm_state, KVM_CAP_ASSIGN_DEV_IRQ)) {
|
if (pos != 0 && kvm_check_extension(kvm_state, KVM_CAP_ASSIGN_DEV_IRQ)) {
|
||||||
if (!check_irqchip_in_kernel()) {
|
verify_irqchip_in_kernel(&local_err);
|
||||||
|
if (local_err) {
|
||||||
|
error_propagate(errp, local_err);
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
}
|
}
|
||||||
dev->cap.available |= ASSIGNED_DEVICE_CAP_MSI;
|
dev->cap.available |= ASSIGNED_DEVICE_CAP_MSI;
|
||||||
/* Only 32-bit/no-mask currently supported */
|
/* Only 32-bit/no-mask currently supported */
|
||||||
ret = pci_add_capability(pci_dev, PCI_CAP_ID_MSI, pos, 10);
|
ret = pci_add_capability2(pci_dev, PCI_CAP_ID_MSI, pos, 10,
|
||||||
|
&local_err);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
error_propagate(errp, local_err);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
pci_dev->msi_cap = pos;
|
pci_dev->msi_cap = pos;
|
||||||
@@ -1259,12 +1301,16 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev)
|
|||||||
int bar_nr;
|
int bar_nr;
|
||||||
uint32_t msix_table_entry;
|
uint32_t msix_table_entry;
|
||||||
|
|
||||||
if (!check_irqchip_in_kernel()) {
|
verify_irqchip_in_kernel(&local_err);
|
||||||
|
if (local_err) {
|
||||||
|
error_propagate(errp, local_err);
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
}
|
}
|
||||||
dev->cap.available |= ASSIGNED_DEVICE_CAP_MSIX;
|
dev->cap.available |= ASSIGNED_DEVICE_CAP_MSIX;
|
||||||
ret = pci_add_capability(pci_dev, PCI_CAP_ID_MSIX, pos, 12);
|
ret = pci_add_capability2(pci_dev, PCI_CAP_ID_MSIX, pos, 12,
|
||||||
|
&local_err);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
error_propagate(errp, local_err);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
pci_dev->msix_cap = pos;
|
pci_dev->msix_cap = pos;
|
||||||
@@ -1291,8 +1337,10 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev)
|
|||||||
if (pos) {
|
if (pos) {
|
||||||
uint16_t pmc;
|
uint16_t pmc;
|
||||||
|
|
||||||
ret = pci_add_capability(pci_dev, PCI_CAP_ID_PM, pos, PCI_PM_SIZEOF);
|
ret = pci_add_capability2(pci_dev, PCI_CAP_ID_PM, pos, PCI_PM_SIZEOF,
|
||||||
|
&local_err);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
error_propagate(errp, local_err);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1330,8 +1378,8 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev)
|
|||||||
*/
|
*/
|
||||||
size = MIN(0x3c, PCI_CONFIG_SPACE_SIZE - pos);
|
size = MIN(0x3c, PCI_CONFIG_SPACE_SIZE - pos);
|
||||||
if (size < 0x34) {
|
if (size < 0x34) {
|
||||||
error_report("%s: Invalid size PCIe cap-id 0x%x",
|
error_setg(errp, "Invalid size PCIe cap-id 0x%x",
|
||||||
__func__, PCI_CAP_ID_EXP);
|
PCI_CAP_ID_EXP);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
} else if (size != 0x3c) {
|
} else if (size != 0x3c) {
|
||||||
error_report("WARNING, %s: PCIe cap-id 0x%x has "
|
error_report("WARNING, %s: PCIe cap-id 0x%x has "
|
||||||
@@ -1352,13 +1400,15 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
error_report("%s: Unsupported PCI express capability version %d",
|
error_setg(errp, "Unsupported PCI express capability version %d",
|
||||||
__func__, version);
|
version);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = pci_add_capability(pci_dev, PCI_CAP_ID_EXP, pos, size);
|
ret = pci_add_capability2(pci_dev, PCI_CAP_ID_EXP, pos, size,
|
||||||
|
&local_err);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
error_propagate(errp, local_err);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1368,8 +1418,8 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev)
|
|||||||
type = (type & PCI_EXP_FLAGS_TYPE) >> 4;
|
type = (type & PCI_EXP_FLAGS_TYPE) >> 4;
|
||||||
if (type != PCI_EXP_TYPE_ENDPOINT &&
|
if (type != PCI_EXP_TYPE_ENDPOINT &&
|
||||||
type != PCI_EXP_TYPE_LEG_END && type != PCI_EXP_TYPE_RC_END) {
|
type != PCI_EXP_TYPE_LEG_END && type != PCI_EXP_TYPE_RC_END) {
|
||||||
error_report("Device assignment only supports endpoint assignment,"
|
error_setg(errp, "Device assignment only supports endpoint "
|
||||||
" device type %d", type);
|
"assignment, device type %d", type);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1431,8 +1481,10 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev)
|
|||||||
uint32_t status;
|
uint32_t status;
|
||||||
|
|
||||||
/* Only expose the minimum, 8 byte capability */
|
/* Only expose the minimum, 8 byte capability */
|
||||||
ret = pci_add_capability(pci_dev, PCI_CAP_ID_PCIX, pos, 8);
|
ret = pci_add_capability2(pci_dev, PCI_CAP_ID_PCIX, pos, 8,
|
||||||
|
&local_err);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
error_propagate(errp, local_err);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1457,8 +1509,10 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev)
|
|||||||
pos = pci_find_cap_offset(pci_dev, PCI_CAP_ID_VPD, 0);
|
pos = pci_find_cap_offset(pci_dev, PCI_CAP_ID_VPD, 0);
|
||||||
if (pos) {
|
if (pos) {
|
||||||
/* Direct R/W passthrough */
|
/* Direct R/W passthrough */
|
||||||
ret = pci_add_capability(pci_dev, PCI_CAP_ID_VPD, pos, 8);
|
ret = pci_add_capability2(pci_dev, PCI_CAP_ID_VPD, pos, 8,
|
||||||
|
&local_err);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
error_propagate(errp, local_err);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1473,8 +1527,10 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev)
|
|||||||
pos += PCI_CAP_LIST_NEXT) {
|
pos += PCI_CAP_LIST_NEXT) {
|
||||||
uint8_t len = pci_get_byte(pci_dev->config + pos + PCI_CAP_FLAGS);
|
uint8_t len = pci_get_byte(pci_dev->config + pos + PCI_CAP_FLAGS);
|
||||||
/* Direct R/W passthrough */
|
/* Direct R/W passthrough */
|
||||||
ret = pci_add_capability(pci_dev, PCI_CAP_ID_VNDR, pos, len);
|
ret = pci_add_capability2(pci_dev, PCI_CAP_ID_VNDR, pos, len,
|
||||||
|
&local_err);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
error_propagate(errp, local_err);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1602,20 +1658,19 @@ static void assigned_dev_msix_reset(AssignedDevice *dev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int assigned_dev_register_msix_mmio(AssignedDevice *dev)
|
static void assigned_dev_register_msix_mmio(AssignedDevice *dev, Error **errp)
|
||||||
{
|
{
|
||||||
dev->msix_table = mmap(NULL, MSIX_PAGE_SIZE, PROT_READ|PROT_WRITE,
|
dev->msix_table = mmap(NULL, MSIX_PAGE_SIZE, PROT_READ|PROT_WRITE,
|
||||||
MAP_ANONYMOUS|MAP_PRIVATE, 0, 0);
|
MAP_ANONYMOUS|MAP_PRIVATE, 0, 0);
|
||||||
if (dev->msix_table == MAP_FAILED) {
|
if (dev->msix_table == MAP_FAILED) {
|
||||||
error_report("fail allocate msix_table! %s", strerror(errno));
|
error_setg_errno(errp, errno, "failed to allocate msix_table");
|
||||||
return -EFAULT;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
assigned_dev_msix_reset(dev);
|
assigned_dev_msix_reset(dev);
|
||||||
|
|
||||||
memory_region_init_io(&dev->mmio, OBJECT(dev), &assigned_dev_msix_mmio_ops,
|
memory_region_init_io(&dev->mmio, OBJECT(dev), &assigned_dev_msix_mmio_ops,
|
||||||
dev, "assigned-dev-msix", MSIX_PAGE_SIZE);
|
dev, "assigned-dev-msix", MSIX_PAGE_SIZE);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void assigned_dev_unregister_msix_mmio(AssignedDevice *dev)
|
static void assigned_dev_unregister_msix_mmio(AssignedDevice *dev)
|
||||||
@@ -1698,16 +1753,17 @@ static int assigned_initfn(struct PCIDevice *pci_dev)
|
|||||||
AssignedDevice *dev = DO_UPCAST(AssignedDevice, dev, pci_dev);
|
AssignedDevice *dev = DO_UPCAST(AssignedDevice, dev, pci_dev);
|
||||||
uint8_t e_intx;
|
uint8_t e_intx;
|
||||||
int r;
|
int r;
|
||||||
|
Error *local_err = NULL;
|
||||||
|
|
||||||
if (!kvm_enabled()) {
|
if (!kvm_enabled()) {
|
||||||
error_report("pci-assign: error: requires KVM support");
|
error_setg(&local_err, "pci-assign requires KVM support");
|
||||||
return -1;
|
goto exit_with_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dev->host.domain && !dev->host.bus && !dev->host.slot &&
|
if (!dev->host.domain && !dev->host.bus && !dev->host.slot &&
|
||||||
!dev->host.function) {
|
!dev->host.function) {
|
||||||
error_report("pci-assign: error: no host device specified");
|
error_setg(&local_err, "no host device specified");
|
||||||
return -1;
|
goto exit_with_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1730,27 +1786,28 @@ static int assigned_initfn(struct PCIDevice *pci_dev)
|
|||||||
memcpy(dev->emulate_config_write, dev->emulate_config_read,
|
memcpy(dev->emulate_config_write, dev->emulate_config_read,
|
||||||
sizeof(dev->emulate_config_read));
|
sizeof(dev->emulate_config_read));
|
||||||
|
|
||||||
if (get_real_device(dev)) {
|
get_real_device(dev, &local_err);
|
||||||
error_report("pci-assign: Error: Couldn't get real device (%s)!",
|
if (local_err) {
|
||||||
dev->dev.qdev.id);
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (assigned_device_pci_cap_init(pci_dev) < 0) {
|
if (assigned_device_pci_cap_init(pci_dev, &local_err) < 0) {
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* intercept MSI-X entry page in the MMIO */
|
/* intercept MSI-X entry page in the MMIO */
|
||||||
if (dev->cap.available & ASSIGNED_DEVICE_CAP_MSIX) {
|
if (dev->cap.available & ASSIGNED_DEVICE_CAP_MSIX) {
|
||||||
if (assigned_dev_register_msix_mmio(dev)) {
|
assigned_dev_register_msix_mmio(dev, &local_err);
|
||||||
|
if (local_err) {
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* handle real device's MMIO/PIO BARs */
|
/* handle real device's MMIO/PIO BARs */
|
||||||
if (assigned_dev_register_regions(dev->real_device.regions,
|
assigned_dev_register_regions(dev->real_device.regions,
|
||||||
dev->real_device.region_number,
|
dev->real_device.region_number, dev,
|
||||||
dev)) {
|
&local_err);
|
||||||
|
if (local_err) {
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1761,13 +1818,13 @@ static int assigned_initfn(struct PCIDevice *pci_dev)
|
|||||||
dev->intx_route.irq = -1;
|
dev->intx_route.irq = -1;
|
||||||
|
|
||||||
/* assign device to guest */
|
/* assign device to guest */
|
||||||
r = assign_device(dev);
|
assign_device(dev, &local_err);
|
||||||
if (r < 0) {
|
if (local_err) {
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* assign legacy INTx to the device */
|
/* assign legacy INTx to the device */
|
||||||
r = assign_intx(dev);
|
r = assign_intx(dev, &local_err);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
goto assigned_out;
|
goto assigned_out;
|
||||||
}
|
}
|
||||||
@@ -1780,8 +1837,14 @@ static int assigned_initfn(struct PCIDevice *pci_dev)
|
|||||||
|
|
||||||
assigned_out:
|
assigned_out:
|
||||||
deassign_device(dev);
|
deassign_device(dev);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
free_assigned_device(dev);
|
free_assigned_device(dev);
|
||||||
|
|
||||||
|
exit_with_error:
|
||||||
|
assert(local_err);
|
||||||
|
qerror_report_err(local_err);
|
||||||
|
error_free(local_err);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -414,6 +414,10 @@ static QEMUMachine pc_i440fx_machine_v2_0 = {
|
|||||||
PC_I440FX_2_0_MACHINE_OPTIONS,
|
PC_I440FX_2_0_MACHINE_OPTIONS,
|
||||||
.name = "pc-i440fx-2.0",
|
.name = "pc-i440fx-2.0",
|
||||||
.init = pc_init_pci_2_0,
|
.init = pc_init_pci_2_0,
|
||||||
|
.compat_props = (GlobalProperty[]) {
|
||||||
|
PC_COMPAT_2_0,
|
||||||
|
{ /* end of list */ }
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PC_I440FX_1_7_MACHINE_OPTIONS PC_I440FX_MACHINE_OPTIONS
|
#define PC_I440FX_1_7_MACHINE_OPTIONS PC_I440FX_MACHINE_OPTIONS
|
||||||
|
|||||||
@@ -327,6 +327,10 @@ static QEMUMachine pc_q35_machine_v2_0 = {
|
|||||||
PC_Q35_2_0_MACHINE_OPTIONS,
|
PC_Q35_2_0_MACHINE_OPTIONS,
|
||||||
.name = "pc-q35-2.0",
|
.name = "pc-q35-2.0",
|
||||||
.init = pc_q35_init_2_0,
|
.init = pc_q35_init_2_0,
|
||||||
|
.compat_props = (GlobalProperty[]) {
|
||||||
|
PC_Q35_COMPAT_2_0,
|
||||||
|
{ /* end of list */ }
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PC_Q35_1_7_MACHINE_OPTIONS PC_Q35_MACHINE_OPTIONS
|
#define PC_Q35_1_7_MACHINE_OPTIONS PC_Q35_MACHINE_OPTIONS
|
||||||
|
|||||||
1
hw/i386/xen/Makefile.objs
Normal file
1
hw/i386/xen/Makefile.objs
Normal file
@@ -0,0 +1 @@
|
|||||||
|
obj-y += xen_platform.o xen_apic.o xen_pvdevice.o
|
||||||
@@ -1293,7 +1293,7 @@ const VMStateDescription vmstate_ahci = {
|
|||||||
VMSTATE_UINT32(control_regs.impl, AHCIState),
|
VMSTATE_UINT32(control_regs.impl, AHCIState),
|
||||||
VMSTATE_UINT32(control_regs.version, AHCIState),
|
VMSTATE_UINT32(control_regs.version, AHCIState),
|
||||||
VMSTATE_UINT32(idp_index, AHCIState),
|
VMSTATE_UINT32(idp_index, AHCIState),
|
||||||
VMSTATE_INT32(ports, AHCIState),
|
VMSTATE_INT32_EQUAL(ports, AHCIState),
|
||||||
VMSTATE_END_OF_LIST()
|
VMSTATE_END_OF_LIST()
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1070,9 +1070,21 @@ static int tsc210x_load(QEMUFile *f, void *opaque, int version_id)
|
|||||||
s->enabled = qemu_get_byte(f);
|
s->enabled = qemu_get_byte(f);
|
||||||
s->host_mode = qemu_get_byte(f);
|
s->host_mode = qemu_get_byte(f);
|
||||||
s->function = qemu_get_byte(f);
|
s->function = qemu_get_byte(f);
|
||||||
|
if (s->function < 0 || s->function >= ARRAY_SIZE(mode_regs)) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
s->nextfunction = qemu_get_byte(f);
|
s->nextfunction = qemu_get_byte(f);
|
||||||
|
if (s->nextfunction < 0 || s->nextfunction >= ARRAY_SIZE(mode_regs)) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
s->precision = qemu_get_byte(f);
|
s->precision = qemu_get_byte(f);
|
||||||
|
if (s->precision < 0 || s->precision >= ARRAY_SIZE(resolution)) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
s->nextprecision = qemu_get_byte(f);
|
s->nextprecision = qemu_get_byte(f);
|
||||||
|
if (s->nextprecision < 0 || s->nextprecision >= ARRAY_SIZE(resolution)) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
s->filter = qemu_get_byte(f);
|
s->filter = qemu_get_byte(f);
|
||||||
s->pin_func = qemu_get_byte(f);
|
s->pin_func = qemu_get_byte(f);
|
||||||
s->ref = qemu_get_byte(f);
|
s->ref = qemu_get_byte(f);
|
||||||
|
|||||||
@@ -675,7 +675,7 @@ static uint32_t apic_mem_readl(void *opaque, hwaddr addr)
|
|||||||
val = s->id << 24;
|
val = s->id << 24;
|
||||||
break;
|
break;
|
||||||
case 0x03: /* version */
|
case 0x03: /* version */
|
||||||
val = 0x11 | ((APIC_LVT_NB - 1) << 16); /* version 0x11 */
|
val = s->version | ((APIC_LVT_NB - 1) << 16);
|
||||||
break;
|
break;
|
||||||
case 0x08:
|
case 0x08:
|
||||||
apic_sync_vapic(s, SYNC_FROM_VAPIC);
|
apic_sync_vapic(s, SYNC_FROM_VAPIC);
|
||||||
|
|||||||
@@ -380,6 +380,7 @@ static const VMStateDescription vmstate_apic_common = {
|
|||||||
|
|
||||||
static Property apic_properties_common[] = {
|
static Property apic_properties_common[] = {
|
||||||
DEFINE_PROP_UINT8("id", APICCommonState, id, -1),
|
DEFINE_PROP_UINT8("id", APICCommonState, id, -1),
|
||||||
|
DEFINE_PROP_UINT8("version", APICCommonState, version, 0x14),
|
||||||
DEFINE_PROP_BIT("vapic", APICCommonState, vapic_control, VAPIC_ENABLE_BIT,
|
DEFINE_PROP_BIT("vapic", APICCommonState, vapic_control, VAPIC_ENABLE_BIT,
|
||||||
true),
|
true),
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
|
|||||||
@@ -797,9 +797,11 @@ static void arm_gic_realize(DeviceState *dev, Error **errp)
|
|||||||
GICState *s = ARM_GIC(dev);
|
GICState *s = ARM_GIC(dev);
|
||||||
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
|
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
|
||||||
ARMGICClass *agc = ARM_GIC_GET_CLASS(s);
|
ARMGICClass *agc = ARM_GIC_GET_CLASS(s);
|
||||||
|
Error *local_err = NULL;
|
||||||
|
|
||||||
agc->parent_realize(dev, errp);
|
agc->parent_realize(dev, &local_err);
|
||||||
if (error_is_set(errp)) {
|
if (local_err) {
|
||||||
|
error_propagate(errp, local_err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -517,10 +517,12 @@ static void kvm_arm_gic_realize(DeviceState *dev, Error **errp)
|
|||||||
GICState *s = KVM_ARM_GIC(dev);
|
GICState *s = KVM_ARM_GIC(dev);
|
||||||
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
|
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
|
||||||
KVMARMGICClass *kgc = KVM_ARM_GIC_GET_CLASS(s);
|
KVMARMGICClass *kgc = KVM_ARM_GIC_GET_CLASS(s);
|
||||||
|
Error *local_err = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
kgc->parent_realize(dev, errp);
|
kgc->parent_realize(dev, &local_err);
|
||||||
if (error_is_set(errp)) {
|
if (local_err) {
|
||||||
|
error_propagate(errp, local_err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -474,14 +474,16 @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
|
|||||||
{
|
{
|
||||||
nvic_state *s = NVIC(dev);
|
nvic_state *s = NVIC(dev);
|
||||||
NVICClass *nc = NVIC_GET_CLASS(s);
|
NVICClass *nc = NVIC_GET_CLASS(s);
|
||||||
|
Error *local_err = NULL;
|
||||||
|
|
||||||
/* The NVIC always has only one CPU */
|
/* The NVIC always has only one CPU */
|
||||||
s->gic.num_cpu = 1;
|
s->gic.num_cpu = 1;
|
||||||
/* Tell the common code we're an NVIC */
|
/* Tell the common code we're an NVIC */
|
||||||
s->gic.revision = 0xffffffff;
|
s->gic.revision = 0xffffffff;
|
||||||
s->num_irq = s->gic.num_irq;
|
s->num_irq = s->gic.num_irq;
|
||||||
nc->parent_realize(dev, errp);
|
nc->parent_realize(dev, &local_err);
|
||||||
if (error_is_set(errp)) {
|
if (local_err) {
|
||||||
|
error_propagate(errp, local_err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
gic_init_irqs_and_distributor(&s->gic, s->num_irq);
|
gic_init_irqs_and_distributor(&s->gic, s->num_irq);
|
||||||
|
|||||||
@@ -265,7 +265,8 @@ static void pic_ioport_write(void *opaque, hwaddr addr64,
|
|||||||
s->init4 = val & 1;
|
s->init4 = val & 1;
|
||||||
s->single_mode = val & 2;
|
s->single_mode = val & 2;
|
||||||
if (val & 0x08) {
|
if (val & 0x08) {
|
||||||
hw_error("level sensitive irq not supported");
|
qemu_log_mask(LOG_UNIMP,
|
||||||
|
"i8259: level sensitive irq not supported\n");
|
||||||
}
|
}
|
||||||
} else if (val & 0x08) {
|
} else if (val & 0x08) {
|
||||||
if (val & 0x04) {
|
if (val & 0x04) {
|
||||||
@@ -412,7 +413,7 @@ static const MemoryRegionOps pic_elcr_ioport_ops = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static void pic_realize(DeviceState *dev, Error **err)
|
static void pic_realize(DeviceState *dev, Error **errp)
|
||||||
{
|
{
|
||||||
PICCommonState *s = PIC_COMMON(dev);
|
PICCommonState *s = PIC_COMMON(dev);
|
||||||
PICClass *pc = PIC_GET_CLASS(dev);
|
PICClass *pc = PIC_GET_CLASS(dev);
|
||||||
@@ -425,7 +426,7 @@ static void pic_realize(DeviceState *dev, Error **err)
|
|||||||
qdev_init_gpio_out(dev, s->int_out, ARRAY_SIZE(s->int_out));
|
qdev_init_gpio_out(dev, s->int_out, ARRAY_SIZE(s->int_out));
|
||||||
qdev_init_gpio_in(dev, pic_set_irq, 8);
|
qdev_init_gpio_in(dev, pic_set_irq, 8);
|
||||||
|
|
||||||
pc->parent_realize(dev, err);
|
pc->parent_realize(dev, errp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pic_info(Monitor *mon, const QDict *qdict)
|
void pic_info(Monitor *mon, const QDict *qdict)
|
||||||
|
|||||||
@@ -41,6 +41,7 @@
|
|||||||
#include "hw/sysbus.h"
|
#include "hw/sysbus.h"
|
||||||
#include "hw/pci/msi.h"
|
#include "hw/pci/msi.h"
|
||||||
#include "qemu/bitops.h"
|
#include "qemu/bitops.h"
|
||||||
|
#include "qapi/qmp/qerror.h"
|
||||||
|
|
||||||
//#define DEBUG_OPENPIC
|
//#define DEBUG_OPENPIC
|
||||||
|
|
||||||
@@ -1416,7 +1417,7 @@ static void openpic_load_IRQ_queue(QEMUFile* f, IRQQueue *q)
|
|||||||
static int openpic_load(QEMUFile* f, void *opaque, int version_id)
|
static int openpic_load(QEMUFile* f, void *opaque, int version_id)
|
||||||
{
|
{
|
||||||
OpenPICState *opp = (OpenPICState *)opaque;
|
OpenPICState *opp = (OpenPICState *)opaque;
|
||||||
unsigned int i;
|
unsigned int i, nb_cpus;
|
||||||
|
|
||||||
if (version_id != 1) {
|
if (version_id != 1) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@@ -1428,7 +1429,11 @@ static int openpic_load(QEMUFile* f, void *opaque, int version_id)
|
|||||||
qemu_get_be32s(f, &opp->spve);
|
qemu_get_be32s(f, &opp->spve);
|
||||||
qemu_get_be32s(f, &opp->tfrr);
|
qemu_get_be32s(f, &opp->tfrr);
|
||||||
|
|
||||||
qemu_get_be32s(f, &opp->nb_cpus);
|
qemu_get_be32s(f, &nb_cpus);
|
||||||
|
if (opp->nb_cpus != nb_cpus) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
assert(nb_cpus > 0 && nb_cpus <= MAX_CPU);
|
||||||
|
|
||||||
for (i = 0; i < opp->nb_cpus; i++) {
|
for (i = 0; i < opp->nb_cpus; i++) {
|
||||||
qemu_get_sbe32s(f, &opp->dst[i].ctpr);
|
qemu_get_sbe32s(f, &opp->dst[i].ctpr);
|
||||||
@@ -1567,6 +1572,13 @@ static void openpic_realize(DeviceState *dev, Error **errp)
|
|||||||
{NULL}
|
{NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (opp->nb_cpus > MAX_CPU) {
|
||||||
|
error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE,
|
||||||
|
TYPE_OPENPIC, "nb_cpus", (uint64_t)opp->nb_cpus,
|
||||||
|
(uint64_t)0, (uint64_t)MAX_CPU);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
switch (opp->model) {
|
switch (opp->model) {
|
||||||
case OPENPIC_MODEL_FSL_MPIC_20:
|
case OPENPIC_MODEL_FSL_MPIC_20:
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -121,6 +121,9 @@ pic_write(void *opaque, hwaddr addr,
|
|||||||
case R_CIE:
|
case R_CIE:
|
||||||
p->regs[R_IER] &= ~value; /* Atomic clear ie. */
|
p->regs[R_IER] &= ~value; /* Atomic clear ie. */
|
||||||
break;
|
break;
|
||||||
|
case R_MER:
|
||||||
|
p->regs[R_MER] = value & 0x3;
|
||||||
|
break;
|
||||||
case R_ISR:
|
case R_ISR:
|
||||||
if ((p->regs[R_MER] & 2)) {
|
if ((p->regs[R_MER] & 2)) {
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -108,15 +108,20 @@ void isa_register_portio_list(ISADevice *dev, uint16_t start,
|
|||||||
const MemoryRegionPortio *pio_start,
|
const MemoryRegionPortio *pio_start,
|
||||||
void *opaque, const char *name)
|
void *opaque, const char *name)
|
||||||
{
|
{
|
||||||
PortioList *piolist = g_new(PortioList, 1);
|
PortioList piolist;
|
||||||
|
|
||||||
/* START is how we should treat DEV, regardless of the actual
|
/* START is how we should treat DEV, regardless of the actual
|
||||||
contents of the portio array. This is how the old code
|
contents of the portio array. This is how the old code
|
||||||
actually handled e.g. the FDC device. */
|
actually handled e.g. the FDC device. */
|
||||||
isa_init_ioport(dev, start);
|
isa_init_ioport(dev, start);
|
||||||
|
|
||||||
portio_list_init(piolist, OBJECT(dev), pio_start, opaque, name);
|
/* FIXME: the device should store created PortioList in its state. Note
|
||||||
portio_list_add(piolist, isabus->address_space_io, start);
|
that DEV can be NULL here and that single device can register several
|
||||||
|
portio lists. Current implementation is leaking memory allocated
|
||||||
|
in portio_list_init. The leak is not critical because it happens only
|
||||||
|
at initialization time. */
|
||||||
|
portio_list_init(&piolist, OBJECT(dev), pio_start, opaque, name);
|
||||||
|
portio_list_add(&piolist, isabus->address_space_io, start);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void isa_device_init(Object *obj)
|
static void isa_device_init(Object *obj)
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr ddr_base,
|
|||||||
big_endian, ELF_MACHINE, 0);
|
big_endian, ELF_MACHINE, 0);
|
||||||
}
|
}
|
||||||
/* Always boot into physical ram. */
|
/* Always boot into physical ram. */
|
||||||
boot_info.bootstrap_pc = ddr_base + (entry & 0x0fffffff);
|
boot_info.bootstrap_pc = (uint32_t)entry;
|
||||||
|
|
||||||
/* If it wasn't an ELF image, try an u-boot image. */
|
/* If it wasn't an ELF image, try an u-boot image. */
|
||||||
if (kernel_size < 0) {
|
if (kernel_size < 0) {
|
||||||
@@ -174,9 +174,15 @@ void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr ddr_base,
|
|||||||
high = ROUND_UP(high + kernel_size, 4);
|
high = ROUND_UP(high + kernel_size, 4);
|
||||||
boot_info.initrd_start = high;
|
boot_info.initrd_start = high;
|
||||||
initrd_offset = boot_info.initrd_start - ddr_base;
|
initrd_offset = boot_info.initrd_start - ddr_base;
|
||||||
initrd_size = load_image_targphys(initrd_filename,
|
|
||||||
boot_info.initrd_start,
|
initrd_size = load_ramdisk(initrd_filename,
|
||||||
ram_size - initrd_offset);
|
boot_info.initrd_start,
|
||||||
|
ram_size - initrd_offset);
|
||||||
|
if (initrd_size < 0) {
|
||||||
|
initrd_size = load_image_targphys(initrd_filename,
|
||||||
|
boot_info.initrd_start,
|
||||||
|
ram_size - initrd_offset);
|
||||||
|
}
|
||||||
if (initrd_size < 0) {
|
if (initrd_size < 0) {
|
||||||
error_report("qemu: could not load initrd '%s'\n",
|
error_report("qemu: could not load initrd '%s'\n",
|
||||||
initrd_filename);
|
initrd_filename);
|
||||||
|
|||||||
@@ -211,7 +211,7 @@ static void main_cpu_reset(void *opaque)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t eeprom_spd[0x80] = {
|
static const uint8_t eeprom_spd[0x80] = {
|
||||||
0x80,0x08,0x07,0x0d,0x09,0x02,0x40,0x00,0x04,0x70,
|
0x80,0x08,0x07,0x0d,0x09,0x02,0x40,0x00,0x04,0x70,
|
||||||
0x70,0x00,0x82,0x10,0x00,0x01,0x0e,0x04,0x0c,0x01,
|
0x70,0x00,0x82,0x10,0x00,0x01,0x0e,0x04,0x0c,0x01,
|
||||||
0x02,0x20,0x80,0x75,0x70,0x00,0x00,0x50,0x3c,0x50,
|
0x02,0x20,0x80,0x75,0x70,0x00,0x00,0x50,0x3c,0x50,
|
||||||
|
|||||||
@@ -68,10 +68,12 @@ static void tmp105_set_temperature(Object *obj, Visitor *v, void *opaque,
|
|||||||
const char *name, Error **errp)
|
const char *name, Error **errp)
|
||||||
{
|
{
|
||||||
TMP105State *s = TMP105(obj);
|
TMP105State *s = TMP105(obj);
|
||||||
|
Error *local_err = NULL;
|
||||||
int64_t temp;
|
int64_t temp;
|
||||||
|
|
||||||
visit_type_int(v, &temp, name, errp);
|
visit_type_int(v, &temp, name, &local_err);
|
||||||
if (error_is_set(errp)) {
|
if (local_err) {
|
||||||
|
error_propagate(errp, local_err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (temp >= 128000 || temp < -128000) {
|
if (temp >= 128000 || temp < -128000) {
|
||||||
|
|||||||
@@ -388,7 +388,7 @@ typedef struct GemState {
|
|||||||
} GemState;
|
} GemState;
|
||||||
|
|
||||||
/* The broadcast MAC address: 0xFFFFFFFFFFFF */
|
/* The broadcast MAC address: 0xFFFFFFFFFFFF */
|
||||||
const uint8_t broadcast_addr[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
|
static const uint8_t broadcast_addr[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* gem_init_register_masks:
|
* gem_init_register_masks:
|
||||||
|
|||||||
@@ -1362,10 +1362,17 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int version_id)
|
|||||||
if (n->mac_table.in_use <= MAC_TABLE_ENTRIES) {
|
if (n->mac_table.in_use <= MAC_TABLE_ENTRIES) {
|
||||||
qemu_get_buffer(f, n->mac_table.macs,
|
qemu_get_buffer(f, n->mac_table.macs,
|
||||||
n->mac_table.in_use * ETH_ALEN);
|
n->mac_table.in_use * ETH_ALEN);
|
||||||
} else if (n->mac_table.in_use) {
|
} else {
|
||||||
uint8_t *buf = g_malloc0(n->mac_table.in_use);
|
int64_t i;
|
||||||
qemu_get_buffer(f, buf, n->mac_table.in_use * ETH_ALEN);
|
|
||||||
g_free(buf);
|
/* Overflow detected - can happen if source has a larger MAC table.
|
||||||
|
* We simply set overflow flag so there's no need to maintain the
|
||||||
|
* table of addresses, discard them all.
|
||||||
|
* Note: 64 bit math to avoid integer overflow.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < (int64_t)n->mac_table.in_use * ETH_ALEN; ++i) {
|
||||||
|
qemu_get_byte(f);
|
||||||
|
}
|
||||||
n->mac_table.multi_overflow = n->mac_table.uni_overflow = 1;
|
n->mac_table.multi_overflow = n->mac_table.uni_overflow = 1;
|
||||||
n->mac_table.in_use = 0;
|
n->mac_table.in_use = 0;
|
||||||
}
|
}
|
||||||
@@ -1407,6 +1414,11 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int version_id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
n->curr_queues = qemu_get_be16(f);
|
n->curr_queues = qemu_get_be16(f);
|
||||||
|
if (n->curr_queues > n->max_queues) {
|
||||||
|
error_report("virtio-net: curr_queues %x > max_queues %x",
|
||||||
|
n->curr_queues, n->max_queues);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
for (i = 1; i < n->curr_queues; i++) {
|
for (i = 1; i < n->curr_queues; i++) {
|
||||||
n->vqs[i].tx_waiting = qemu_get_be32(f);
|
n->vqs[i].tx_waiting = qemu_get_be32(f);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2305,7 +2305,7 @@ static void vmxnet3_put_txq_descr(QEMUFile *f, void *pv, size_t size)
|
|||||||
vmxnet3_put_tx_stats_to_file(f, &r->txq_stats);
|
vmxnet3_put_tx_stats_to_file(f, &r->txq_stats);
|
||||||
}
|
}
|
||||||
|
|
||||||
const VMStateInfo txq_descr_info = {
|
static const VMStateInfo txq_descr_info = {
|
||||||
.name = "txq_descr",
|
.name = "txq_descr",
|
||||||
.get = vmxnet3_get_txq_descr,
|
.get = vmxnet3_get_txq_descr,
|
||||||
.put = vmxnet3_put_txq_descr
|
.put = vmxnet3_put_txq_descr
|
||||||
@@ -2397,7 +2397,7 @@ static int vmxnet3_post_load(void *opaque, int version_id)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const VMStateInfo rxq_descr_info = {
|
static const VMStateInfo rxq_descr_info = {
|
||||||
.name = "rxq_descr",
|
.name = "rxq_descr",
|
||||||
.get = vmxnet3_get_rxq_descr,
|
.get = vmxnet3_get_rxq_descr,
|
||||||
.put = vmxnet3_put_rxq_descr
|
.put = vmxnet3_put_rxq_descr
|
||||||
@@ -2423,7 +2423,7 @@ static void vmxnet3_put_int_state(QEMUFile *f, void *pv, size_t size)
|
|||||||
qemu_put_byte(f, r->is_asserted);
|
qemu_put_byte(f, r->is_asserted);
|
||||||
}
|
}
|
||||||
|
|
||||||
const VMStateInfo int_state_info = {
|
static const VMStateInfo int_state_info = {
|
||||||
.name = "int_state",
|
.name = "int_state",
|
||||||
.get = vmxnet3_get_int_state,
|
.get = vmxnet3_get_int_state,
|
||||||
.put = vmxnet3_put_int_state
|
.put = vmxnet3_put_int_state
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ typedef struct XgmacState {
|
|||||||
uint32_t regs[R_MAX];
|
uint32_t regs[R_MAX];
|
||||||
} XgmacState;
|
} XgmacState;
|
||||||
|
|
||||||
const VMStateDescription vmstate_rxtx_stats = {
|
static const VMStateDescription vmstate_rxtx_stats = {
|
||||||
.name = "xgmac_stats",
|
.name = "xgmac_stats",
|
||||||
.version_id = 1,
|
.version_id = 1,
|
||||||
.minimum_version_id = 1,
|
.minimum_version_id = 1,
|
||||||
|
|||||||
@@ -945,24 +945,24 @@ static void xilinx_enet_realize(DeviceState *dev, Error **errp)
|
|||||||
XilinxAXIEnetStreamSlave *ds = XILINX_AXI_ENET_DATA_STREAM(&s->rx_data_dev);
|
XilinxAXIEnetStreamSlave *ds = XILINX_AXI_ENET_DATA_STREAM(&s->rx_data_dev);
|
||||||
XilinxAXIEnetStreamSlave *cs = XILINX_AXI_ENET_CONTROL_STREAM(
|
XilinxAXIEnetStreamSlave *cs = XILINX_AXI_ENET_CONTROL_STREAM(
|
||||||
&s->rx_control_dev);
|
&s->rx_control_dev);
|
||||||
Error *local_errp = NULL;
|
Error *local_err = NULL;
|
||||||
|
|
||||||
object_property_add_link(OBJECT(ds), "enet", "xlnx.axi-ethernet",
|
object_property_add_link(OBJECT(ds), "enet", "xlnx.axi-ethernet",
|
||||||
(Object **) &ds->enet,
|
(Object **) &ds->enet,
|
||||||
object_property_allow_set_link,
|
object_property_allow_set_link,
|
||||||
OBJ_PROP_LINK_UNREF_ON_RELEASE,
|
OBJ_PROP_LINK_UNREF_ON_RELEASE,
|
||||||
&local_errp);
|
&local_err);
|
||||||
object_property_add_link(OBJECT(cs), "enet", "xlnx.axi-ethernet",
|
object_property_add_link(OBJECT(cs), "enet", "xlnx.axi-ethernet",
|
||||||
(Object **) &cs->enet,
|
(Object **) &cs->enet,
|
||||||
object_property_allow_set_link,
|
object_property_allow_set_link,
|
||||||
OBJ_PROP_LINK_UNREF_ON_RELEASE,
|
OBJ_PROP_LINK_UNREF_ON_RELEASE,
|
||||||
&local_errp);
|
&local_err);
|
||||||
if (local_errp) {
|
if (local_err) {
|
||||||
goto xilinx_enet_realize_fail;
|
goto xilinx_enet_realize_fail;
|
||||||
}
|
}
|
||||||
object_property_set_link(OBJECT(ds), OBJECT(s), "enet", &local_errp);
|
object_property_set_link(OBJECT(ds), OBJECT(s), "enet", &local_err);
|
||||||
object_property_set_link(OBJECT(cs), OBJECT(s), "enet", &local_errp);
|
object_property_set_link(OBJECT(cs), OBJECT(s), "enet", &local_err);
|
||||||
if (local_errp) {
|
if (local_err) {
|
||||||
goto xilinx_enet_realize_fail;
|
goto xilinx_enet_realize_fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -981,7 +981,7 @@ static void xilinx_enet_realize(DeviceState *dev, Error **errp)
|
|||||||
|
|
||||||
xilinx_enet_realize_fail:
|
xilinx_enet_realize_fail:
|
||||||
if (!*errp) {
|
if (!*errp) {
|
||||||
*errp = local_errp;
|
*errp = local_err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
36
hw/pci/pci.c
36
hw/pci/pci.c
@@ -475,7 +475,7 @@ const VMStateDescription vmstate_pci_device = {
|
|||||||
.minimum_version_id = 1,
|
.minimum_version_id = 1,
|
||||||
.minimum_version_id_old = 1,
|
.minimum_version_id_old = 1,
|
||||||
.fields = (VMStateField []) {
|
.fields = (VMStateField []) {
|
||||||
VMSTATE_INT32_LE(version_id, PCIDevice),
|
VMSTATE_INT32_POSITIVE_LE(version_id, PCIDevice),
|
||||||
VMSTATE_BUFFER_UNSAFE_INFO(config, PCIDevice, 0,
|
VMSTATE_BUFFER_UNSAFE_INFO(config, PCIDevice, 0,
|
||||||
vmstate_info_pci_config,
|
vmstate_info_pci_config,
|
||||||
PCI_CONFIG_SPACE_SIZE),
|
PCI_CONFIG_SPACE_SIZE),
|
||||||
@@ -492,7 +492,7 @@ const VMStateDescription vmstate_pcie_device = {
|
|||||||
.minimum_version_id = 1,
|
.minimum_version_id = 1,
|
||||||
.minimum_version_id_old = 1,
|
.minimum_version_id_old = 1,
|
||||||
.fields = (VMStateField []) {
|
.fields = (VMStateField []) {
|
||||||
VMSTATE_INT32_LE(version_id, PCIDevice),
|
VMSTATE_INT32_POSITIVE_LE(version_id, PCIDevice),
|
||||||
VMSTATE_BUFFER_UNSAFE_INFO(config, PCIDevice, 0,
|
VMSTATE_BUFFER_UNSAFE_INFO(config, PCIDevice, 0,
|
||||||
vmstate_info_pci_config,
|
vmstate_info_pci_config,
|
||||||
PCIE_CONFIG_SPACE_SIZE),
|
PCIE_CONFIG_SPACE_SIZE),
|
||||||
@@ -2012,6 +2012,25 @@ static void pci_del_option_rom(PCIDevice *pdev)
|
|||||||
* in pci config space */
|
* in pci config space */
|
||||||
int pci_add_capability(PCIDevice *pdev, uint8_t cap_id,
|
int pci_add_capability(PCIDevice *pdev, uint8_t cap_id,
|
||||||
uint8_t offset, uint8_t size)
|
uint8_t offset, uint8_t size)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
Error *local_err = NULL;
|
||||||
|
|
||||||
|
ret = pci_add_capability2(pdev, cap_id, offset, size, &local_err);
|
||||||
|
if (local_err) {
|
||||||
|
assert(ret < 0);
|
||||||
|
error_report("%s", error_get_pretty(local_err));
|
||||||
|
error_free(local_err);
|
||||||
|
} else {
|
||||||
|
/* success implies a positive offset in config space */
|
||||||
|
assert(ret > 0);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pci_add_capability2(PCIDevice *pdev, uint8_t cap_id,
|
||||||
|
uint8_t offset, uint8_t size,
|
||||||
|
Error **errp)
|
||||||
{
|
{
|
||||||
uint8_t *config;
|
uint8_t *config;
|
||||||
int i, overlapping_cap;
|
int i, overlapping_cap;
|
||||||
@@ -2019,6 +2038,7 @@ int pci_add_capability(PCIDevice *pdev, uint8_t cap_id,
|
|||||||
if (!offset) {
|
if (!offset) {
|
||||||
offset = pci_find_space(pdev, size);
|
offset = pci_find_space(pdev, size);
|
||||||
if (!offset) {
|
if (!offset) {
|
||||||
|
error_setg(errp, "out of PCI config space");
|
||||||
return -ENOSPC;
|
return -ENOSPC;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -2029,12 +2049,12 @@ int pci_add_capability(PCIDevice *pdev, uint8_t cap_id,
|
|||||||
for (i = offset; i < offset + size; i++) {
|
for (i = offset; i < offset + size; i++) {
|
||||||
overlapping_cap = pci_find_capability_at_offset(pdev, i);
|
overlapping_cap = pci_find_capability_at_offset(pdev, i);
|
||||||
if (overlapping_cap) {
|
if (overlapping_cap) {
|
||||||
fprintf(stderr, "ERROR: %s:%02x:%02x.%x "
|
error_setg(errp, "%s:%02x:%02x.%x "
|
||||||
"Attempt to add PCI capability %x at offset "
|
"Attempt to add PCI capability %x at offset "
|
||||||
"%x overlaps existing capability %x at offset %x\n",
|
"%x overlaps existing capability %x at offset %x",
|
||||||
pci_root_bus_path(pdev), pci_bus_num(pdev->bus),
|
pci_root_bus_path(pdev), pci_bus_num(pdev->bus),
|
||||||
PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
|
PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
|
||||||
cap_id, offset, overlapping_cap, i);
|
cap_id, offset, overlapping_cap, i);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -795,6 +795,13 @@ static const VMStateDescription vmstate_pcie_aer_err = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static bool pcie_aer_state_log_num_valid(void *opaque, int version_id)
|
||||||
|
{
|
||||||
|
PCIEAERLog *s = opaque;
|
||||||
|
|
||||||
|
return s->log_num <= s->log_max;
|
||||||
|
}
|
||||||
|
|
||||||
const VMStateDescription vmstate_pcie_aer_log = {
|
const VMStateDescription vmstate_pcie_aer_log = {
|
||||||
.name = "PCIE_AER_ERROR_LOG",
|
.name = "PCIE_AER_ERROR_LOG",
|
||||||
.version_id = 1,
|
.version_id = 1,
|
||||||
@@ -802,7 +809,8 @@ const VMStateDescription vmstate_pcie_aer_log = {
|
|||||||
.minimum_version_id_old = 1,
|
.minimum_version_id_old = 1,
|
||||||
.fields = (VMStateField[]) {
|
.fields = (VMStateField[]) {
|
||||||
VMSTATE_UINT16(log_num, PCIEAERLog),
|
VMSTATE_UINT16(log_num, PCIEAERLog),
|
||||||
VMSTATE_UINT16(log_max, PCIEAERLog),
|
VMSTATE_UINT16_EQUAL(log_max, PCIEAERLog),
|
||||||
|
VMSTATE_VALIDATE("log_num <= log_max", pcie_aer_state_log_num_valid),
|
||||||
VMSTATE_STRUCT_VARRAY_POINTER_UINT16(log, PCIEAERLog, log_num,
|
VMSTATE_STRUCT_VARRAY_POINTER_UINT16(log, PCIEAERLog, log_num,
|
||||||
vmstate_pcie_aer_err, PCIEAERErr),
|
vmstate_pcie_aer_err, PCIEAERErr),
|
||||||
VMSTATE_END_OF_LIST()
|
VMSTATE_END_OF_LIST()
|
||||||
|
|||||||
@@ -361,6 +361,8 @@ static const MemoryRegionPortio prep_portio_list[] = {
|
|||||||
PORTIO_END_OF_LIST(),
|
PORTIO_END_OF_LIST(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static PortioList prep_port_list;
|
||||||
|
|
||||||
/* PowerPC PREP hardware initialisation */
|
/* PowerPC PREP hardware initialisation */
|
||||||
static void ppc_prep_init(QEMUMachineInitArgs *args)
|
static void ppc_prep_init(QEMUMachineInitArgs *args)
|
||||||
{
|
{
|
||||||
@@ -375,7 +377,6 @@ static void ppc_prep_init(QEMUMachineInitArgs *args)
|
|||||||
CPUPPCState *env = NULL;
|
CPUPPCState *env = NULL;
|
||||||
nvram_t nvram;
|
nvram_t nvram;
|
||||||
M48t59State *m48t59;
|
M48t59State *m48t59;
|
||||||
PortioList *port_list = g_new(PortioList, 1);
|
|
||||||
#if 0
|
#if 0
|
||||||
MemoryRegion *xcsr = g_new(MemoryRegion, 1);
|
MemoryRegion *xcsr = g_new(MemoryRegion, 1);
|
||||||
#endif
|
#endif
|
||||||
@@ -542,8 +543,8 @@ static void ppc_prep_init(QEMUMachineInitArgs *args)
|
|||||||
cpu = POWERPC_CPU(first_cpu);
|
cpu = POWERPC_CPU(first_cpu);
|
||||||
sysctrl->reset_irq = cpu->env.irq_inputs[PPC6xx_INPUT_HRESET];
|
sysctrl->reset_irq = cpu->env.irq_inputs[PPC6xx_INPUT_HRESET];
|
||||||
|
|
||||||
portio_list_init(port_list, NULL, prep_portio_list, sysctrl, "prep");
|
portio_list_init(&prep_port_list, NULL, prep_portio_list, sysctrl, "prep");
|
||||||
portio_list_add(port_list, isa_address_space_io(isa), 0x0);
|
portio_list_add(&prep_port_list, isa_address_space_io(isa), 0x0);
|
||||||
|
|
||||||
/* PowerPC control and status register group */
|
/* PowerPC control and status register group */
|
||||||
#if 0
|
#if 0
|
||||||
|
|||||||
@@ -1419,19 +1419,6 @@ static int spapr_kvm_type(const char *vm_type)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static QEMUMachine spapr_machine = {
|
|
||||||
.name = "pseries",
|
|
||||||
.desc = "pSeries Logical Partition (PAPR compliant)",
|
|
||||||
.is_default = 1,
|
|
||||||
.init = ppc_spapr_init,
|
|
||||||
.reset = ppc_spapr_reset,
|
|
||||||
.block_default_type = IF_SCSI,
|
|
||||||
.max_cpus = MAX_CPUS,
|
|
||||||
.no_parallel = 1,
|
|
||||||
.default_boot_order = NULL,
|
|
||||||
.kvm_type = spapr_kvm_type,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Implementation of an interface to adjust firmware patch
|
* Implementation of an interface to adjust firmware patch
|
||||||
* for the bootindex property handling.
|
* for the bootindex property handling.
|
||||||
@@ -1494,7 +1481,17 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
|
|||||||
MachineClass *mc = MACHINE_CLASS(oc);
|
MachineClass *mc = MACHINE_CLASS(oc);
|
||||||
FWPathProviderClass *fwc = FW_PATH_PROVIDER_CLASS(oc);
|
FWPathProviderClass *fwc = FW_PATH_PROVIDER_CLASS(oc);
|
||||||
|
|
||||||
mc->qemu_machine = data;
|
mc->name = "pseries";
|
||||||
|
mc->desc = "pSeries Logical Partition (PAPR compliant)";
|
||||||
|
mc->is_default = 1;
|
||||||
|
mc->init = ppc_spapr_init;
|
||||||
|
mc->reset = ppc_spapr_reset;
|
||||||
|
mc->block_default_type = IF_SCSI;
|
||||||
|
mc->max_cpus = MAX_CPUS;
|
||||||
|
mc->no_parallel = 1;
|
||||||
|
mc->default_boot_order = NULL;
|
||||||
|
mc->kvm_type = spapr_kvm_type;
|
||||||
|
|
||||||
fwc->get_dev_path = spapr_get_fw_dev_path;
|
fwc->get_dev_path = spapr_get_fw_dev_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1502,7 +1499,6 @@ static const TypeInfo spapr_machine_info = {
|
|||||||
.name = TYPE_SPAPR_MACHINE,
|
.name = TYPE_SPAPR_MACHINE,
|
||||||
.parent = TYPE_MACHINE,
|
.parent = TYPE_MACHINE,
|
||||||
.class_init = spapr_machine_class_init,
|
.class_init = spapr_machine_class_init,
|
||||||
.class_data = &spapr_machine,
|
|
||||||
.interfaces = (InterfaceInfo[]) {
|
.interfaces = (InterfaceInfo[]) {
|
||||||
{ TYPE_FW_PATH_PROVIDER },
|
{ TYPE_FW_PATH_PROVIDER },
|
||||||
{ }
|
{ }
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ enum sPAPRTCEAccess {
|
|||||||
SPAPR_TCE_RW = 3,
|
SPAPR_TCE_RW = 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
QLIST_HEAD(spapr_tce_tables, sPAPRTCETable) spapr_tce_tables;
|
static QLIST_HEAD(spapr_tce_tables, sPAPRTCETable) spapr_tce_tables;
|
||||||
|
|
||||||
static sPAPRTCETable *spapr_tce_find_by_liobn(uint32_t liobn)
|
static sPAPRTCETable *spapr_tce_find_by_liobn(uint32_t liobn)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -272,7 +272,7 @@ static struct rtas_call {
|
|||||||
spapr_rtas_fn fn;
|
spapr_rtas_fn fn;
|
||||||
} rtas_table[TOKEN_MAX];
|
} rtas_table[TOKEN_MAX];
|
||||||
|
|
||||||
struct rtas_call *rtas_next = rtas_table;
|
static struct rtas_call *rtas_next = rtas_table;
|
||||||
|
|
||||||
target_ulong spapr_rtas_call(PowerPCCPU *cpu, sPAPREnvironment *spapr,
|
target_ulong spapr_rtas_call(PowerPCCPU *cpu, sPAPREnvironment *spapr,
|
||||||
uint32_t token, uint32_t nargs, target_ulong args,
|
uint32_t token, uint32_t nargs, target_ulong args,
|
||||||
|
|||||||
@@ -140,7 +140,6 @@ static void sch_handle_clear_func(SubchDev *sch)
|
|||||||
s->flags &= ~SCSW_FLAGS_MASK_PNO;
|
s->flags &= ~SCSW_FLAGS_MASK_PNO;
|
||||||
|
|
||||||
/* We always 'attempt to issue the clear signal', and we always succeed. */
|
/* We always 'attempt to issue the clear signal', and we always succeed. */
|
||||||
sch->orb = NULL;
|
|
||||||
sch->channel_prog = 0x0;
|
sch->channel_prog = 0x0;
|
||||||
sch->last_cmd_valid = false;
|
sch->last_cmd_valid = false;
|
||||||
s->ctrl &= ~SCSW_ACTL_CLEAR_PEND;
|
s->ctrl &= ~SCSW_ACTL_CLEAR_PEND;
|
||||||
@@ -163,7 +162,6 @@ static void sch_handle_halt_func(SubchDev *sch)
|
|||||||
path = 0x80;
|
path = 0x80;
|
||||||
|
|
||||||
/* We always 'attempt to issue the halt signal', and we always succeed. */
|
/* We always 'attempt to issue the halt signal', and we always succeed. */
|
||||||
sch->orb = NULL;
|
|
||||||
sch->channel_prog = 0x0;
|
sch->channel_prog = 0x0;
|
||||||
sch->last_cmd_valid = false;
|
sch->last_cmd_valid = false;
|
||||||
s->ctrl &= ~SCSW_ACTL_HALT_PEND;
|
s->ctrl &= ~SCSW_ACTL_HALT_PEND;
|
||||||
@@ -317,12 +315,11 @@ static int css_interpret_ccw(SubchDev *sch, hwaddr ccw_addr)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sch_handle_start_func(SubchDev *sch)
|
static void sch_handle_start_func(SubchDev *sch, ORB *orb)
|
||||||
{
|
{
|
||||||
|
|
||||||
PMCW *p = &sch->curr_status.pmcw;
|
PMCW *p = &sch->curr_status.pmcw;
|
||||||
SCSW *s = &sch->curr_status.scsw;
|
SCSW *s = &sch->curr_status.scsw;
|
||||||
ORB *orb = sch->orb;
|
|
||||||
int path;
|
int path;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@@ -331,6 +328,7 @@ static void sch_handle_start_func(SubchDev *sch)
|
|||||||
|
|
||||||
if (!(s->ctrl & SCSW_ACTL_SUSP)) {
|
if (!(s->ctrl & SCSW_ACTL_SUSP)) {
|
||||||
/* Look at the orb and try to execute the channel program. */
|
/* Look at the orb and try to execute the channel program. */
|
||||||
|
assert(orb != NULL); /* resume does not pass an orb */
|
||||||
p->intparm = orb->intparm;
|
p->intparm = orb->intparm;
|
||||||
if (!(orb->lpm & path)) {
|
if (!(orb->lpm & path)) {
|
||||||
/* Generate a deferred cc 3 condition. */
|
/* Generate a deferred cc 3 condition. */
|
||||||
@@ -406,7 +404,7 @@ static void sch_handle_start_func(SubchDev *sch)
|
|||||||
* read/writes) asynchronous later on if we start supporting more than
|
* read/writes) asynchronous later on if we start supporting more than
|
||||||
* our current very simple devices.
|
* our current very simple devices.
|
||||||
*/
|
*/
|
||||||
static void do_subchannel_work(SubchDev *sch)
|
static void do_subchannel_work(SubchDev *sch, ORB *orb)
|
||||||
{
|
{
|
||||||
|
|
||||||
SCSW *s = &sch->curr_status.scsw;
|
SCSW *s = &sch->curr_status.scsw;
|
||||||
@@ -416,7 +414,7 @@ static void do_subchannel_work(SubchDev *sch)
|
|||||||
} else if (s->ctrl & SCSW_FCTL_HALT_FUNC) {
|
} else if (s->ctrl & SCSW_FCTL_HALT_FUNC) {
|
||||||
sch_handle_halt_func(sch);
|
sch_handle_halt_func(sch);
|
||||||
} else if (s->ctrl & SCSW_FCTL_START_FUNC) {
|
} else if (s->ctrl & SCSW_FCTL_START_FUNC) {
|
||||||
sch_handle_start_func(sch);
|
sch_handle_start_func(sch, orb);
|
||||||
} else {
|
} else {
|
||||||
/* Cannot happen. */
|
/* Cannot happen. */
|
||||||
return;
|
return;
|
||||||
@@ -594,7 +592,6 @@ int css_do_xsch(SubchDev *sch)
|
|||||||
SCSW_ACTL_SUSP);
|
SCSW_ACTL_SUSP);
|
||||||
sch->channel_prog = 0x0;
|
sch->channel_prog = 0x0;
|
||||||
sch->last_cmd_valid = false;
|
sch->last_cmd_valid = false;
|
||||||
sch->orb = NULL;
|
|
||||||
s->dstat = 0;
|
s->dstat = 0;
|
||||||
s->cstat = 0;
|
s->cstat = 0;
|
||||||
ret = 0;
|
ret = 0;
|
||||||
@@ -618,7 +615,7 @@ int css_do_csch(SubchDev *sch)
|
|||||||
s->ctrl &= ~(SCSW_CTRL_MASK_FCTL | SCSW_CTRL_MASK_ACTL);
|
s->ctrl &= ~(SCSW_CTRL_MASK_FCTL | SCSW_CTRL_MASK_ACTL);
|
||||||
s->ctrl |= SCSW_FCTL_CLEAR_FUNC | SCSW_FCTL_CLEAR_FUNC;
|
s->ctrl |= SCSW_FCTL_CLEAR_FUNC | SCSW_FCTL_CLEAR_FUNC;
|
||||||
|
|
||||||
do_subchannel_work(sch);
|
do_subchannel_work(sch, NULL);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
@@ -659,7 +656,7 @@ int css_do_hsch(SubchDev *sch)
|
|||||||
}
|
}
|
||||||
s->ctrl |= SCSW_ACTL_HALT_PEND;
|
s->ctrl |= SCSW_ACTL_HALT_PEND;
|
||||||
|
|
||||||
do_subchannel_work(sch);
|
do_subchannel_work(sch, NULL);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
@@ -721,13 +718,12 @@ int css_do_ssch(SubchDev *sch, ORB *orb)
|
|||||||
if (channel_subsys->chnmon_active) {
|
if (channel_subsys->chnmon_active) {
|
||||||
css_update_chnmon(sch);
|
css_update_chnmon(sch);
|
||||||
}
|
}
|
||||||
sch->orb = orb;
|
|
||||||
sch->channel_prog = orb->cpa;
|
sch->channel_prog = orb->cpa;
|
||||||
/* Trigger the start function. */
|
/* Trigger the start function. */
|
||||||
s->ctrl |= (SCSW_FCTL_START_FUNC | SCSW_ACTL_START_PEND);
|
s->ctrl |= (SCSW_FCTL_START_FUNC | SCSW_ACTL_START_PEND);
|
||||||
s->flags &= ~SCSW_FLAGS_MASK_PNO;
|
s->flags &= ~SCSW_FLAGS_MASK_PNO;
|
||||||
|
|
||||||
do_subchannel_work(sch);
|
do_subchannel_work(sch, orb);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
@@ -957,7 +953,7 @@ int css_do_rsch(SubchDev *sch)
|
|||||||
}
|
}
|
||||||
|
|
||||||
s->ctrl |= SCSW_ACTL_RESUME_PEND;
|
s->ctrl |= SCSW_ACTL_RESUME_PEND;
|
||||||
do_subchannel_work(sch);
|
do_subchannel_work(sch, NULL);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
@@ -1267,7 +1263,6 @@ void css_reset_sch(SubchDev *sch)
|
|||||||
|
|
||||||
sch->channel_prog = 0x0;
|
sch->channel_prog = 0x0;
|
||||||
sch->last_cmd_valid = false;
|
sch->last_cmd_valid = false;
|
||||||
sch->orb = NULL;
|
|
||||||
sch->thinint_active = false;
|
sch->thinint_active = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -76,7 +76,6 @@ struct SubchDev {
|
|||||||
hwaddr channel_prog;
|
hwaddr channel_prog;
|
||||||
CCW1 last_cmd;
|
CCW1 last_cmd;
|
||||||
bool last_cmd_valid;
|
bool last_cmd_valid;
|
||||||
ORB *orb;
|
|
||||||
bool thinint_active;
|
bool thinint_active;
|
||||||
/* transport-provided data: */
|
/* transport-provided data: */
|
||||||
int (*ccw_cb) (SubchDev *, CCW1);
|
int (*ccw_cb) (SubchDev *, CCW1);
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ struct SCLPEventFacility {
|
|||||||
unsigned int receive_mask;
|
unsigned int receive_mask;
|
||||||
};
|
};
|
||||||
|
|
||||||
SCLPEvent cpu_hotplug;
|
static SCLPEvent cpu_hotplug;
|
||||||
|
|
||||||
/* return true if any child has event pending set */
|
/* return true if any child has event pending set */
|
||||||
static bool event_pending(SCLPEventFacility *ef)
|
static bool event_pending(SCLPEventFacility *ef)
|
||||||
|
|||||||
@@ -559,7 +559,6 @@ static int virtio_ccw_device_init(VirtioCcwDevice *dev, VirtIODevice *vdev)
|
|||||||
/* Initialize subchannel structure. */
|
/* Initialize subchannel structure. */
|
||||||
sch->channel_prog = 0x0;
|
sch->channel_prog = 0x0;
|
||||||
sch->last_cmd_valid = false;
|
sch->last_cmd_valid = false;
|
||||||
sch->orb = NULL;
|
|
||||||
sch->thinint_active = false;
|
sch->thinint_active = false;
|
||||||
/*
|
/*
|
||||||
* Use a device number if provided. Otherwise, fall back to subchannel
|
* Use a device number if provided. Otherwise, fall back to subchannel
|
||||||
|
|||||||
@@ -1179,7 +1179,7 @@ static uint64_t scsi_cmd_lba(SCSICommand *cmd)
|
|||||||
return lba;
|
return lba;
|
||||||
}
|
}
|
||||||
|
|
||||||
int scsi_req_parse(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf)
|
static int scsi_req_parse(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
|||||||
@@ -147,6 +147,15 @@ static void *virtio_scsi_load_request(QEMUFile *f, SCSIRequest *sreq)
|
|||||||
qemu_get_be32s(f, &n);
|
qemu_get_be32s(f, &n);
|
||||||
assert(n < vs->conf.num_queues);
|
assert(n < vs->conf.num_queues);
|
||||||
qemu_get_buffer(f, (unsigned char *)&req->elem, sizeof(req->elem));
|
qemu_get_buffer(f, (unsigned char *)&req->elem, sizeof(req->elem));
|
||||||
|
/* TODO: add a way for SCSIBusInfo's load_request to fail,
|
||||||
|
* and fail migration instead of asserting here.
|
||||||
|
* When we do, we might be able to re-enable NDEBUG below.
|
||||||
|
*/
|
||||||
|
#ifdef NDEBUG
|
||||||
|
#error building with NDEBUG is not supported
|
||||||
|
#endif
|
||||||
|
assert(req->elem.in_num <= ARRAY_SIZE(req->elem.in_sg));
|
||||||
|
assert(req->elem.out_num <= ARRAY_SIZE(req->elem.out_sg));
|
||||||
virtio_scsi_parse_req(s, vs->cmd_vqs[n], req);
|
virtio_scsi_parse_req(s, vs->cmd_vqs[n], req);
|
||||||
|
|
||||||
scsi_req_ref(sreq);
|
scsi_req_ref(sreq);
|
||||||
|
|||||||
@@ -230,8 +230,17 @@ static int ssi_sd_load(QEMUFile *f, void *opaque, int version_id)
|
|||||||
for (i = 0; i < 5; i++)
|
for (i = 0; i < 5; i++)
|
||||||
s->response[i] = qemu_get_be32(f);
|
s->response[i] = qemu_get_be32(f);
|
||||||
s->arglen = qemu_get_be32(f);
|
s->arglen = qemu_get_be32(f);
|
||||||
|
if (s->mode == SSI_SD_CMDARG &&
|
||||||
|
(s->arglen < 0 || s->arglen >= ARRAY_SIZE(s->cmdarg))) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
s->response_pos = qemu_get_be32(f);
|
s->response_pos = qemu_get_be32(f);
|
||||||
s->stopping = qemu_get_be32(f);
|
s->stopping = qemu_get_be32(f);
|
||||||
|
if (s->mode == SSI_SD_RESPONSE &&
|
||||||
|
(s->response_pos < 0 || s->response_pos >= ARRAY_SIZE(s->response) ||
|
||||||
|
(!s->stopping && s->arglen > ARRAY_SIZE(s->response)))) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
ss->cs = qemu_get_be32(f);
|
ss->cs = qemu_get_be32(f);
|
||||||
|
|
||||||
|
|||||||
@@ -240,11 +240,25 @@ static const MemoryRegionOps pl022_ops = {
|
|||||||
.endianness = DEVICE_NATIVE_ENDIAN,
|
.endianness = DEVICE_NATIVE_ENDIAN,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int pl022_post_load(void *opaque, int version_id)
|
||||||
|
{
|
||||||
|
PL022State *s = opaque;
|
||||||
|
|
||||||
|
if (s->tx_fifo_head < 0 ||
|
||||||
|
s->tx_fifo_head >= ARRAY_SIZE(s->tx_fifo) ||
|
||||||
|
s->rx_fifo_head < 0 ||
|
||||||
|
s->rx_fifo_head >= ARRAY_SIZE(s->rx_fifo)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static const VMStateDescription vmstate_pl022 = {
|
static const VMStateDescription vmstate_pl022 = {
|
||||||
.name = "pl022_ssp",
|
.name = "pl022_ssp",
|
||||||
.version_id = 1,
|
.version_id = 1,
|
||||||
.minimum_version_id = 1,
|
.minimum_version_id = 1,
|
||||||
.minimum_version_id_old = 1,
|
.minimum_version_id_old = 1,
|
||||||
|
.post_load = pl022_post_load,
|
||||||
.fields = (VMStateField[]) {
|
.fields = (VMStateField[]) {
|
||||||
VMSTATE_UINT32(cr0, PL022State),
|
VMSTATE_UINT32(cr0, PL022State),
|
||||||
VMSTATE_UINT32(cr1, PL022State),
|
VMSTATE_UINT32(cr1, PL022State),
|
||||||
|
|||||||
@@ -239,6 +239,18 @@ static int hpet_pre_load(void *opaque)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool hpet_validate_num_timers(void *opaque, int version_id)
|
||||||
|
{
|
||||||
|
HPETState *s = opaque;
|
||||||
|
|
||||||
|
if (s->num_timers < HPET_MIN_TIMERS) {
|
||||||
|
return false;
|
||||||
|
} else if (s->num_timers > HPET_MAX_TIMERS) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static int hpet_post_load(void *opaque, int version_id)
|
static int hpet_post_load(void *opaque, int version_id)
|
||||||
{
|
{
|
||||||
HPETState *s = opaque;
|
HPETState *s = opaque;
|
||||||
@@ -307,6 +319,7 @@ static const VMStateDescription vmstate_hpet = {
|
|||||||
VMSTATE_UINT64(isr, HPETState),
|
VMSTATE_UINT64(isr, HPETState),
|
||||||
VMSTATE_UINT64(hpet_counter, HPETState),
|
VMSTATE_UINT64(hpet_counter, HPETState),
|
||||||
VMSTATE_UINT8_V(num_timers, HPETState, 2),
|
VMSTATE_UINT8_V(num_timers, HPETState, 2),
|
||||||
|
VMSTATE_VALIDATE("num_timers in range", hpet_validate_num_timers),
|
||||||
VMSTATE_STRUCT_VARRAY_UINT8(timer, HPETState, num_timers, 0,
|
VMSTATE_STRUCT_VARRAY_UINT8(timer, HPETState, num_timers, 0,
|
||||||
vmstate_hpet_timer, HPETTimer),
|
vmstate_hpet_timer, HPETTimer),
|
||||||
VMSTATE_END_OF_LIST()
|
VMSTATE_END_OF_LIST()
|
||||||
|
|||||||
@@ -322,7 +322,7 @@ static void pit_post_load(PITCommonState *s)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pit_realizefn(DeviceState *dev, Error **err)
|
static void pit_realizefn(DeviceState *dev, Error **errp)
|
||||||
{
|
{
|
||||||
PITCommonState *pit = PIT_COMMON(dev);
|
PITCommonState *pit = PIT_COMMON(dev);
|
||||||
PITClass *pc = PIT_GET_CLASS(dev);
|
PITClass *pc = PIT_GET_CLASS(dev);
|
||||||
@@ -338,7 +338,7 @@ static void pit_realizefn(DeviceState *dev, Error **err)
|
|||||||
|
|
||||||
qdev_init_gpio_in(dev, pit_irq_control, 1);
|
qdev_init_gpio_in(dev, pit_irq_control, 1);
|
||||||
|
|
||||||
pc->parent_realize(dev, err);
|
pc->parent_realize(dev, errp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Property pit_properties[] = {
|
static Property pit_properties[] = {
|
||||||
|
|||||||
@@ -169,7 +169,7 @@ timer_write(void *opaque, hwaddr addr,
|
|||||||
if (value & TCSR_TINT)
|
if (value & TCSR_TINT)
|
||||||
value &= ~TCSR_TINT;
|
value &= ~TCSR_TINT;
|
||||||
|
|
||||||
xt->regs[addr] = value;
|
xt->regs[addr] = value & 0x7ff;
|
||||||
if (value & TCSR_ENT)
|
if (value & TCSR_ENT)
|
||||||
timer_enable(xt);
|
timer_enable(xt);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ ifeq ($(CONFIG_USB_SMARTCARD),y)
|
|||||||
common-obj-y += dev-smartcard-reader.o
|
common-obj-y += dev-smartcard-reader.o
|
||||||
common-obj-y += ccid-card-passthru.o
|
common-obj-y += ccid-card-passthru.o
|
||||||
common-obj-$(CONFIG_SMARTCARD_NSS) += ccid-card-emulated.o
|
common-obj-$(CONFIG_SMARTCARD_NSS) += ccid-card-emulated.o
|
||||||
|
ccid-card-emulated.o-cflags := -I$(SRC_PATH)/libcacard
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_POSIX),y)
|
ifeq ($(CONFIG_POSIX),y)
|
||||||
|
|||||||
@@ -49,7 +49,9 @@ static int usb_device_post_load(void *opaque, int version_id)
|
|||||||
} else {
|
} else {
|
||||||
dev->attached = 1;
|
dev->attached = 1;
|
||||||
}
|
}
|
||||||
if (dev->setup_index >= sizeof(dev->data_buf) ||
|
if (dev->setup_index < 0 ||
|
||||||
|
dev->setup_len < 0 ||
|
||||||
|
dev->setup_index >= sizeof(dev->data_buf) ||
|
||||||
dev->setup_len >= sizeof(dev->data_buf)) {
|
dev->setup_len >= sizeof(dev->data_buf)) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ enum mtp_code {
|
|||||||
RES_INVALID_TRANSACTION_ID = 0x2004,
|
RES_INVALID_TRANSACTION_ID = 0x2004,
|
||||||
RES_OPERATION_NOT_SUPPORTED = 0x2005,
|
RES_OPERATION_NOT_SUPPORTED = 0x2005,
|
||||||
RES_PARAMETER_NOT_SUPPORTED = 0x2006,
|
RES_PARAMETER_NOT_SUPPORTED = 0x2006,
|
||||||
|
RES_INCOMPLETE_TRANSFER = 0x2007,
|
||||||
RES_INVALID_STORAGE_ID = 0x2008,
|
RES_INVALID_STORAGE_ID = 0x2008,
|
||||||
RES_INVALID_OBJECT_HANDLE = 0x2009,
|
RES_INVALID_OBJECT_HANDLE = 0x2009,
|
||||||
RES_SPEC_BY_FORMAT_UNSUPPORTED = 0x2014,
|
RES_SPEC_BY_FORMAT_UNSUPPORTED = 0x2014,
|
||||||
@@ -294,7 +295,7 @@ static MTPObject *usb_mtp_object_alloc(MTPState *s, uint32_t handle,
|
|||||||
goto ignore;
|
goto ignore;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stderr, "%s: 0x%x %s\n", __func__, o->handle, o->path);
|
trace_usb_mtp_object_alloc(s->dev.addr, o->handle, o->path);
|
||||||
|
|
||||||
QTAILQ_INSERT_TAIL(&s->objects, o, next);
|
QTAILQ_INSERT_TAIL(&s->objects, o, next);
|
||||||
return o;
|
return o;
|
||||||
@@ -310,7 +311,7 @@ static void usb_mtp_object_free(MTPState *s, MTPObject *o)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
fprintf(stderr, "%s: 0x%x %s\n", __func__, o->handle, o->path);
|
trace_usb_mtp_object_free(s->dev.addr, o->handle, o->path);
|
||||||
|
|
||||||
QTAILQ_REMOVE(&s->objects, o, next);
|
QTAILQ_REMOVE(&s->objects, o, next);
|
||||||
for (i = 0; i < o->nchildren; i++) {
|
for (i = 0; i < o->nchildren; i++) {
|
||||||
@@ -416,7 +417,7 @@ static void usb_mtp_add_u32(MTPData *data, uint32_t val)
|
|||||||
|
|
||||||
static void usb_mtp_add_u64(MTPData *data, uint64_t val)
|
static void usb_mtp_add_u64(MTPData *data, uint64_t val)
|
||||||
{
|
{
|
||||||
usb_mtp_realloc(data, 4);
|
usb_mtp_realloc(data, 8);
|
||||||
data->data[data->length++] = (val >> 0) & 0xff;
|
data->data[data->length++] = (val >> 0) & 0xff;
|
||||||
data->data[data->length++] = (val >> 8) & 0xff;
|
data->data[data->length++] = (val >> 8) & 0xff;
|
||||||
data->data[data->length++] = (val >> 16) & 0xff;
|
data->data[data->length++] = (val >> 16) & 0xff;
|
||||||
@@ -424,7 +425,7 @@ static void usb_mtp_add_u64(MTPData *data, uint64_t val)
|
|||||||
data->data[data->length++] = (val >> 32) & 0xff;
|
data->data[data->length++] = (val >> 32) & 0xff;
|
||||||
data->data[data->length++] = (val >> 40) & 0xff;
|
data->data[data->length++] = (val >> 40) & 0xff;
|
||||||
data->data[data->length++] = (val >> 48) & 0xff;
|
data->data[data->length++] = (val >> 48) & 0xff;
|
||||||
data->data[data->length++] = (val >> 54) & 0xff;
|
data->data[data->length++] = (val >> 56) & 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void usb_mtp_add_u16_array(MTPData *data, uint32_t len,
|
static void usb_mtp_add_u16_array(MTPData *data, uint32_t len,
|
||||||
@@ -533,7 +534,7 @@ static MTPData *usb_mtp_get_device_info(MTPState *s, MTPControl *c)
|
|||||||
|
|
||||||
trace_usb_mtp_op_get_device_info(s->dev.addr);
|
trace_usb_mtp_op_get_device_info(s->dev.addr);
|
||||||
|
|
||||||
usb_mtp_add_u16(d, 0x0100);
|
usb_mtp_add_u16(d, 100);
|
||||||
usb_mtp_add_u32(d, 0xffffffff);
|
usb_mtp_add_u32(d, 0xffffffff);
|
||||||
usb_mtp_add_u16(d, 0x0101);
|
usb_mtp_add_u16(d, 0x0101);
|
||||||
usb_mtp_add_wstr(d, L"");
|
usb_mtp_add_wstr(d, L"");
|
||||||
@@ -548,7 +549,7 @@ static MTPData *usb_mtp_get_device_info(MTPState *s, MTPControl *c)
|
|||||||
usb_mtp_add_wstr(d, L"" MTP_MANUFACTURER);
|
usb_mtp_add_wstr(d, L"" MTP_MANUFACTURER);
|
||||||
usb_mtp_add_wstr(d, L"" MTP_PRODUCT);
|
usb_mtp_add_wstr(d, L"" MTP_PRODUCT);
|
||||||
usb_mtp_add_wstr(d, L"0.1");
|
usb_mtp_add_wstr(d, L"0.1");
|
||||||
usb_mtp_add_wstr(d, L"123456789abcdef123456789abcdef");
|
usb_mtp_add_wstr(d, L"0123456789abcdef0123456789abcdef");
|
||||||
|
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
@@ -669,6 +670,7 @@ static MTPData *usb_mtp_get_object(MTPState *s, MTPControl *c,
|
|||||||
|
|
||||||
d->fd = open(o->path, O_RDONLY);
|
d->fd = open(o->path, O_RDONLY);
|
||||||
if (d->fd == -1) {
|
if (d->fd == -1) {
|
||||||
|
usb_mtp_data_free(d);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
d->length = o->stat.st_size;
|
d->length = o->stat.st_size;
|
||||||
@@ -688,6 +690,7 @@ static MTPData *usb_mtp_get_partial_object(MTPState *s, MTPControl *c,
|
|||||||
|
|
||||||
d->fd = open(o->path, O_RDONLY);
|
d->fd = open(o->path, O_RDONLY);
|
||||||
if (d->fd == -1) {
|
if (d->fd == -1) {
|
||||||
|
usb_mtp_data_free(d);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -843,8 +846,7 @@ static void usb_mtp_command(MTPState *s, MTPControl *c)
|
|||||||
res0 = data_in->length;
|
res0 = data_in->length;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "%s: unknown command code 0x%04x\n",
|
trace_usb_mtp_op_unknown(s->dev.addr, c->code);
|
||||||
__func__, c->code);
|
|
||||||
usb_mtp_queue_result(s, RES_OPERATION_NOT_SUPPORTED,
|
usb_mtp_queue_result(s, RES_OPERATION_NOT_SUPPORTED,
|
||||||
c->trans, 0, 0, 0);
|
c->trans, 0, 0, 0);
|
||||||
return;
|
return;
|
||||||
@@ -892,6 +894,7 @@ static void usb_mtp_handle_control(USBDevice *dev, USBPacket *p,
|
|||||||
|
|
||||||
static void usb_mtp_cancel_packet(USBDevice *dev, USBPacket *p)
|
static void usb_mtp_cancel_packet(USBDevice *dev, USBPacket *p)
|
||||||
{
|
{
|
||||||
|
/* we don't use async packets, so this should never be called */
|
||||||
fprintf(stderr, "%s\n", __func__);
|
fprintf(stderr, "%s\n", __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -944,7 +947,8 @@ static void usb_mtp_handle_data(USBDevice *dev, USBPacket *p)
|
|||||||
}
|
}
|
||||||
rc = read(d->fd, d->data, dlen);
|
rc = read(d->fd, d->data, dlen);
|
||||||
if (rc != dlen) {
|
if (rc != dlen) {
|
||||||
fprintf(stderr, "%s: TODO: handle read error\n", __func__);
|
memset(d->data, 0, dlen);
|
||||||
|
s->result->code = RES_INCOMPLETE_TRANSFER;
|
||||||
}
|
}
|
||||||
usb_packet_copy(p, d->data, dlen);
|
usb_packet_copy(p, d->data, dlen);
|
||||||
}
|
}
|
||||||
@@ -996,6 +1000,14 @@ static void usb_mtp_handle_data(USBDevice *dev, USBPacket *p)
|
|||||||
cmd.argc = (le32_to_cpu(container.length) - sizeof(container))
|
cmd.argc = (le32_to_cpu(container.length) - sizeof(container))
|
||||||
/ sizeof(uint32_t);
|
/ sizeof(uint32_t);
|
||||||
cmd.trans = le32_to_cpu(container.trans);
|
cmd.trans = le32_to_cpu(container.trans);
|
||||||
|
if (cmd.argc > ARRAY_SIZE(cmd.argv)) {
|
||||||
|
cmd.argc = ARRAY_SIZE(cmd.argv);
|
||||||
|
}
|
||||||
|
if (p->iov.size < sizeof(container) + cmd.argc * sizeof(uint32_t)) {
|
||||||
|
trace_usb_mtp_stall(s->dev.addr, "packet too small");
|
||||||
|
p->status = USB_RET_STALL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
usb_packet_copy(p, ¶ms, cmd.argc * sizeof(uint32_t));
|
usb_packet_copy(p, ¶ms, cmd.argc * sizeof(uint32_t));
|
||||||
for (i = 0; i < cmd.argc; i++) {
|
for (i = 0; i < cmd.argc; i++) {
|
||||||
cmd.argv[i] = le32_to_cpu(params[i]);
|
cmd.argv[i] = le32_to_cpu(params[i]);
|
||||||
@@ -1009,8 +1021,7 @@ static void usb_mtp_handle_data(USBDevice *dev, USBPacket *p)
|
|||||||
usb_mtp_command(s, &cmd);
|
usb_mtp_command(s, &cmd);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
iov_hexdump(p->iov.iov, p->iov.niov, stderr, "mtp-out", 32);
|
/* not needed as long as the mtp device is read-only */
|
||||||
trace_usb_mtp_stall(s->dev.addr, "TODO: implement data-out");
|
|
||||||
p->status = USB_RET_STALL;
|
p->status = USB_RET_STALL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1044,7 +1055,7 @@ static int usb_mtp_initfn(USBDevice *dev)
|
|||||||
QTAILQ_INIT(&s->objects);
|
QTAILQ_INIT(&s->objects);
|
||||||
if (s->desc == NULL) {
|
if (s->desc == NULL) {
|
||||||
s->desc = strrchr(s->root, '/');
|
s->desc = strrchr(s->root, '/');
|
||||||
if (s->desc) {
|
if (s->desc && s->desc[0]) {
|
||||||
s->desc = g_strdup(s->desc + 1);
|
s->desc = g_strdup(s->desc + 1);
|
||||||
} else {
|
} else {
|
||||||
s->desc = g_strdup("none");
|
s->desc = g_strdup("none");
|
||||||
|
|||||||
@@ -80,13 +80,13 @@ typedef struct {
|
|||||||
uint32_t bulk_head, bulk_cur;
|
uint32_t bulk_head, bulk_cur;
|
||||||
uint32_t per_cur;
|
uint32_t per_cur;
|
||||||
uint32_t done;
|
uint32_t done;
|
||||||
int done_count;
|
int32_t done_count;
|
||||||
|
|
||||||
/* Frame counter partition */
|
/* Frame counter partition */
|
||||||
uint32_t fsmps:15;
|
uint16_t fsmps;
|
||||||
uint32_t fit:1;
|
uint8_t fit;
|
||||||
uint32_t fi:14;
|
uint16_t fi;
|
||||||
uint32_t frt:1;
|
uint8_t frt;
|
||||||
uint16_t frame_number;
|
uint16_t frame_number;
|
||||||
uint16_t padding;
|
uint16_t padding;
|
||||||
uint32_t pstart;
|
uint32_t pstart;
|
||||||
@@ -111,7 +111,7 @@ typedef struct {
|
|||||||
USBPacket usb_packet;
|
USBPacket usb_packet;
|
||||||
uint8_t usb_buf[8192];
|
uint8_t usb_buf[8192];
|
||||||
uint32_t async_td;
|
uint32_t async_td;
|
||||||
int async_complete;
|
bool async_complete;
|
||||||
|
|
||||||
} OHCIState;
|
} OHCIState;
|
||||||
|
|
||||||
@@ -693,7 +693,7 @@ static void ohci_async_complete_packet(USBPort *port, USBPacket *packet)
|
|||||||
#ifdef DEBUG_PACKET
|
#ifdef DEBUG_PACKET
|
||||||
DPRINTF("Async packet complete\n");
|
DPRINTF("Async packet complete\n");
|
||||||
#endif
|
#endif
|
||||||
ohci->async_complete = 1;
|
ohci->async_complete = true;
|
||||||
ohci_process_lists(ohci, 1);
|
ohci_process_lists(ohci, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1058,7 +1058,7 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed)
|
|||||||
#endif
|
#endif
|
||||||
if (completion) {
|
if (completion) {
|
||||||
ohci->async_td = 0;
|
ohci->async_td = 0;
|
||||||
ohci->async_complete = 0;
|
ohci->async_complete = false;
|
||||||
} else {
|
} else {
|
||||||
if (ohci->async_td) {
|
if (ohci->async_td) {
|
||||||
/* ??? The hardware should allow one active packet per
|
/* ??? The hardware should allow one active packet per
|
||||||
@@ -1984,6 +1984,108 @@ static Property ohci_pci_properties[] = {
|
|||||||
DEFINE_PROP_END_OF_LIST(),
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const VMStateDescription vmstate_ohci_state_port = {
|
||||||
|
.name = "ohci-core/port",
|
||||||
|
.version_id = 1,
|
||||||
|
.minimum_version_id = 1,
|
||||||
|
.minimum_version_id_old = 1,
|
||||||
|
.fields = (VMStateField []) {
|
||||||
|
VMSTATE_UINT32(ctrl, OHCIPort),
|
||||||
|
VMSTATE_END_OF_LIST()
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool ohci_eof_timer_needed(void *opaque)
|
||||||
|
{
|
||||||
|
OHCIState *ohci = opaque;
|
||||||
|
|
||||||
|
return ohci->eof_timer != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ohci_eof_timer_pre_load(void *opaque)
|
||||||
|
{
|
||||||
|
OHCIState *ohci = opaque;
|
||||||
|
|
||||||
|
ohci_bus_start(ohci);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const VMStateDescription vmstate_ohci_eof_timer = {
|
||||||
|
.name = "ohci-core/eof-timer",
|
||||||
|
.version_id = 1,
|
||||||
|
.minimum_version_id = 1,
|
||||||
|
.minimum_version_id_old = 1,
|
||||||
|
.pre_load = ohci_eof_timer_pre_load,
|
||||||
|
.fields = (VMStateField []) {
|
||||||
|
VMSTATE_TIMER(eof_timer, OHCIState),
|
||||||
|
VMSTATE_END_OF_LIST()
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const VMStateDescription vmstate_ohci_state = {
|
||||||
|
.name = "ohci-core",
|
||||||
|
.version_id = 1,
|
||||||
|
.minimum_version_id = 1,
|
||||||
|
.fields = (VMStateField[]) {
|
||||||
|
VMSTATE_INT64(sof_time, OHCIState),
|
||||||
|
VMSTATE_UINT32(ctl, OHCIState),
|
||||||
|
VMSTATE_UINT32(status, OHCIState),
|
||||||
|
VMSTATE_UINT32(intr_status, OHCIState),
|
||||||
|
VMSTATE_UINT32(intr, OHCIState),
|
||||||
|
VMSTATE_UINT32(hcca, OHCIState),
|
||||||
|
VMSTATE_UINT32(ctrl_head, OHCIState),
|
||||||
|
VMSTATE_UINT32(ctrl_cur, OHCIState),
|
||||||
|
VMSTATE_UINT32(bulk_head, OHCIState),
|
||||||
|
VMSTATE_UINT32(bulk_cur, OHCIState),
|
||||||
|
VMSTATE_UINT32(per_cur, OHCIState),
|
||||||
|
VMSTATE_UINT32(done, OHCIState),
|
||||||
|
VMSTATE_INT32(done_count, OHCIState),
|
||||||
|
VMSTATE_UINT16(fsmps, OHCIState),
|
||||||
|
VMSTATE_UINT8(fit, OHCIState),
|
||||||
|
VMSTATE_UINT16(fi, OHCIState),
|
||||||
|
VMSTATE_UINT8(frt, OHCIState),
|
||||||
|
VMSTATE_UINT16(frame_number, OHCIState),
|
||||||
|
VMSTATE_UINT16(padding, OHCIState),
|
||||||
|
VMSTATE_UINT32(pstart, OHCIState),
|
||||||
|
VMSTATE_UINT32(lst, OHCIState),
|
||||||
|
VMSTATE_UINT32(rhdesc_a, OHCIState),
|
||||||
|
VMSTATE_UINT32(rhdesc_b, OHCIState),
|
||||||
|
VMSTATE_UINT32(rhstatus, OHCIState),
|
||||||
|
VMSTATE_STRUCT_ARRAY(rhport, OHCIState, OHCI_MAX_PORTS, 0,
|
||||||
|
vmstate_ohci_state_port, OHCIPort),
|
||||||
|
VMSTATE_UINT32(hstatus, OHCIState),
|
||||||
|
VMSTATE_UINT32(hmask, OHCIState),
|
||||||
|
VMSTATE_UINT32(hreset, OHCIState),
|
||||||
|
VMSTATE_UINT32(htest, OHCIState),
|
||||||
|
VMSTATE_UINT32(old_ctl, OHCIState),
|
||||||
|
VMSTATE_UINT8_ARRAY(usb_buf, OHCIState, 8192),
|
||||||
|
VMSTATE_UINT32(async_td, OHCIState),
|
||||||
|
VMSTATE_BOOL(async_complete, OHCIState),
|
||||||
|
VMSTATE_END_OF_LIST()
|
||||||
|
},
|
||||||
|
.subsections = (VMStateSubsection []) {
|
||||||
|
{
|
||||||
|
.vmsd = &vmstate_ohci_eof_timer,
|
||||||
|
.needed = ohci_eof_timer_needed,
|
||||||
|
} , {
|
||||||
|
/* empty */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const VMStateDescription vmstate_ohci = {
|
||||||
|
.name = "ohci",
|
||||||
|
.version_id = 1,
|
||||||
|
.minimum_version_id = 1,
|
||||||
|
.minimum_version_id_old = 1,
|
||||||
|
.fields = (VMStateField[]) {
|
||||||
|
VMSTATE_PCI_DEVICE(parent_obj, OHCIPCIState),
|
||||||
|
VMSTATE_STRUCT(state, OHCIPCIState, 1, vmstate_ohci_state, OHCIState),
|
||||||
|
VMSTATE_END_OF_LIST()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
static void ohci_pci_class_init(ObjectClass *klass, void *data)
|
static void ohci_pci_class_init(ObjectClass *klass, void *data)
|
||||||
{
|
{
|
||||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||||
@@ -1997,6 +2099,7 @@ static void ohci_pci_class_init(ObjectClass *klass, void *data)
|
|||||||
dc->desc = "Apple USB Controller";
|
dc->desc = "Apple USB Controller";
|
||||||
dc->props = ohci_pci_properties;
|
dc->props = ohci_pci_properties;
|
||||||
dc->hotpluggable = false;
|
dc->hotpluggable = false;
|
||||||
|
dc->vmsd = &vmstate_ohci;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const TypeInfo ohci_pci_info = {
|
static const TypeInfo ohci_pci_info = {
|
||||||
|
|||||||
@@ -142,10 +142,12 @@ static void balloon_stats_set_poll_interval(Object *obj, struct Visitor *v,
|
|||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
VirtIOBalloon *s = opaque;
|
VirtIOBalloon *s = opaque;
|
||||||
|
Error *local_err = NULL;
|
||||||
int64_t value;
|
int64_t value;
|
||||||
|
|
||||||
visit_type_int(v, &value, name, errp);
|
visit_type_int(v, &value, name, &local_err);
|
||||||
if (error_is_set(errp)) {
|
if (local_err) {
|
||||||
|
error_propagate(errp, local_err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -430,6 +430,12 @@ void virtqueue_map_sg(struct iovec *sg, hwaddr *addr,
|
|||||||
unsigned int i;
|
unsigned int i;
|
||||||
hwaddr len;
|
hwaddr len;
|
||||||
|
|
||||||
|
if (num_sg >= VIRTQUEUE_MAX_SIZE) {
|
||||||
|
error_report("virtio: map attempt out of bounds: %zd > %d",
|
||||||
|
num_sg, VIRTQUEUE_MAX_SIZE);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < num_sg; i++) {
|
for (i = 0; i < num_sg; i++) {
|
||||||
len = sg[i].iov_len;
|
len = sg[i].iov_len;
|
||||||
sg[i].iov_base = cpu_physical_memory_map(addr[i], &len, is_write);
|
sg[i].iov_base = cpu_physical_memory_map(addr[i], &len, is_write);
|
||||||
@@ -891,7 +897,9 @@ int virtio_set_features(VirtIODevice *vdev, uint32_t val)
|
|||||||
|
|
||||||
int virtio_load(VirtIODevice *vdev, QEMUFile *f)
|
int virtio_load(VirtIODevice *vdev, QEMUFile *f)
|
||||||
{
|
{
|
||||||
int num, i, ret;
|
int i, ret;
|
||||||
|
int32_t config_len;
|
||||||
|
uint32_t num;
|
||||||
uint32_t features;
|
uint32_t features;
|
||||||
uint32_t supported_features;
|
uint32_t supported_features;
|
||||||
BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
|
BusState *qbus = qdev_get_parent_bus(DEVICE(vdev));
|
||||||
@@ -906,6 +914,9 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f)
|
|||||||
qemu_get_8s(f, &vdev->status);
|
qemu_get_8s(f, &vdev->status);
|
||||||
qemu_get_8s(f, &vdev->isr);
|
qemu_get_8s(f, &vdev->isr);
|
||||||
qemu_get_be16s(f, &vdev->queue_sel);
|
qemu_get_be16s(f, &vdev->queue_sel);
|
||||||
|
if (vdev->queue_sel >= VIRTIO_PCI_QUEUE_MAX) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
qemu_get_be32s(f, &features);
|
qemu_get_be32s(f, &features);
|
||||||
|
|
||||||
if (virtio_set_features(vdev, features) < 0) {
|
if (virtio_set_features(vdev, features) < 0) {
|
||||||
@@ -914,11 +925,21 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f)
|
|||||||
features, supported_features);
|
features, supported_features);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
vdev->config_len = qemu_get_be32(f);
|
config_len = qemu_get_be32(f);
|
||||||
|
if (config_len != vdev->config_len) {
|
||||||
|
error_report("Unexpected config length 0x%x. Expected 0x%zx",
|
||||||
|
config_len, vdev->config_len);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
qemu_get_buffer(f, vdev->config, vdev->config_len);
|
qemu_get_buffer(f, vdev->config, vdev->config_len);
|
||||||
|
|
||||||
num = qemu_get_be32(f);
|
num = qemu_get_be32(f);
|
||||||
|
|
||||||
|
if (num > VIRTIO_PCI_QUEUE_MAX) {
|
||||||
|
error_report("Invalid number of PCI queues: 0x%x", num);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < num; i++) {
|
for (i = 0; i < num; i++) {
|
||||||
vdev->vq[i].vring.num = qemu_get_be32(f);
|
vdev->vq[i].vring.num = qemu_get_be32(f);
|
||||||
if (k->has_variable_vring_alignment) {
|
if (k->has_variable_vring_alignment) {
|
||||||
|
|||||||
@@ -42,6 +42,8 @@ typedef struct IB700state {
|
|||||||
ISADevice parent_obj;
|
ISADevice parent_obj;
|
||||||
|
|
||||||
QEMUTimer *timer;
|
QEMUTimer *timer;
|
||||||
|
|
||||||
|
PortioList port_list;
|
||||||
} IB700State;
|
} IB700State;
|
||||||
|
|
||||||
/* This is the timer. We use a global here because the watchdog
|
/* This is the timer. We use a global here because the watchdog
|
||||||
@@ -106,14 +108,13 @@ static const MemoryRegionPortio wdt_portio_list[] = {
|
|||||||
static void wdt_ib700_realize(DeviceState *dev, Error **errp)
|
static void wdt_ib700_realize(DeviceState *dev, Error **errp)
|
||||||
{
|
{
|
||||||
IB700State *s = IB700(dev);
|
IB700State *s = IB700(dev);
|
||||||
PortioList *port_list = g_new(PortioList, 1);
|
|
||||||
|
|
||||||
ib700_debug("watchdog init\n");
|
ib700_debug("watchdog init\n");
|
||||||
|
|
||||||
s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, ib700_timer_expired, s);
|
s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, ib700_timer_expired, s);
|
||||||
|
|
||||||
portio_list_init(port_list, OBJECT(s), wdt_portio_list, s, "ib700");
|
portio_list_init(&s->port_list, OBJECT(s), wdt_portio_list, s, "ib700");
|
||||||
portio_list_add(port_list, isa_address_space_io(&s->parent_obj), 0);
|
portio_list_add(&s->port_list, isa_address_space_io(&s->parent_obj), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void wdt_ib700_reset(DeviceState *dev)
|
static void wdt_ib700_reset(DeviceState *dev)
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user