Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Andrea Fioraldi 2021-12-06 10:02:49 +01:00
commit e97deaae59
135 changed files with 1102 additions and 726 deletions

View File

@ -324,7 +324,7 @@ F: disas/sparc.c
X86 TCG CPUs X86 TCG CPUs
M: Paolo Bonzini <pbonzini@redhat.com> M: Paolo Bonzini <pbonzini@redhat.com>
M: Richard Henderson <richard.henderson@linaro.org> M: Richard Henderson <richard.henderson@linaro.org>
M: Eduardo Habkost <ehabkost@redhat.com> M: Eduardo Habkost <eduardo@habkost.net>
S: Maintained S: Maintained
F: target/i386/tcg/ F: target/i386/tcg/
F: tests/tcg/i386/ F: tests/tcg/i386/
@ -1628,7 +1628,7 @@ F: include/hw/i386/microvm.h
F: pc-bios/bios-microvm.bin F: pc-bios/bios-microvm.bin
Machine core Machine core
M: Eduardo Habkost <ehabkost@redhat.com> M: Eduardo Habkost <eduardo@habkost.net>
M: Marcel Apfelbaum <marcel.apfelbaum@gmail.com> M: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
R: Philippe Mathieu-Daudé <philmd@redhat.com> R: Philippe Mathieu-Daudé <philmd@redhat.com>
S: Supported S: Supported
@ -2648,13 +2648,13 @@ F: backends/cryptodev*.c
Python library Python library
M: John Snow <jsnow@redhat.com> M: John Snow <jsnow@redhat.com>
M: Cleber Rosa <crosa@redhat.com> M: Cleber Rosa <crosa@redhat.com>
R: Eduardo Habkost <ehabkost@redhat.com> R: Eduardo Habkost <eduardo@habkost.net>
S: Maintained S: Maintained
F: python/ F: python/
T: git https://gitlab.com/jsnow/qemu.git python T: git https://gitlab.com/jsnow/qemu.git python
Python scripts Python scripts
M: Eduardo Habkost <ehabkost@redhat.com> M: Eduardo Habkost <eduardo@habkost.net>
M: Cleber Rosa <crosa@redhat.com> M: Cleber Rosa <crosa@redhat.com>
S: Odd Fixes S: Odd Fixes
F: scripts/*.py F: scripts/*.py
@ -2730,7 +2730,7 @@ T: git https://github.com/mdroth/qemu.git qga
QOM QOM
M: Paolo Bonzini <pbonzini@redhat.com> M: Paolo Bonzini <pbonzini@redhat.com>
R: Daniel P. Berrange <berrange@redhat.com> R: Daniel P. Berrange <berrange@redhat.com>
R: Eduardo Habkost <ehabkost@redhat.com> R: Eduardo Habkost <eduardo@habkost.net>
S: Supported S: Supported
F: docs/qdev-device-use.txt F: docs/qdev-device-use.txt
F: hw/core/qdev* F: hw/core/qdev*
@ -2750,7 +2750,7 @@ F: tests/unit/check-qom-proplist.c
F: tests/unit/test-qdev-global-props.c F: tests/unit/test-qdev-global-props.c
QOM boilerplate conversion script QOM boilerplate conversion script
M: Eduardo Habkost <ehabkost@redhat.com> M: Eduardo Habkost <eduardo@habkost.net>
S: Maintained S: Maintained
F: scripts/codeconverter/ F: scripts/codeconverter/
@ -3469,7 +3469,7 @@ M: Alex Bennée <alex.bennee@linaro.org>
M: Philippe Mathieu-Daudé <f4bug@amsat.org> M: Philippe Mathieu-Daudé <f4bug@amsat.org>
M: Thomas Huth <thuth@redhat.com> M: Thomas Huth <thuth@redhat.com>
R: Wainer dos Santos Moschetta <wainersm@redhat.com> R: Wainer dos Santos Moschetta <wainersm@redhat.com>
R: Willian Rampazzo <willianr@redhat.com> R: Beraldo Leal <bleal@redhat.com>
S: Maintained S: Maintained
F: .github/lockdown.yml F: .github/lockdown.yml
F: .gitlab-ci.yml F: .gitlab-ci.yml
@ -3507,10 +3507,16 @@ W: https://trello.com/b/6Qi1pxVn/avocado-qemu
R: Cleber Rosa <crosa@redhat.com> R: Cleber Rosa <crosa@redhat.com>
R: Philippe Mathieu-Daudé <philmd@redhat.com> R: Philippe Mathieu-Daudé <philmd@redhat.com>
R: Wainer dos Santos Moschetta <wainersm@redhat.com> R: Wainer dos Santos Moschetta <wainersm@redhat.com>
R: Willian Rampazzo <willianr@redhat.com> R: Beraldo Leal <bleal@redhat.com>
S: Odd Fixes S: Odd Fixes
F: tests/avocado/ F: tests/avocado/
GitLab custom runner (Works On Arm Sponsored)
M: Alex Bennée <alex.bennee@linaro.org>
M: Philippe Mathieu-Daudé <f4bug@amsat.org>
S: Maintained
F: .gitlab-ci.d/custom-runners/ubuntu-20.04-aarch64.yml
Documentation Documentation
------------- -------------
Build system architecture Build system architecture

View File

@ -1 +1 @@
6.2.91 6.1.93

View File

@ -733,6 +733,15 @@ static inline bool need_replay_interrupt(int interrupt_request)
static inline bool cpu_handle_interrupt(CPUState *cpu, static inline bool cpu_handle_interrupt(CPUState *cpu,
TranslationBlock **last_tb) TranslationBlock **last_tb)
{ {
/*
* If we have requested custom cflags with CF_NOIRQ we should
* skip checking here. Any pending interrupts will get picked up
* by the next TB we execute under normal cflags.
*/
if (cpu->cflags_next_tb != -1 && cpu->cflags_next_tb & CF_NOIRQ) {
return false;
}
/* Clear the interrupt flag now since we're processing /* Clear the interrupt flag now since we're processing
* cpu->interrupt_request and cpu->exit_request. * cpu->interrupt_request and cpu->exit_request.
* Ensure zeroing happens before reading cpu->exit_request or * Ensure zeroing happens before reading cpu->exit_request or

View File

@ -2243,7 +2243,7 @@ tb_invalidate_phys_page_range__locked(struct page_collection *pages,
if (current_tb_modified) { if (current_tb_modified) {
page_collection_unlock(pages); page_collection_unlock(pages);
/* Force execution of one insn next time. */ /* Force execution of one insn next time. */
cpu->cflags_next_tb = 1 | curr_cflags(cpu); cpu->cflags_next_tb = 1 | CF_NOIRQ | curr_cflags(cpu);
mmap_unlock(); mmap_unlock();
cpu_loop_exit_noexc(cpu); cpu_loop_exit_noexc(cpu);
} }
@ -2411,7 +2411,7 @@ static bool tb_invalidate_phys_page(tb_page_addr_t addr, uintptr_t pc)
#ifdef TARGET_HAS_PRECISE_SMC #ifdef TARGET_HAS_PRECISE_SMC
if (current_tb_modified) { if (current_tb_modified) {
/* Force execution of one insn next time. */ /* Force execution of one insn next time. */
cpu->cflags_next_tb = 1 | curr_cflags(cpu); cpu->cflags_next_tb = 1 | CF_NOIRQ | curr_cflags(cpu);
return true; return true;
} }
#endif #endif

View File

@ -1279,8 +1279,18 @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
qemu_co_mutex_init(&s->lock); qemu_co_mutex_init(&s->lock);
ret = 0; qemu_opts_del(opts);
return 0;
fail: fail:
g_free(s->qcow_filename);
s->qcow_filename = NULL;
g_free(s->cluster_buffer);
s->cluster_buffer = NULL;
g_free(s->used_clusters);
s->used_clusters = NULL;
qemu_opts_del(opts); qemu_opts_del(opts);
return ret; return ret;
} }
@ -3118,7 +3128,7 @@ static int enable_write_target(BlockDriverState *bs, Error **errp)
int size = sector2cluster(s, s->sector_count); int size = sector2cluster(s, s->sector_count);
QDict *options; QDict *options;
s->used_clusters = calloc(size, 1); s->used_clusters = g_malloc0(size);
array_init(&(s->commits), sizeof(commit_t)); array_init(&(s->commits), sizeof(commit_t));
@ -3166,8 +3176,6 @@ static int enable_write_target(BlockDriverState *bs, Error **errp)
return 0; return 0;
err: err:
g_free(s->qcow_filename);
s->qcow_filename = NULL;
return ret; return ret;
} }

View File

@ -320,7 +320,6 @@ static void wctablet_chr_finalize(Object *obj)
TabletChardev *tablet = WCTABLET_CHARDEV(obj); TabletChardev *tablet = WCTABLET_CHARDEV(obj);
qemu_input_handler_unregister(tablet->hs); qemu_input_handler_unregister(tablet->hs);
g_free(tablet);
} }
static void wctablet_chr_open(Chardev *chr, static void wctablet_chr_open(Chardev *chr,

View File

@ -209,9 +209,9 @@ children.0=childs0 \
3. On Secondary VM's QEMU monitor, issue command 3. On Secondary VM's QEMU monitor, issue command
{'execute':'qmp_capabilities'} {"execute":"qmp_capabilities"}
{'execute': 'nbd-server-start', 'arguments': {'addr': {'type': 'inet', 'data': {'host': '0.0.0.0', 'port': '9999'} } } } {"execute": "nbd-server-start", "arguments": {"addr": {"type": "inet", "data": {"host": "0.0.0.0", "port": "9999"} } } }
{'execute': 'nbd-server-add', 'arguments': {'device': 'parent0', 'writable': true } } {"execute": "nbd-server-add", "arguments": {"device": "parent0", "writable": true } }
Note: Note:
a. The qmp command nbd-server-start and nbd-server-add must be run a. The qmp command nbd-server-start and nbd-server-add must be run
@ -222,11 +222,11 @@ Note:
will be merged into the parent disk on failover. will be merged into the parent disk on failover.
4. On Primary VM's QEMU monitor, issue command: 4. On Primary VM's QEMU monitor, issue command:
{'execute':'qmp_capabilities'} {"execute":"qmp_capabilities"}
{'execute': 'human-monitor-command', 'arguments': {'command-line': 'drive_add -n buddy driver=replication,mode=primary,file.driver=nbd,file.host=127.0.0.2,file.port=9999,file.export=parent0,node-name=replication0'}} {"execute": "human-monitor-command", "arguments": {"command-line": "drive_add -n buddy driver=replication,mode=primary,file.driver=nbd,file.host=127.0.0.2,file.port=9999,file.export=parent0,node-name=replication0"}}
{'execute': 'x-blockdev-change', 'arguments':{'parent': 'colo-disk0', 'node': 'replication0' } } {"execute": "x-blockdev-change", "arguments":{"parent": "colo-disk0", "node": "replication0" } }
{'execute': 'migrate-set-capabilities', 'arguments': {'capabilities': [ {'capability': 'x-colo', 'state': true } ] } } {"execute": "migrate-set-capabilities", "arguments": {"capabilities": [ {"capability": "x-colo", "state": true } ] } }
{'execute': 'migrate', 'arguments': {'uri': 'tcp:127.0.0.2:9998' } } {"execute": "migrate", "arguments": {"uri": "tcp:127.0.0.2:9998" } }
Note: Note:
a. There should be only one NBD Client for each primary disk. a. There should be only one NBD Client for each primary disk.
@ -249,59 +249,59 @@ if you want to resume the replication, follow "Secondary resume replication"
== Primary Failover == == Primary Failover ==
The Secondary died, resume on the Primary The Secondary died, resume on the Primary
{'execute': 'x-blockdev-change', 'arguments':{ 'parent': 'colo-disk0', 'child': 'children.1'} } {"execute": "x-blockdev-change", "arguments":{ "parent": "colo-disk0", "child": "children.1"} }
{'execute': 'human-monitor-command', 'arguments':{ 'command-line': 'drive_del replication0' } } {"execute": "human-monitor-command", "arguments":{ "command-line": "drive_del replication0" } }
{'execute': 'object-del', 'arguments':{ 'id': 'comp0' } } {"execute": "object-del", "arguments":{ "id": "comp0" } }
{'execute': 'object-del', 'arguments':{ 'id': 'iothread1' } } {"execute": "object-del", "arguments":{ "id": "iothread1" } }
{'execute': 'object-del', 'arguments':{ 'id': 'm0' } } {"execute": "object-del", "arguments":{ "id": "m0" } }
{'execute': 'object-del', 'arguments':{ 'id': 'redire0' } } {"execute": "object-del", "arguments":{ "id": "redire0" } }
{'execute': 'object-del', 'arguments':{ 'id': 'redire1' } } {"execute": "object-del", "arguments":{ "id": "redire1" } }
{'execute': 'x-colo-lost-heartbeat' } {"execute": "x-colo-lost-heartbeat" }
== Secondary Failover == == Secondary Failover ==
The Primary died, resume on the Secondary and prepare to become the new Primary The Primary died, resume on the Secondary and prepare to become the new Primary
{'execute': 'nbd-server-stop'} {"execute": "nbd-server-stop"}
{'execute': 'x-colo-lost-heartbeat'} {"execute": "x-colo-lost-heartbeat"}
{'execute': 'object-del', 'arguments':{ 'id': 'f2' } } {"execute": "object-del", "arguments":{ "id": "f2" } }
{'execute': 'object-del', 'arguments':{ 'id': 'f1' } } {"execute": "object-del", "arguments":{ "id": "f1" } }
{'execute': 'chardev-remove', 'arguments':{ 'id': 'red1' } } {"execute": "chardev-remove", "arguments":{ "id": "red1" } }
{'execute': 'chardev-remove', 'arguments':{ 'id': 'red0' } } {"execute": "chardev-remove", "arguments":{ "id": "red0" } }
{'execute': 'chardev-add', 'arguments':{ 'id': 'mirror0', 'backend': {'type': 'socket', 'data': {'addr': { 'type': 'inet', 'data': { 'host': '0.0.0.0', 'port': '9003' } }, 'server': true } } } } {"execute": "chardev-add", "arguments":{ "id": "mirror0", "backend": {"type": "socket", "data": {"addr": { "type": "inet", "data": { "host": "0.0.0.0", "port": "9003" } }, "server": true } } } }
{'execute': 'chardev-add', 'arguments':{ 'id': 'compare1', 'backend': {'type': 'socket', 'data': {'addr': { 'type': 'inet', 'data': { 'host': '0.0.0.0', 'port': '9004' } }, 'server': true } } } } {"execute": "chardev-add", "arguments":{ "id": "compare1", "backend": {"type": "socket", "data": {"addr": { "type": "inet", "data": { "host": "0.0.0.0", "port": "9004" } }, "server": true } } } }
{'execute': 'chardev-add', 'arguments':{ 'id': 'compare0', 'backend': {'type': 'socket', 'data': {'addr': { 'type': 'inet', 'data': { 'host': '127.0.0.1', 'port': '9001' } }, 'server': true } } } } {"execute": "chardev-add", "arguments":{ "id": "compare0", "backend": {"type": "socket", "data": {"addr": { "type": "inet", "data": { "host": "127.0.0.1", "port": "9001" } }, "server": true } } } }
{'execute': 'chardev-add', 'arguments':{ 'id': 'compare0-0', 'backend': {'type': 'socket', 'data': {'addr': { 'type': 'inet', 'data': { 'host': '127.0.0.1', 'port': '9001' } }, 'server': false } } } } {"execute": "chardev-add", "arguments":{ "id": "compare0-0", "backend": {"type": "socket", "data": {"addr": { "type": "inet", "data": { "host": "127.0.0.1", "port": "9001" } }, "server": false } } } }
{'execute': 'chardev-add', 'arguments':{ 'id': 'compare_out', 'backend': {'type': 'socket', 'data': {'addr': { 'type': 'inet', 'data': { 'host': '127.0.0.1', 'port': '9005' } }, 'server': true } } } } {"execute": "chardev-add", "arguments":{ "id": "compare_out", "backend": {"type": "socket", "data": {"addr": { "type": "inet", "data": { "host": "127.0.0.1", "port": "9005" } }, "server": true } } } }
{'execute': 'chardev-add', 'arguments':{ 'id': 'compare_out0', 'backend': {'type': 'socket', 'data': {'addr': { 'type': 'inet', 'data': { 'host': '127.0.0.1', 'port': '9005' } }, 'server': false } } } } {"execute": "chardev-add", "arguments":{ "id": "compare_out0", "backend": {"type": "socket", "data": {"addr": { "type": "inet", "data": { "host": "127.0.0.1", "port": "9005" } }, "server": false } } } }
== Primary resume replication == == Primary resume replication ==
Resume replication after new Secondary is up. Resume replication after new Secondary is up.
Start the new Secondary (Steps 2 and 3 above), then on the Primary: Start the new Secondary (Steps 2 and 3 above), then on the Primary:
{'execute': 'drive-mirror', 'arguments':{ 'device': 'colo-disk0', 'job-id': 'resync', 'target': 'nbd://127.0.0.2:9999/parent0', 'mode': 'existing', 'format': 'raw', 'sync': 'full'} } {"execute": "drive-mirror", "arguments":{ "device": "colo-disk0", "job-id": "resync", "target": "nbd://127.0.0.2:9999/parent0", "mode": "existing", "format": "raw", "sync": "full"} }
Wait until disk is synced, then: Wait until disk is synced, then:
{'execute': 'stop'} {"execute": "stop"}
{'execute': 'block-job-cancel', 'arguments':{ 'device': 'resync'} } {"execute": "block-job-cancel", "arguments":{ "device": "resync"} }
{'execute': 'human-monitor-command', 'arguments':{ 'command-line': 'drive_add -n buddy driver=replication,mode=primary,file.driver=nbd,file.host=127.0.0.2,file.port=9999,file.export=parent0,node-name=replication0'}} {"execute": "human-monitor-command", "arguments":{ "command-line": "drive_add -n buddy driver=replication,mode=primary,file.driver=nbd,file.host=127.0.0.2,file.port=9999,file.export=parent0,node-name=replication0"}}
{'execute': 'x-blockdev-change', 'arguments':{ 'parent': 'colo-disk0', 'node': 'replication0' } } {"execute": "x-blockdev-change", "arguments":{ "parent": "colo-disk0", "node": "replication0" } }
{'execute': 'object-add', 'arguments':{ 'qom-type': 'filter-mirror', 'id': 'm0', 'props': { 'netdev': 'hn0', 'queue': 'tx', 'outdev': 'mirror0' } } } {"execute": "object-add", "arguments":{ "qom-type": "filter-mirror", "id": "m0", "netdev": "hn0", "queue": "tx", "outdev": "mirror0" } }
{'execute': 'object-add', 'arguments':{ 'qom-type': 'filter-redirector', 'id': 'redire0', 'props': { 'netdev': 'hn0', 'queue': 'rx', 'indev': 'compare_out' } } } {"execute": "object-add", "arguments":{ "qom-type": "filter-redirector", "id": "redire0", "netdev": "hn0", "queue": "rx", "indev": "compare_out" } }
{'execute': 'object-add', 'arguments':{ 'qom-type': 'filter-redirector', 'id': 'redire1', 'props': { 'netdev': 'hn0', 'queue': 'rx', 'outdev': 'compare0' } } } {"execute": "object-add", "arguments":{ "qom-type": "filter-redirector", "id": "redire1", "netdev": "hn0", "queue": "rx", "outdev": "compare0" } }
{'execute': 'object-add', 'arguments':{ 'qom-type': 'iothread', 'id': 'iothread1' } } {"execute": "object-add", "arguments":{ "qom-type": "iothread", "id": "iothread1" } }
{'execute': 'object-add', 'arguments':{ 'qom-type': 'colo-compare', 'id': 'comp0', 'props': { 'primary_in': 'compare0-0', 'secondary_in': 'compare1', 'outdev': 'compare_out0', 'iothread': 'iothread1' } } } {"execute": "object-add", "arguments":{ "qom-type": "colo-compare", "id": "comp0", "primary_in": "compare0-0", "secondary_in": "compare1", "outdev": "compare_out0", "iothread": "iothread1" } }
{'execute': 'migrate-set-capabilities', 'arguments':{ 'capabilities': [ {'capability': 'x-colo', 'state': true } ] } } {"execute": "migrate-set-capabilities", "arguments":{ "capabilities": [ {"capability": "x-colo", "state": true } ] } }
{'execute': 'migrate', 'arguments':{ 'uri': 'tcp:127.0.0.2:9998' } } {"execute": "migrate", "arguments":{ "uri": "tcp:127.0.0.2:9998" } }
Note: Note:
If this Primary previously was a Secondary, then we need to insert the If this Primary previously was a Secondary, then we need to insert the
filters before the filter-rewriter by using the filters before the filter-rewriter by using the
"'insert': 'before', 'position': 'id=rew0'" Options. See below. ""insert": "before", "position": "id=rew0"" Options. See below.
== Secondary resume replication == == Secondary resume replication ==
Become Primary and resume replication after new Secondary is up. Note Become Primary and resume replication after new Secondary is up. Note
@ -309,23 +309,23 @@ that now 127.0.0.1 is the Secondary and 127.0.0.2 is the Primary.
Start the new Secondary (Steps 2 and 3 above, but with primary_ip=127.0.0.2), Start the new Secondary (Steps 2 and 3 above, but with primary_ip=127.0.0.2),
then on the old Secondary: then on the old Secondary:
{'execute': 'drive-mirror', 'arguments':{ 'device': 'colo-disk0', 'job-id': 'resync', 'target': 'nbd://127.0.0.1:9999/parent0', 'mode': 'existing', 'format': 'raw', 'sync': 'full'} } {"execute": "drive-mirror", "arguments":{ "device": "colo-disk0", "job-id": "resync", "target": "nbd://127.0.0.1:9999/parent0", "mode": "existing", "format": "raw", "sync": "full"} }
Wait until disk is synced, then: Wait until disk is synced, then:
{'execute': 'stop'} {"execute": "stop"}
{'execute': 'block-job-cancel', 'arguments':{ 'device': 'resync' } } {"execute": "block-job-cancel", "arguments":{ "device": "resync" } }
{'execute': 'human-monitor-command', 'arguments':{ 'command-line': 'drive_add -n buddy driver=replication,mode=primary,file.driver=nbd,file.host=127.0.0.1,file.port=9999,file.export=parent0,node-name=replication0'}} {"execute": "human-monitor-command", "arguments":{ "command-line": "drive_add -n buddy driver=replication,mode=primary,file.driver=nbd,file.host=127.0.0.1,file.port=9999,file.export=parent0,node-name=replication0"}}
{'execute': 'x-blockdev-change', 'arguments':{ 'parent': 'colo-disk0', 'node': 'replication0' } } {"execute": "x-blockdev-change", "arguments":{ "parent": "colo-disk0", "node": "replication0" } }
{'execute': 'object-add', 'arguments':{ 'qom-type': 'filter-mirror', 'id': 'm0', 'props': { 'insert': 'before', 'position': 'id=rew0', 'netdev': 'hn0', 'queue': 'tx', 'outdev': 'mirror0' } } } {"execute": "object-add", "arguments":{ "qom-type": "filter-mirror", "id": "m0", "insert": "before", "position": "id=rew0", "netdev": "hn0", "queue": "tx", "outdev": "mirror0" } }
{'execute': 'object-add', 'arguments':{ 'qom-type': 'filter-redirector', 'id': 'redire0', 'props': { 'insert': 'before', 'position': 'id=rew0', 'netdev': 'hn0', 'queue': 'rx', 'indev': 'compare_out' } } } {"execute": "object-add", "arguments":{ "qom-type": "filter-redirector", "id": "redire0", "insert": "before", "position": "id=rew0", "netdev": "hn0", "queue": "rx", "indev": "compare_out" } }
{'execute': 'object-add', 'arguments':{ 'qom-type': 'filter-redirector', 'id': 'redire1', 'props': { 'insert': 'before', 'position': 'id=rew0', 'netdev': 'hn0', 'queue': 'rx', 'outdev': 'compare0' } } } {"execute": "object-add", "arguments":{ "qom-type": "filter-redirector", "id": "redire1", "insert": "before", "position": "id=rew0", "netdev": "hn0", "queue": "rx", "outdev": "compare0" } }
{'execute': 'object-add', 'arguments':{ 'qom-type': 'iothread', 'id': 'iothread1' } } {"execute": "object-add", "arguments":{ "qom-type": "iothread", "id": "iothread1" } }
{'execute': 'object-add', 'arguments':{ 'qom-type': 'colo-compare', 'id': 'comp0', 'props': { 'primary_in': 'compare0-0', 'secondary_in': 'compare1', 'outdev': 'compare_out0', 'iothread': 'iothread1' } } } {"execute": "object-add", "arguments":{ "qom-type": "colo-compare", "id": "comp0", "primary_in": "compare0-0", "secondary_in": "compare1", "outdev": "compare_out0", "iothread": "iothread1" } }
{'execute': 'migrate-set-capabilities', 'arguments':{ 'capabilities': [ {'capability': 'x-colo', 'state': true } ] } } {"execute": "migrate-set-capabilities", "arguments":{ "capabilities": [ {"capability": "x-colo", "state": true } ] } }
{'execute': 'migrate', 'arguments':{ 'uri': 'tcp:127.0.0.1:9998' } } {"execute": "migrate", "arguments":{ "uri": "tcp:127.0.0.1:9998" } }
== TODO == == TODO ==
1. Support shared storage. 1. Support shared storage.

View File

@ -192,6 +192,12 @@ as short-form boolean values, and passed to plugins as ``arg_name=on``.
However, short-form booleans are deprecated and full explicit ``arg_name=on`` However, short-form booleans are deprecated and full explicit ``arg_name=on``
form is preferred. form is preferred.
``-drive if=none`` for the sifive_u OTP device (since 6.2)
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Using ``-drive if=none`` to configure the OTP device of the sifive_u
RISC-V machine is deprecated. Use ``-drive if=pflash`` instead.
QEMU Machine Protocol (QMP) commands QEMU Machine Protocol (QMP) commands
------------------------------------ ------------------------------------

View File

@ -658,8 +658,8 @@ enforce that any failure to open the backing image (including if the
backing file is missing or an incorrect format was specified) is an backing file is missing or an incorrect format was specified) is an
error when ``-u`` is not used. error when ``-u`` is not used.
qemu-img amend to adjust backing file (removed in 6.1) ``qemu-img amend`` to adjust backing file (removed in 6.1)
'''''''''''''''''''''''''''''''''''''''''''''''''''''' ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
The use of ``qemu-img amend`` to modify the name or format of a qcow2 The use of ``qemu-img amend`` to modify the name or format of a qcow2
backing image was never fully documented or tested, and interferes backing image was never fully documented or tested, and interferes
@ -670,8 +670,8 @@ backing chain should be performed with ``qemu-img rebase -u`` either
before or after the remaining changes being performed by amend, as before or after the remaining changes being performed by amend, as
appropriate. appropriate.
qemu-img backing file without format (removed in 6.1) ``qemu-img`` backing file without format (removed in 6.1)
''''''''''''''''''''''''''''''''''''''''''''''''''''' '''''''''''''''''''''''''''''''''''''''''''''''''''''''''
The use of ``qemu-img create``, ``qemu-img rebase``, or ``qemu-img The use of ``qemu-img create``, ``qemu-img rebase``, or ``qemu-img
convert`` to create or modify an image that depends on a backing file convert`` to create or modify an image that depends on a backing file

View File

@ -156,15 +156,15 @@ Primary:
children.0.driver=raw children.0.driver=raw
Run qmp command in primary qemu: Run qmp command in primary qemu:
{ 'execute': 'human-monitor-command', { "execute": "human-monitor-command",
'arguments': { "arguments": {
'command-line': 'drive_add -n buddy driver=replication,mode=primary,file.driver=nbd,file.host=xxxx,file.port=xxxx,file.export=colo1,node-name=nbd_client1' "command-line": "drive_add -n buddy driver=replication,mode=primary,file.driver=nbd,file.host=xxxx,file.port=xxxx,file.export=colo1,node-name=nbd_client1"
} }
} }
{ 'execute': 'x-blockdev-change', { "execute": "x-blockdev-change",
'arguments': { "arguments": {
'parent': 'colo1', "parent": "colo1",
'node': 'nbd_client1' "node": "nbd_client1"
} }
} }
Note: Note:
@ -189,21 +189,21 @@ Secondary:
vote-threshold=1,children.0=childs1 vote-threshold=1,children.0=childs1
Then run qmp command in secondary qemu: Then run qmp command in secondary qemu:
{ 'execute': 'nbd-server-start', { "execute": "nbd-server-start",
'arguments': { "arguments": {
'addr': { "addr": {
'type': 'inet', "type": "inet",
'data': { "data": {
'host': 'xxx', "host": "xxx",
'port': 'xxx' "port": "xxx"
} }
} }
} }
} }
{ 'execute': 'nbd-server-add', { "execute": "nbd-server-add",
'arguments': { "arguments": {
'device': 'colo1', "device": "colo1",
'writable': true "writable": true
} }
} }
@ -223,22 +223,22 @@ After Failover:
Primary: Primary:
The secondary host is down, so we should run the following qmp command The secondary host is down, so we should run the following qmp command
to remove the nbd child from the quorum: to remove the nbd child from the quorum:
{ 'execute': 'x-blockdev-change', { "execute": "x-blockdev-change",
'arguments': { "arguments": {
'parent': 'colo1', "parent": "colo1",
'child': 'children.1' "child": "children.1"
} }
} }
{ 'execute': 'human-monitor-command', { "execute": "human-monitor-command",
'arguments': { "arguments": {
'command-line': 'drive_del xxxx' "command-line": "drive_del xxxx"
} }
} }
Note: there is no qmp command to remove the blockdev now Note: there is no qmp command to remove the blockdev now
Secondary: Secondary:
The primary host is down, so we should do the following thing: The primary host is down, so we should do the following thing:
{ 'execute': 'nbd-server-stop' } { "execute": "nbd-server-stop" }
Promote Secondary to Primary: Promote Secondary to Primary:
see COLO-FT.txt see COLO-FT.txt

View File

@ -121,11 +121,11 @@ process for:
1) executables, which include: 1) executables, which include:
- Tools - qemu-img, qemu-nbd, qga (guest agent), etc - Tools - ``qemu-img``, ``qemu-nbd``, ``qga`` (guest agent), etc
- System emulators - qemu-system-$ARCH - System emulators - ``qemu-system-$ARCH``
- Userspace emulators - qemu-$ARCH - Userspace emulators - ``qemu-$ARCH``
- Unit tests - Unit tests

View File

@ -1,5 +1,5 @@
============ ============
Qemu modules QEMU modules
============ ============
.. kernel-doc:: include/qemu/module.h .. kernel-doc:: include/qemu/module.h

View File

@ -187,9 +187,9 @@ desired, in which the emulation application should only be allowed to
access the files or devices the VM it's running on behalf of can access. access the files or devices the VM it's running on behalf of can access.
#### qemu-io model #### qemu-io model
Qemu-io is a test harness used to test changes to the QEMU block backend ``qemu-io`` is a test harness used to test changes to the QEMU block backend
object code. (e.g., the code that implements disk images for disk driver object code (e.g., the code that implements disk images for disk driver
emulation) Qemu-io is not a device emulation application per se, but it emulation). ``qemu-io`` is not a device emulation application per se, but it
does compile the QEMU block objects into a separate binary from the main does compile the QEMU block objects into a separate binary from the main
QEMU one. This could be useful for disk device emulation, since its QEMU one. This could be useful for disk device emulation, since its
emulation applications will need to include the QEMU block objects. emulation applications will need to include the QEMU block objects.
@ -641,7 +641,7 @@ the CPU that issued the MMIO.
+==========+========================+ +==========+========================+
| rid | range MMIO is within | | rid | range MMIO is within |
+----------+------------------------+ +----------+------------------------+
| offset | offset withing *rid* | | offset | offset within *rid* |
+----------+------------------------+ +----------+------------------------+
| type | e.g., load or store | | type | e.g., load or store |
+----------+------------------------+ +----------+------------------------+

View File

@ -228,7 +228,7 @@ Emulated hardware state
Currently thanks to KVM work any access to IO memory is automatically Currently thanks to KVM work any access to IO memory is automatically
protected by the global iothread mutex, also known as the BQL (Big protected by the global iothread mutex, also known as the BQL (Big
Qemu Lock). Any IO region that doesn't use global mutex is expected to QEMU Lock). Any IO region that doesn't use global mutex is expected to
do its own locking. do its own locking.
However IO memory isn't the only way emulated hardware state can be However IO memory isn't the only way emulated hardware state can be

View File

@ -14,7 +14,7 @@ support that device.
Using only libqos APIs, the test has to manually take care of Using only libqos APIs, the test has to manually take care of
covering all the setups, and build the correct command line. covering all the setups, and build the correct command line.
This also introduces backward compability issues: if a device/driver command This also introduces backward compatibility issues: if a device/driver command
line name is changed, all tests that use that will not work line name is changed, all tests that use that will not work
properly anymore and need to be adjusted. properly anymore and need to be adjusted.

View File

@ -1,3 +1,5 @@
.. _stable-process:
QEMU and the stable process QEMU and the stable process
=========================== ===========================

View File

@ -1,3 +1,5 @@
.. _coding-style:
================= =================
QEMU Coding Style QEMU Coding Style
================= =================
@ -686,7 +688,7 @@ Rationale: hex numbers are hard to read in logs when there is no 0x prefix,
especially when (occasionally) the representation doesn't contain any letters especially when (occasionally) the representation doesn't contain any letters
and especially in one line with other decimal numbers. Number groups are allowed and especially in one line with other decimal numbers. Number groups are allowed
to not use '0x' because for some things notations like %x.%x.%x are used not to not use '0x' because for some things notations like %x.%x.%x are used not
only in Qemu. Also dumping raw data bytes with '0x' is less readable. only in QEMU. Also dumping raw data bytes with '0x' is less readable.
'#' printf flag '#' printf flag
--------------- ---------------

View File

@ -1,3 +1,5 @@
.. _submitting-a-patch:
Submitting a Patch Submitting a Patch
================== ==================
@ -20,11 +22,11 @@ one-shot fix, the bare minimum we ask is that:
should not be posted on the bug tracker, posted on forums, or should not be posted on the bug tracker, posted on forums, or
externally hosted and linked to. (We have other mailing lists too, externally hosted and linked to. (We have other mailing lists too,
but all patches must go to qemu-devel, possibly with a Cc: to another but all patches must go to qemu-devel, possibly with a Cc: to another
list.) ``git send-email`` works best for delivering the patch without list.) ``git send-email`` (`step-by-step setup
mangling it (`hints for setting it guide <https://git-send-email.io/>`__ and `hints and
up <http://lxr.free-electrons.com/source/Documentation/process/email-clients.rst>`__), tips <https://elixir.bootlin.com/linux/latest/source/Documentation/process/email-clients.rst>`__)
but attachments can be used as a last resort on a first-time works best for delivering the patch without mangling it, but
submission. attachments can be used as a last resort on a first-time submission.
- You must read replies to your message, and be willing to act on them. - You must read replies to your message, and be willing to act on them.
Note, however, that maintainers are often willing to manually fix up Note, however, that maintainers are often willing to manually fix up
first-time contributions, since there is a learning curve involved in first-time contributions, since there is a learning curve involved in
@ -45,6 +47,8 @@ Reading the table of contents below should already give you an idea of
the basic requirements. Use the table of contents as a reference, and the basic requirements. Use the table of contents as a reference, and
read the parts that you have doubts about. read the parts that you have doubts about.
.. contents:: Table of Contents
.. _writing_your_patches: .. _writing_your_patches:
Writing your Patches Writing your Patches
@ -60,11 +64,9 @@ check that you are in compliance with our coding standards. Be aware
that ``checkpatch.pl`` is not infallible, though, especially where C that ``checkpatch.pl`` is not infallible, though, especially where C
preprocessor macros are involved; use some common sense too. See also: preprocessor macros are involved; use some common sense too. See also:
- `QEMU Coding Style - :ref:`coding-style`
<https://qemu-project.gitlab.io/qemu/devel/style.html>`__
- `Automate a checkpatch run on - `Automate a checkpatch run on
commit <http://blog.vmsplice.net/2011/03/how-to-automatically-run-checkpatchpl.html>`__ commit <https://blog.vmsplice.net/2011/03/how-to-automatically-run-checkpatchpl.html>`__
.. _base_patches_against_current_git_master: .. _base_patches_against_current_git_master:
@ -76,6 +78,13 @@ of QEMU because development will have moved on from then and it probably
won't even apply to master. We only apply selected bugfixes to release won't even apply to master. We only apply selected bugfixes to release
branches and then only as backports once the code has gone into master. branches and then only as backports once the code has gone into master.
It is also okay to base patches on top of other on-going work that is
not yet part of the git master branch. To aid continuous integration
tools, such as `patchew <http://patchew.org/QEMU/>`__, you should `add a
tag <https://lists.gnu.org/archive/html/qemu-devel/2017-08/msg01288.html>`__
line ``Based-on: $MESSAGE_ID`` to your cover letter to make the series
dependency obvious.
.. _split_up_long_patches: .. _split_up_long_patches:
Split up long patches Split up long patches
@ -104,18 +113,17 @@ Make code motion patches easy to review
If a series requires large blocks of code motion, there are tricks for If a series requires large blocks of code motion, there are tricks for
making the refactoring easier to review. Split up the series so that making the refactoring easier to review. Split up the series so that
semantic changes (or even function renames) are done in a separate patch semantic changes (or even function renames) are done in a separate patch
from the raw code motion. Use a one-time setup of from the raw code motion. Use a one-time setup of ``git config
``git config diff.renames true; git config diff.algorithm patience`` diff.renames true;`` ``git config diff.algorithm patience`` (refer to
(Refer to `git-config <http://git-scm.com/docs/git-config>`__.) The `git-config <http://git-scm.com/docs/git-config>`__). The 'diff.renames'
``diff.renames`` property ensures file rename patches will be given in a property ensures file rename patches will be given in a more compact
more compact representation that focuses only on the differences across representation that focuses only on the differences across the file
the file rename, instead of showing the entire old file as a deletion rename, instead of showing the entire old file as a deletion and the new
and the new file as an insertion. Meanwhile, the 'diff.algorithm' file as an insertion. Meanwhile, the 'diff.algorithm' property ensures
property ensures that extracting a non-contiguous subset of one file that extracting a non-contiguous subset of one file into a new file, but
into a new file, but where all extracted parts occur in the same order where all extracted parts occur in the same order both before and after
both before and after the patch, will reduce churn in trying to treat the patch, will reduce churn in trying to treat unrelated ``}`` lines in
unrelated ``}`` lines in the original file as separating hunks of the original file as separating hunks of changes.
changes.
Ideally, a code motion patch can be reviewed by doing:: Ideally, a code motion patch can be reviewed by doing::
@ -138,8 +146,7 @@ as a separate patch which makes no semantic changes; don't put it in the
same patch as your bug fix. same patch as your bug fix.
For smaller patches in less frequently changed areas of QEMU, consider For smaller patches in less frequently changed areas of QEMU, consider
using the `trivial patches process using the :ref:`trivial-patches` process.
<https://qemu-project.gitlab.io/qemu/devel/style.html>`__.
.. _write_a_meaningful_commit_message: .. _write_a_meaningful_commit_message:
@ -154,7 +161,7 @@ QEMU follows the usual standard for git commit messages: the first line
(which becomes the email subject line) is "subsystem: single line (which becomes the email subject line) is "subsystem: single line
summary of change". Whether the "single line summary of change" starts summary of change". Whether the "single line summary of change" starts
with a capital is a matter of taste, but we prefer that the summary does with a capital is a matter of taste, but we prefer that the summary does
not end in ".". Look at ``git shortlog -30`` for an idea of sample not end in a dot. Look at ``git shortlog -30`` for an idea of sample
subject lines. Then there is a blank line and a more detailed subject lines. Then there is a blank line and a more detailed
description of the patch, another blank and your Signed-off-by: line. description of the patch, another blank and your Signed-off-by: line.
Please do not use lines that are longer than 76 characters in your Please do not use lines that are longer than 76 characters in your
@ -170,11 +177,79 @@ displays the subject line some distance apart (that is, a body that
starts with "... so that" as a continuation of the subject line is starts with "... so that" as a continuation of the subject line is
harder to follow). harder to follow).
If your patch fixes a commit that is already in the repository, please
add an additional line with "Fixes: <at-least-12-digits-of-SHA-commit-id>
("Fixed commit subject")" below the patch description / before your
"Signed-off-by:" line in the commit message.
If your patch fixes a bug in the gitlab bug tracker, please add a line
with "Resolves: <URL-of-the-bug>" to the commit message, too. Gitlab can
close bugs automatically once commits with the "Resolved:" keyword get
merged into the master branch of the project. And if your patch addresses
a bug in another public bug tracker, you can also use a line with
"Buglink: <URL-of-the-bug>" for reference here, too.
Example::
Fixes: 14055ce53c2d ("s390x/tcg: avoid overflows in time2tod/tod2time")
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/42
Buglink: https://bugs.launchpad.net/qemu/+bug/1804323``
Some other tags that are used in commit messages include "Message-Id:"
"Tested-by:", "Acked-by:", "Reported-by:", "Suggested-by:". See ``git
log`` for these keywords for example usage.
.. _test_your_patches:
Test your patches
~~~~~~~~~~~~~~~~~
Although QEMU has `continuous integration
services <Testing#Continuous_Integration>`__ that attempt to test
patches submitted to the list, it still saves everyone time if you have
already tested that your patch compiles and works. Because QEMU is such
a large project, it's okay to use configure arguments to limit what is
built for faster turnaround during your development time; but it is
still wise to also check that your patches work with a full build before
submitting a series, especially if your changes might have an unintended
effect on other areas of the code you don't normally experiment with.
See `Testing <Testing>`__ for more details on what tests are available.
Also, it is a wise idea to include a testsuite addition as part of your
patches - either to ensure that future changes won't regress your new
feature, or to add a test which exposes the bug that the rest of your
series fixes. Keeping separate commits for the test and the fix allows
reviewers to rebase the test to occur first to prove it catches the
problem, then again to place it last in the series so that bisection
doesn't land on a known-broken state.
.. _submitting_your_patches: .. _submitting_your_patches:
Submitting your Patches Submitting your Patches
----------------------- -----------------------
.. _if_you_cannot_send_patch_emails:
If you cannot send patch emails
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In rare cases it may not be possible to send properly formatted patch
emails. You can use `sourcehut <https://sourcehut.org/>`__ to send your
patches to the QEMU mailing list by following these steps:
#. Register or sign in to your account
#. Add your SSH public key in `meta \|
keys <https://meta.sr.ht/keys>`__.
#. Publish your git branch using **git push git@git.sr.ht:~USERNAME/qemu
HEAD**
#. Send your patches to the QEMU mailing list using the web-based
``git-send-email`` UI at https://git.sr.ht/~USERNAME/qemu/send-email
`This video
<https://spacepub.space/videos/watch/ad258d23-0ac6-488c-83fc-2bacf578de3a>`__
shows the web-based ``git-send-email`` workflow. Documentation is
available `here
<https://man.sr.ht/git.sr.ht/#sending-patches-upstream>`__.
.. _cc_the_relevant_maintainer: .. _cc_the_relevant_maintainer:
CC the relevant maintainer CC the relevant maintainer
@ -219,17 +294,26 @@ such as 'git-email' on Fedora-based systems.) Patch series need a cover
letter, with shallow threading (all patches in the series are letter, with shallow threading (all patches in the series are
in-reply-to the cover letter, but not to each other); single unrelated in-reply-to the cover letter, but not to each other); single unrelated
patches do not need a cover letter (but if you do send a cover letter, patches do not need a cover letter (but if you do send a cover letter,
use --numbered so the cover and the patch have distinct subject lines). use ``--numbered`` so the cover and the patch have distinct subject lines).
Patches are easier to find if they start a new top-level thread, rather Patches are easier to find if they start a new top-level thread, rather
than being buried in-reply-to another existing thread. than being buried in-reply-to another existing thread.
.. _avoid_posting_large_binary_blob:
Avoid posting large binary blob
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If you added binaries to the repository, consider producing the patch
emails using ``git format-patch --no-binary`` and include a link to a
git repository to fetch the original commit.
.. _patch_emails_must_include_a_signed_off_by_line: .. _patch_emails_must_include_a_signed_off_by_line:
Patch emails must include a ``Signed-off-by:`` line Patch emails must include a ``Signed-off-by:`` line
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
For more information see `1.12) Sign your work For more information see `SubmittingPatches 1.12
<http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/SubmittingPatches?id=f6f94e2ab1b33f0082ac22d71f66385a60d8157f#n296>`__. <http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/SubmittingPatches?id=f6f94e2ab1b33f0082ac22d71f66385a60d8157f#n297>`__.
This is vital or we will not be able to apply your patch! Please use This is vital or we will not be able to apply your patch! Please use
your real name to sign a patch (not an alias or acronym). your real name to sign a patch (not an alias or acronym).
@ -246,8 +330,13 @@ that author's Signed-off-by: line is mandatory, with the same spelling.
Include a meaningful cover letter Include a meaningful cover letter
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This usually applies only to a series that includes multiple patches; This is a requirement for any series with multiple patches (as it aids
the cover letter explains the overall goal of such a series. continuous integration), but optional for an isolated patch. The cover
letter explains the overall goal of such a series, and also provides a
convenient 0/N email for others to reply to the series as a whole. A
one-time setup of ``git config format.coverletter auto`` (refer to
`git-config <http://git-scm.com/docs/git-config>`__) will generate the
cover letter as needed.
When reviewers don't know your goal at the start of their review, they When reviewers don't know your goal at the start of their review, they
may object to early changes that don't make sense until the end of the may object to early changes that don't make sense until the end of the
@ -288,6 +377,18 @@ it's best to:
of the patchset you're looking for review on, and why reviewers of the patchset you're looking for review on, and why reviewers
should care should care
.. _consider_whether_your_patch_is_applicable_for_stable:
Consider whether your patch is applicable for stable
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If your patch fixes a severe issue or a regression, it may be applicable
for stable. In that case, consider adding ``Cc: qemu-stable@nongnu.org``
to your patch to notify the stable maintainers.
For more details on how QEMU's stable process works, refer to the
:ref:`stable-process` page.
.. _participating_in_code_review: .. _participating_in_code_review:
Participating in Code Review Participating in Code Review
@ -367,19 +468,19 @@ Include version history in patchset revisions
For later versions of patches, include a summary of changes from For later versions of patches, include a summary of changes from
previous versions, but not in the commit message itself. In an email previous versions, but not in the commit message itself. In an email
formatted as a git patch, the commit message is the part above the "---" formatted as a git patch, the commit message is the part above the ``---``
line, and this will go into the git changelog when the patch is line, and this will go into the git changelog when the patch is
committed. This part should be a self-contained description of what this committed. This part should be a self-contained description of what this
version of the patch does, written to make sense to anybody who comes version of the patch does, written to make sense to anybody who comes
back to look at this commit in git in six months' time. The part below back to look at this commit in git in six months' time. The part below
the "---" line and above the patch proper (git format-patch puts the the ``---`` line and above the patch proper (git format-patch puts the
diffstat here) is a good place to put remarks for people reading the diffstat here) is a good place to put remarks for people reading the
patch email, and this is where the "changes since previous version" patch email, and this is where the "changes since previous version"
summary belongs. The summary belongs. The `git-publish
`git-publish <https://github.com/stefanha/git-publish>`__ script can <https://github.com/stefanha/git-publish>`__ script can help with
help with tracking a good summary across versions. Also, the tracking a good summary across versions. Also, the `git-backport-diff
`git-backport-diff <https://github.com/codyprime/git-scripts>`__ script <https://github.com/codyprime/git-scripts>`__ script can help focus
can help focus reviewers on what changed between revisions. reviewers on what changed between revisions.
.. _tips_and_tricks: .. _tips_and_tricks:
@ -411,27 +512,32 @@ If your patch seems to have been ignored
If your patchset has received no replies you should "ping" it after a If your patchset has received no replies you should "ping" it after a
week or two, by sending an email as a reply-to-all to the patch mail, week or two, by sending an email as a reply-to-all to the patch mail,
including the word "ping" and ideally also a link to the page for the including the word "ping" and ideally also a link to the page for the
patch on patch on `patchew <https://patchew.org/QEMU/>`__ or
`patchwork <http://patchwork.ozlabs.org/project/qemu-devel/list/>`__ or `lore.kernel.org <https://lore.kernel.org/qemu-devel/>`__. It's worth
GMANE. It's worth double-checking for reasons why your patch might have double-checking for reasons why your patch might have been ignored
been ignored (forgot to CC the maintainer? annoyed people by failing to (forgot to CC the maintainer? annoyed people by failing to respond to
respond to review comments on an earlier version?), but often for review comments on an earlier version?), but often for less-maintained
less-maintained areas of QEMU patches do just slip through the cracks. areas of QEMU patches do just slip through the cracks. If your ping is
If your ping is also ignored, ping again after another week or so. As also ignored, ping again after another week or so. As the submitter, you
the submitter, you are the person with the most motivation to get your are the person with the most motivation to get your patch applied, so
patch applied, so you have to be persistent. you have to be persistent.
.. _is_my_patch_in: .. _is_my_patch_in:
Is my patch in? Is my patch in?
~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~
QEMU has some Continuous Integration machines that try to catch patch
submission problems as soon as possible. `patchew
<http://patchew.org/QEMU/>`__ includes a web interface for tracking the
status of various threads that have been posted to the list, and may
send you an automated mail if it detected a problem with your patch.
Once your patch has had enough review on list, the maintainer for that Once your patch has had enough review on list, the maintainer for that
area of code will send notification to the list that they are including area of code will send notification to the list that they are including
your patch in a particular staging branch. Periodically, the maintainer your patch in a particular staging branch. Periodically, the maintainer
then sends a `pull request then takes care of :ref:`submitting-a-pull-request`
<https://qemu-project.gitlab.io/qemu/devel/submitting-a-pull-request.html>`__ for aggregating topic branches into mainline QEMU. Generally, you do not
for aggregating topic branches into mainline qemu. Generally, you do not
need to send a pull request unless you have contributed enough patches need to send a pull request unless you have contributed enough patches
to become a maintainer over a particular section of code. Maintainers to become a maintainer over a particular section of code. Maintainers
may further modify your commit, by resolving simple merge conflicts or may further modify your commit, by resolving simple merge conflicts or

View File

@ -1,10 +1,11 @@
Submit a Pull Request .. _submitting-a-pull-request:
=====================
Submitting a Pull Request
=========================
QEMU welcomes contributions of code, but we generally expect these to be QEMU welcomes contributions of code, but we generally expect these to be
sent as simple patch emails to the mailing list (see our page on sent as simple patch emails to the mailing list (see our page on
`submitting a patch :ref:`submitting-a-patch`
<https://qemu-project.gitlab.io/qemu/devel/submitting-a-patch.html>`__
for more details). Generally only existing submaintainers of a tree for more details). Generally only existing submaintainers of a tree
will need to submit pull requests, although occasionally for a large will need to submit pull requests, although occasionally for a large
patch series we might ask a submitter to send a pull request. This page patch series we might ask a submitter to send a pull request. This page

View File

@ -564,11 +564,11 @@ exploiting a QEMU security bug to compromise the host.
QEMU binaries QEMU binaries
~~~~~~~~~~~~~ ~~~~~~~~~~~~~
By default, qemu-system-x86_64 is searched in $PATH to run the guest. If there By default, ``qemu-system-x86_64`` is searched in $PATH to run the guest. If
isn't one, or if it is older than 2.10, the test won't work. In this case, there isn't one, or if it is older than 2.10, the test won't work. In this case,
provide the QEMU binary in env var: ``QEMU=/path/to/qemu-2.10+``. provide the QEMU binary in env var: ``QEMU=/path/to/qemu-2.10+``.
Likewise the path to qemu-img can be set in QEMU_IMG environment variable. Likewise the path to ``qemu-img`` can be set in QEMU_IMG environment variable.
Make jobs Make jobs
~~~~~~~~~ ~~~~~~~~~
@ -650,7 +650,7 @@ supported. To start the fuzzer, run
tests/image-fuzzer/runner.py -c '[["qemu-img", "info", "$test_img"]]' /tmp/test qcow2 tests/image-fuzzer/runner.py -c '[["qemu-img", "info", "$test_img"]]' /tmp/test qcow2
Alternatively, some command different from "qemu-img info" can be tested, by Alternatively, some command different from ``qemu-img info`` can be tested, by
changing the ``-c`` option. changing the ``-c`` option.
Integration tests using the Avocado Framework Integration tests using the Avocado Framework

View File

@ -1,3 +1,5 @@
.. _trivial-patches:
Trivial Patches Trivial Patches
=============== ===============

View File

@ -1,8 +1,8 @@
================= =================
Qemu UI subsystem QEMU UI subsystem
================= =================
Qemu Clipboard QEMU Clipboard
-------------- --------------
.. kernel-doc:: include/ui/clipboard.h .. kernel-doc:: include/ui/clipboard.h

View File

@ -677,7 +677,7 @@ return a single text string::
The ``HumanReadableText`` struct is intended to be used for all The ``HumanReadableText`` struct is intended to be used for all
commands, under the ``x-`` name prefix that are returning unstructured commands, under the ``x-`` name prefix that are returning unstructured
text targetted at humans. It should never be used for commands outside text targeted at humans. It should never be used for commands outside
the ``x-`` name prefix, as those should be using structured QAPI types. the ``x-`` name prefix, as those should be using structured QAPI types.
Implementing the QMP command Implementing the QMP command

View File

@ -195,7 +195,7 @@ The enlightenment allows to use Hyper-V SynIC with hardware APICv/AVIC enabled.
Normally, Hyper-V SynIC disables these hardware feature and suggests the guest Normally, Hyper-V SynIC disables these hardware feature and suggests the guest
to use paravirtualized AutoEOI feature. to use paravirtualized AutoEOI feature.
Note: enabling this feature on old hardware (without APICv/AVIC support) may Note: enabling this feature on old hardware (without APICv/AVIC support) may
have negative effect on guest's performace. have negative effect on guest's performance.
3.19. hv-no-nonarch-coresharing=on/off/auto 3.19. hv-no-nonarch-coresharing=on/off/auto
=========================================== ===========================================

View File

@ -51,10 +51,10 @@ assumes that core dumps will be generated in the current working directory.
For comprehensive test results, please, set up your test environment For comprehensive test results, please, set up your test environment
properly. properly.
Paths to binaries under test (SUTs) qemu-img and qemu-io are retrieved from Paths to binaries under test (SUTs) ``qemu-img`` and ``qemu-io`` are retrieved
environment variables. If the environment check fails the runner will from environment variables. If the environment check fails the runner will
use SUTs installed in system paths. use SUTs installed in system paths.
qemu-img is required for creation of backing files, so it's mandatory to set ``qemu-img`` is required for creation of backing files, so it's mandatory to set
the related environment variable if it's not installed in the system path. the related environment variable if it's not installed in the system path.
For details about environment variables see qemu-iotests/check. For details about environment variables see qemu-iotests/check.

View File

@ -1,4 +1,4 @@
Qemu supports the NBD protocol, and has an internal NBD client (see QEMU supports the NBD protocol, and has an internal NBD client (see
block/nbd.c), an internal NBD server (see blockdev-nbd.c), and an block/nbd.c), an internal NBD server (see blockdev-nbd.c), and an
external NBD server tool (see qemu-nbd.c). The common code is placed external NBD server tool (see qemu-nbd.c). The common code is placed
in nbd/*. in nbd/*.
@ -7,11 +7,11 @@ The NBD protocol is specified here:
https://github.com/NetworkBlockDevice/nbd/blob/master/doc/proto.md https://github.com/NetworkBlockDevice/nbd/blob/master/doc/proto.md
The following paragraphs describe some specific properties of NBD The following paragraphs describe some specific properties of NBD
protocol realization in Qemu. protocol realization in QEMU.
= Metadata namespaces = = Metadata namespaces =
Qemu supports the "base:allocation" metadata context as defined in the QEMU supports the "base:allocation" metadata context as defined in the
NBD protocol specification, and also defines an additional metadata NBD protocol specification, and also defines an additional metadata
namespace "qemu". namespace "qemu".

View File

@ -313,7 +313,7 @@ The fields of the bitmaps extension are:
The number of bitmaps contained in the image. Must be The number of bitmaps contained in the image. Must be
greater than or equal to 1. greater than or equal to 1.
Note: Qemu currently only supports up to 65535 bitmaps per Note: QEMU currently only supports up to 65535 bitmaps per
image. image.
4 - 7: Reserved, must be zero. 4 - 7: Reserved, must be zero.
@ -775,7 +775,7 @@ Structure of a bitmap directory entry:
2: extra_data_compatible 2: extra_data_compatible
This flags is meaningful when the extra data is This flags is meaningful when the extra data is
unknown to the software (currently any extra data is unknown to the software (currently any extra data is
unknown to Qemu). unknown to QEMU).
If it is set, the bitmap may be used as expected, extra If it is set, the bitmap may be used as expected, extra
data must be left as is. data must be left as is.
If it is not set, the bitmap must not be used, but If it is not set, the bitmap must not be used, but
@ -793,7 +793,7 @@ Structure of a bitmap directory entry:
17: granularity_bits 17: granularity_bits
Granularity bits. Valid values: 0 - 63. Granularity bits. Valid values: 0 - 63.
Note: Qemu currently supports only values 9 - 31. Note: QEMU currently supports only values 9 - 31.
Granularity is calculated as Granularity is calculated as
granularity = 1 << granularity_bits granularity = 1 << granularity_bits
@ -804,7 +804,7 @@ Structure of a bitmap directory entry:
18 - 19: name_size 18 - 19: name_size
Size of the bitmap name. Must be non-zero. Size of the bitmap name. Must be non-zero.
Note: Qemu currently doesn't support values greater than Note: QEMU currently doesn't support values greater than
1023. 1023.
20 - 23: extra_data_size 20 - 23: extra_data_size

View File

@ -123,7 +123,7 @@ Background info is here:
guest side with pci-bridge-seat guest side with pci-bridge-seat
------------------------------- -------------------------------
Qemu version 2.4 and newer has a new pci-bridge-seat device which QEMU version 2.4 and newer has a new pci-bridge-seat device which
can be used instead of pci-bridge. Just swap the device name in the can be used instead of pci-bridge. Just swap the device name in the
qemu command line above. The only difference between the two devices qemu command line above. The only difference between the two devices
is the pci id. We can match the pci id instead of the device path is the pci id. We can match the pci id instead of the device path

View File

@ -128,7 +128,7 @@ Alternatively, you can also choose to build you own image with buildroot
using the orangepi_pc_defconfig. Also see https://buildroot.org for more information. using the orangepi_pc_defconfig. Also see https://buildroot.org for more information.
When using an image as an SD card, it must be resized to a power of two. This can be When using an image as an SD card, it must be resized to a power of two. This can be
done with the qemu-img command. It is recommended to only increase the image size done with the ``qemu-img`` command. It is recommended to only increase the image size
instead of shrinking it to a power of two, to avoid loss of data. For example, instead of shrinking it to a power of two, to avoid loss of data. For example,
to prepare a downloaded Armbian image, first extract it and then increase to prepare a downloaded Armbian image, first extract it and then increase
its size to one gigabyte as follows: its size to one gigabyte as follows:

View File

@ -77,11 +77,9 @@ To create an instance of this driver via QMP:
"arguments": { "arguments": {
"qom-type": "authz-simple", "qom-type": "authz-simple",
"id": "authz0", "id": "authz0",
"props": {
"identity": "fred" "identity": "fred"
} }
} }
}
Or via the command line Or via the command line
@ -110,7 +108,6 @@ To create an instance of this class via QMP:
"arguments": { "arguments": {
"qom-type": "authz-list", "qom-type": "authz-list",
"id": "authz0", "id": "authz0",
"props": {
"rules": [ "rules": [
{ "match": "fred", "policy": "allow", "format": "exact" }, { "match": "fred", "policy": "allow", "format": "exact" },
{ "match": "bob", "policy": "allow", "format": "exact" }, { "match": "bob", "policy": "allow", "format": "exact" },
@ -120,7 +117,6 @@ To create an instance of this class via QMP:
"policy": "deny" "policy": "deny"
} }
} }
}
Due to the way this driver requires setting nested properties, creating Due to the way this driver requires setting nested properties, creating
@ -143,12 +139,10 @@ To create an instance of this class via QMP:
"arguments": { "arguments": {
"qom-type": "authz-list-file", "qom-type": "authz-list-file",
"id": "authz0", "id": "authz0",
"props": {
"filename": "/etc/qemu/myvm-vnc.acl", "filename": "/etc/qemu/myvm-vnc.acl",
"refresh": true "refresh": true
} }
} }
}
If ``refresh`` is ``yes``, inotify is used to monitor for changes If ``refresh`` is ``yes``, inotify is used to monitor for changes

View File

@ -49,7 +49,7 @@ future OS and toolchains are likely to target newer ABIs. The
table that follows illustrates which ABI compatibility levels table that follows illustrates which ABI compatibility levels
can be satisfied by the QEMU CPU models. Note that the table only can be satisfied by the QEMU CPU models. Note that the table only
lists the long term stable CPU model versions (eg Haswell-v4). lists the long term stable CPU model versions (eg Haswell-v4).
In addition to whats listed, there are also many CPU model In addition to what is listed, there are also many CPU model
aliases which resolve to a different CPU model version, aliases which resolve to a different CPU model version,
depending on the machine type is in use. depending on the machine type is in use.

View File

@ -15,7 +15,7 @@ These are specified using a special URL syntax.
'iqn.2008-11.org.linux-kvm[:<name>]' but this can also be set from 'iqn.2008-11.org.linux-kvm[:<name>]' but this can also be set from
the command line or a configuration file. the command line or a configuration file.
Since version Qemu 2.4 it is possible to specify a iSCSI request Since version QEMU 2.4 it is possible to specify a iSCSI request
timeout to detect stalled requests and force a reestablishment of the timeout to detect stalled requests and force a reestablishment of the
session. The timeout is specified in seconds. The default is 0 which session. The timeout is specified in seconds. The default is 0 which
means no timeout. Libiscsi 1.15.0 or greater is required for this means no timeout. Libiscsi 1.15.0 or greater is required for this

View File

@ -70,7 +70,7 @@ namespaces and additional features, the ``nvme-ns`` device must be used.
The namespaces defined by the ``nvme-ns`` device will attach to the most The namespaces defined by the ``nvme-ns`` device will attach to the most
recently defined ``nvme-bus`` that is created by the ``nvme`` device. Namespace recently defined ``nvme-bus`` that is created by the ``nvme`` device. Namespace
identifers are allocated automatically, starting from ``1``. identifiers are allocated automatically, starting from ``1``.
There are a number of parameters available: There are a number of parameters available:

View File

@ -56,7 +56,7 @@ machine has more than one CPU, QEMU exposes each CPU cluster as a
separate "inferior", where each CPU within the cluster is a separate separate "inferior", where each CPU within the cluster is a separate
"thread". Most QEMU machine types have identical CPUs, so there is a "thread". Most QEMU machine types have identical CPUs, so there is a
single cluster which has all the CPUs in it. A few machine types are single cluster which has all the CPUs in it. A few machine types are
heterogenous and have multiple clusters: for example the ``sifive_u`` heterogeneous and have multiple clusters: for example the ``sifive_u``
machine has a cluster with one E51 core and a second cluster with four machine has a cluster with one E51 core and a second cluster with four
U54 cores. Here the E51 is the only thread in the first inferior, and U54 cores. Here the E51 is the only thread in the first inferior, and
the U54 cores are all threads in the second inferior. the U54 cores are all threads in the second inferior.

View File

@ -20,13 +20,13 @@ report the same CPUID info to guest as on host for most of SGX CPUID. With
reporting the same CPUID guest is able to use full capacity of SGX, and KVM reporting the same CPUID guest is able to use full capacity of SGX, and KVM
doesn't need to emulate those info. doesn't need to emulate those info.
The guest's EPC base and size are determined by Qemu, and KVM needs Qemu to The guest's EPC base and size are determined by QEMU, and KVM needs QEMU to
notify such info to it before it can initialize SGX for guest. notify such info to it before it can initialize SGX for guest.
Virtual EPC Virtual EPC
~~~~~~~~~~~ ~~~~~~~~~~~
By default, Qemu does not assign EPC to a VM, i.e. fully enabling SGX in a VM By default, QEMU does not assign EPC to a VM, i.e. fully enabling SGX in a VM
requires explicit allocation of EPC to the VM. Similar to other specialized requires explicit allocation of EPC to the VM. Similar to other specialized
memory types, e.g. hugetlbfs, EPC is exposed as a memory backend. memory types, e.g. hugetlbfs, EPC is exposed as a memory backend.
@ -35,12 +35,12 @@ prior to realizing the vCPUs themselves, which occurs long before generic
devices are parsed and realized. This limitation means that EPC does not devices are parsed and realized. This limitation means that EPC does not
require -maxmem as EPC is not treated as {cold,hot}plugged memory. require -maxmem as EPC is not treated as {cold,hot}plugged memory.
Qemu does not artificially restrict the number of EPC sections exposed to a QEMU does not artificially restrict the number of EPC sections exposed to a
guest, e.g. Qemu will happily allow you to create 64 1M EPC sections. Be aware guest, e.g. QEMU will happily allow you to create 64 1M EPC sections. Be aware
that some kernels may not recognize all EPC sections, e.g. the Linux SGX driver that some kernels may not recognize all EPC sections, e.g. the Linux SGX driver
is hardwired to support only 8 EPC sections. is hardwired to support only 8 EPC sections.
The following Qemu snippet creates two EPC sections, with 64M pre-allocated The following QEMU snippet creates two EPC sections, with 64M pre-allocated
to the VM and an additional 28M mapped but not allocated:: to the VM and an additional 28M mapped but not allocated::
-object memory-backend-epc,id=mem1,size=64M,prealloc=on \ -object memory-backend-epc,id=mem1,size=64M,prealloc=on \
@ -54,7 +54,7 @@ to physical EPC. Because physical EPC is protected via range registers,
the size of the physical EPC must be a power of two (though software sees the size of the physical EPC must be a power of two (though software sees
a subset of the full EPC, e.g. 92M or 128M) and the EPC must be naturally a subset of the full EPC, e.g. 92M or 128M) and the EPC must be naturally
aligned. KVM SGX's virtual EPC is purely a software construct and only aligned. KVM SGX's virtual EPC is purely a software construct and only
requires the size and location to be page aligned. Qemu enforces the EPC requires the size and location to be page aligned. QEMU enforces the EPC
size is a multiple of 4k and will ensure the base of the EPC is 4k aligned. size is a multiple of 4k and will ensure the base of the EPC is 4k aligned.
To simplify the implementation, EPC is always located above 4g in the guest To simplify the implementation, EPC is always located above 4g in the guest
physical address space. physical address space.
@ -62,7 +62,7 @@ physical address space.
Migration Migration
~~~~~~~~~ ~~~~~~~~~
Qemu/KVM doesn't prevent live migrating SGX VMs, although from hardware's QEMU/KVM doesn't prevent live migrating SGX VMs, although from hardware's
perspective, SGX doesn't support live migration, since both EPC and the SGX perspective, SGX doesn't support live migration, since both EPC and the SGX
key hierarchy are bound to the physical platform. However live migration key hierarchy are bound to the physical platform. However live migration
can be supported in the sense if guest software stack can support recreating can be supported in the sense if guest software stack can support recreating
@ -76,7 +76,7 @@ CPUID
~~~~~ ~~~~~
Due to its myriad dependencies, SGX is currently not listed as supported Due to its myriad dependencies, SGX is currently not listed as supported
in any of Qemu's built-in CPU configuration. To expose SGX (and SGX Launch in any of QEMU's built-in CPU configuration. To expose SGX (and SGX Launch
Control) to a guest, you must either use ``-cpu host`` to pass-through the Control) to a guest, you must either use ``-cpu host`` to pass-through the
host CPU model, or explicitly enable SGX when using a built-in CPU model, host CPU model, or explicitly enable SGX when using a built-in CPU model,
e.g. via ``-cpu <model>,+sgx`` or ``-cpu <model>,+sgx,+sgxlc``. e.g. via ``-cpu <model>,+sgx`` or ``-cpu <model>,+sgx,+sgxlc``.
@ -101,7 +101,7 @@ controlled via -cpu are prefixed with "sgx", e.g.::
sgx2 sgx2
sgxlc sgxlc
The following Qemu snippet passes through the host CPU but restricts access to The following QEMU snippet passes through the host CPU but restricts access to
the provision and EINIT token keys:: the provision and EINIT token keys::
-cpu host,-sgx-provisionkey,-sgx-tokenkey -cpu host,-sgx-provisionkey,-sgx-tokenkey
@ -112,11 +112,11 @@ in hardware cannot be forced on via '-cpu'.
Virtualize SGX Launch Control Virtualize SGX Launch Control
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Qemu SGX support for Launch Control (LC) is passive, in the sense that it QEMU SGX support for Launch Control (LC) is passive, in the sense that it
does not actively change the LC configuration. Qemu SGX provides the user does not actively change the LC configuration. QEMU SGX provides the user
the ability to set/clear the CPUID flag (and by extension the associated the ability to set/clear the CPUID flag (and by extension the associated
IA32_FEATURE_CONTROL MSR bit in fw_cfg) and saves/restores the LE Hash MSRs IA32_FEATURE_CONTROL MSR bit in fw_cfg) and saves/restores the LE Hash MSRs
when getting/putting guest state, but Qemu does not add new controls to when getting/putting guest state, but QEMU does not add new controls to
directly modify the LC configuration. Similar to hardware behavior, locking directly modify the LC configuration. Similar to hardware behavior, locking
the LC configuration to a non-Intel value is left to guest firmware. Unlike the LC configuration to a non-Intel value is left to guest firmware. Unlike
host bios setting for SGX launch control(LC), there is no special bios setting host bios setting for SGX launch control(LC), there is no special bios setting
@ -126,7 +126,7 @@ creating VM with SGX.
Feature Control Feature Control
~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~
Qemu SGX updates the ``etc/msr_feature_control`` fw_cfg entry to set the SGX QEMU SGX updates the ``etc/msr_feature_control`` fw_cfg entry to set the SGX
(bit 18) and SGX LC (bit 17) flags based on their respective CPUID support, (bit 18) and SGX LC (bit 17) flags based on their respective CPUID support,
i.e. existing guest firmware will automatically set SGX and SGX LC accordingly, i.e. existing guest firmware will automatically set SGX and SGX LC accordingly,
assuming said firmware supports fw_cfg.msr_feature_control. assuming said firmware supports fw_cfg.msr_feature_control.

View File

@ -20,7 +20,7 @@ where myimage.img is the disk image filename and mysize is its size in
kilobytes. You can add an ``M`` suffix to give the size in megabytes and kilobytes. You can add an ``M`` suffix to give the size in megabytes and
a ``G`` suffix for gigabytes. a ``G`` suffix for gigabytes.
See the qemu-img invocation documentation for more information. See the ``qemu-img`` invocation documentation for more information.
.. _disk_005fimages_005fsnapshot_005fmode: .. _disk_005fimages_005fsnapshot_005fmode:

View File

@ -75,7 +75,7 @@ as the BIOS. QEMU follows below truth table to select which payload to execute:
When both -bios and -kernel are present, QEMU loads U-Boot and U-Boot in turns When both -bios and -kernel are present, QEMU loads U-Boot and U-Boot in turns
automatically loads the kernel image specified by the -kernel parameter via automatically loads the kernel image specified by the -kernel parameter via
U-Boot's built-in "bootm" command, hence a legacy uImage format is required in U-Boot's built-in "bootm" command, hence a legacy uImage format is required in
such senario. such scenario.
Running Linux kernel Running Linux kernel
-------------------- --------------------

View File

@ -511,13 +511,13 @@ of an inet socket:
|qemu_system| linux.img -hdb nbd+unix://?socket=/tmp/my_socket |qemu_system| linux.img -hdb nbd+unix://?socket=/tmp/my_socket
In this case, the block device must be exported using qemu-nbd: In this case, the block device must be exported using ``qemu-nbd``:
.. parsed-literal:: .. parsed-literal::
qemu-nbd --socket=/tmp/my_socket my_disk.qcow2 qemu-nbd --socket=/tmp/my_socket my_disk.qcow2
The use of qemu-nbd allows sharing of a disk between several guests: The use of ``qemu-nbd`` allows sharing of a disk between several guests:
.. parsed-literal:: .. parsed-literal::
@ -530,7 +530,7 @@ and then you can use it with two guests:
|qemu_system| linux1.img -hdb nbd+unix://?socket=/tmp/my_socket |qemu_system| linux1.img -hdb nbd+unix://?socket=/tmp/my_socket
|qemu_system| linux2.img -hdb nbd+unix://?socket=/tmp/my_socket |qemu_system| linux2.img -hdb nbd+unix://?socket=/tmp/my_socket
If the nbd-server uses named exports (supported since NBD 2.9.18, or with QEMU's If the ``nbd-server`` uses named exports (supported since NBD 2.9.18, or with QEMU's
own embedded NBD server), you must specify an export name in the URI: own embedded NBD server), you must specify an export name in the URI:
.. parsed-literal:: .. parsed-literal::

View File

@ -45,7 +45,7 @@ Shakti SDK can be used to generate the baremetal example UART applications.
Binary would be generated in: Binary would be generated in:
software/examples/uart_applns/loopback/output/loopback.shakti software/examples/uart_applns/loopback/output/loopback.shakti
You could also download the precompiled example applicatons using below You could also download the precompiled example applications using below
commands. commands.
.. code-block:: bash .. code-block:: bash

View File

@ -311,7 +311,7 @@ containing one or more usernames and random keys::
mkdir -m 0700 /tmp/keys mkdir -m 0700 /tmp/keys
psktool -u rich -p /tmp/keys/keys.psk psktool -u rich -p /tmp/keys/keys.psk
TLS-enabled servers such as qemu-nbd can use this directory like so:: TLS-enabled servers such as ``qemu-nbd`` can use this directory like so::
qemu-nbd \ qemu-nbd \
-t -x / \ -t -x / \

View File

@ -273,14 +273,12 @@ A group can be created using the object-add QMP function:
"arguments": { "arguments": {
"qom-type": "throttle-group", "qom-type": "throttle-group",
"id": "group0", "id": "group0",
"props": {
"limits" : { "limits" : {
"iops-total": 1000 "iops-total": 1000,
"bps-write": 2097152 "bps-write": 2097152
} }
} }
} }
}
throttle-group has a 'limits' property (of type ThrottleLimits as throttle-group has a 'limits' property (of type ThrottleLimits as
defined in qapi/block-core.json) which can be set on creation or later defined in qapi/block-core.json) which can be set on creation or later

View File

@ -127,9 +127,9 @@ by the used format or see the format descriptions below for details.
.. option:: -S SIZE .. option:: -S SIZE
Indicates the consecutive number of bytes that must contain only zeros Indicates the consecutive number of bytes that must contain only zeros
for qemu-img to create a sparse image during conversion. This value is rounded for ``qemu-img`` to create a sparse image during conversion. This value is
down to the nearest 512 bytes. You may use the common size suffixes like rounded down to the nearest 512 bytes. You may use the common size suffixes
``k`` for kilobytes. like ``k`` for kilobytes.
.. option:: -t CACHE .. option:: -t CACHE
@ -431,7 +431,7 @@ Command description:
suppressed from the destination image. suppressed from the destination image.
*SPARSE_SIZE* indicates the consecutive number of bytes (defaults to 4k) *SPARSE_SIZE* indicates the consecutive number of bytes (defaults to 4k)
that must contain only zeros for qemu-img to create a sparse image during that must contain only zeros for ``qemu-img`` to create a sparse image during
conversion. If *SPARSE_SIZE* is 0, the source will not be scanned for conversion. If *SPARSE_SIZE* is 0, the source will not be scanned for
unallocated or zero sectors, and the destination image will always be unallocated or zero sectors, and the destination image will always be
fully allocated. fully allocated.
@ -447,7 +447,7 @@ Command description:
If the ``-n`` option is specified, the target volume creation will be If the ``-n`` option is specified, the target volume creation will be
skipped. This is useful for formats such as ``rbd`` if the target skipped. This is useful for formats such as ``rbd`` if the target
volume has already been created with site specific options that cannot volume has already been created with site specific options that cannot
be supplied through qemu-img. be supplied through ``qemu-img``.
Out of order writes can be enabled with ``-W`` to improve performance. Out of order writes can be enabled with ``-W`` to improve performance.
This is only recommended for preallocated devices like host devices or other This is only recommended for preallocated devices like host devices or other
@ -472,7 +472,7 @@ Command description:
If the option *BACKING_FILE* is specified, then the image will record If the option *BACKING_FILE* is specified, then the image will record
only the differences from *BACKING_FILE*. No size needs to be specified in only the differences from *BACKING_FILE*. No size needs to be specified in
this case. *BACKING_FILE* will never be modified unless you use the this case. *BACKING_FILE* will never be modified unless you use the
``commit`` monitor command (or qemu-img commit). ``commit`` monitor command (or ``qemu-img commit``).
If a relative path name is given, the backing file is looked up relative to If a relative path name is given, the backing file is looked up relative to
the directory containing *FILENAME*. the directory containing *FILENAME*.
@ -684,7 +684,7 @@ Command description:
Safe mode Safe mode
This is the default mode and performs a real rebase operation. The This is the default mode and performs a real rebase operation. The
new backing file may differ from the old one and qemu-img rebase new backing file may differ from the old one and ``qemu-img rebase``
will take care of keeping the guest-visible content of *FILENAME* will take care of keeping the guest-visible content of *FILENAME*
unchanged. unchanged.
@ -697,7 +697,7 @@ Command description:
exists. exists.
Unsafe mode Unsafe mode
qemu-img uses the unsafe mode if ``-u`` is specified. In this ``qemu-img`` uses the unsafe mode if ``-u`` is specified. In this
mode, only the backing file name and format of *FILENAME* is changed mode, only the backing file name and format of *FILENAME* is changed
without any checks on the file contents. The user must take care of without any checks on the file contents. The user must take care of
specifying the correct new backing file, or the guest-visible specifying the correct new backing file, or the guest-visible
@ -735,7 +735,7 @@ Command description:
sizes accordingly. Failure to do so will result in data loss! sizes accordingly. Failure to do so will result in data loss!
When shrinking images, the ``--shrink`` option must be given. This informs When shrinking images, the ``--shrink`` option must be given. This informs
qemu-img that the user acknowledges all loss of data beyond the truncated ``qemu-img`` that the user acknowledges all loss of data beyond the truncated
image's end. image's end.
After using this command to grow a disk image, you must use file system and After using this command to grow a disk image, you must use file system and

View File

@ -31,14 +31,14 @@ driver options if ``--image-opts`` is specified.
*dev* is an NBD device. *dev* is an NBD device.
.. option:: --object type,id=ID,...props... .. option:: --object type,id=ID,...
Define a new instance of the *type* object class identified by *ID*. Define a new instance of the *type* object class identified by *ID*.
See the :manpage:`qemu(1)` manual page for full details of the properties See the :manpage:`qemu(1)` manual page for full details of the properties
supported. The common object types that it makes sense to define are the supported. The common object types that it makes sense to define are the
``secret`` object, which is used to supply passwords and/or encryption ``secret`` object, which is used to supply passwords and/or encryption
keys, and the ``tls-creds`` object, which is used to supply TLS keys, and the ``tls-creds`` object, which is used to supply TLS
credentials for the qemu-nbd server or client. credentials for the ``qemu-nbd`` server or client.
.. option:: -p, --port=PORT .. option:: -p, --port=PORT
@ -238,7 +238,7 @@ daemon:
Expose the guest-visible contents of a qcow2 file via a block device Expose the guest-visible contents of a qcow2 file via a block device
/dev/nbd0 (and possibly creating /dev/nbd0p1 and friends for /dev/nbd0 (and possibly creating /dev/nbd0p1 and friends for
partitions found within), then disconnect the device when done. partitions found within), then disconnect the device when done.
Access to bind qemu-nbd to an /dev/nbd device generally requires root Access to bind ``qemu-nbd`` to a /dev/nbd device generally requires root
privileges, and may also require the execution of ``modprobe nbd`` privileges, and may also require the execution of ``modprobe nbd``
to enable the kernel NBD client module. *CAUTION*: Do not use to enable the kernel NBD client module. *CAUTION*: Do not use
this method to mount filesystems from an untrusted guest image - a this method to mount filesystems from an untrusted guest image - a

View File

@ -10,9 +10,10 @@ Synopsis
Description Description
----------- -----------
qemu-storage-daemon provides disk image functionality from QEMU, qemu-img, and ``qemu-storage-daemon`` provides disk image functionality from QEMU,
qemu-nbd in a long-running process controlled via QMP commands without running ``qemu-img``, and ``qemu-nbd`` in a long-running process controlled via QMP
a virtual machine. It can export disk images, run block job operations, and commands without running a virtual machine.
It can export disk images, run block job operations, and
perform other disk-related operations. The daemon is controlled via a QMP perform other disk-related operations. The daemon is controlled via a QMP
monitor and initial configuration from the command-line. monitor and initial configuration from the command-line.

View File

@ -136,8 +136,8 @@ Extended attribute (xattr) mapping
By default the name of xattr's used by the client are passed through to the server By default the name of xattr's used by the client are passed through to the server
file system. This can be a problem where either those xattr names are used file system. This can be a problem where either those xattr names are used
by something on the server (e.g. selinux client/server confusion) or if the by something on the server (e.g. selinux client/server confusion) or if the
virtiofsd is running in a container with restricted privileges where it cannot ``virtiofsd`` is running in a container with restricted privileges where it
access some attributes. cannot access some attributes.
Mapping syntax Mapping syntax
~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~

View File

@ -21,7 +21,7 @@ The second factor is materialized by a device implementing the U2F
protocol. In case of a USB U2F security key, it is a USB HID device protocol. In case of a USB U2F security key, it is a USB HID device
that implements the U2F protocol. that implements the U2F protocol.
In Qemu, the USB U2F key device offers a dedicated support of U2F, allowing In QEMU, the USB U2F key device offers a dedicated support of U2F, allowing
guest USB FIDO/U2F security keys operating in two possible modes: guest USB FIDO/U2F security keys operating in two possible modes:
pass-through and emulated. pass-through and emulated.

View File

@ -94,7 +94,7 @@ static inline int cpu_gdb_index(CPUState *cpu)
{ {
#if defined(CONFIG_USER_ONLY) #if defined(CONFIG_USER_ONLY)
TaskState *ts = (TaskState *) cpu->opaque; TaskState *ts = (TaskState *) cpu->opaque;
return ts->ts_tid; return ts ? ts->ts_tid : -1;
#else #else
return cpu->cpu_index + 1; return cpu->cpu_index + 1;
#endif #endif

View File

@ -222,6 +222,23 @@ static void acpi_pcihp_eject_slot(AcpiPciHpState *s, unsigned bsel, unsigned slo
PCIDevice *dev = PCI_DEVICE(qdev); PCIDevice *dev = PCI_DEVICE(qdev);
if (PCI_SLOT(dev->devfn) == slot) { if (PCI_SLOT(dev->devfn) == slot) {
if (!acpi_pcihp_pc_no_hotplug(s, dev)) { if (!acpi_pcihp_pc_no_hotplug(s, dev)) {
/*
* partially_hotplugged is used by virtio-net failover:
* failover has asked the guest OS to unplug the device
* but we need to keep some references to the device
* to be able to plug it back in case of failure so
* we don't execute hotplug_handler_unplug().
*/
if (dev->partially_hotplugged) {
/*
* pending_deleted_event is set to true when
* virtio-net failover asks to unplug the device,
* and set to false here when the operation is done
* This is used by the migration loop to detect the
* end of the operation and really start the migration.
*/
qdev->pending_deleted_event = false;
} else {
hotplug_ctrl = qdev_get_hotplug_handler(qdev); hotplug_ctrl = qdev_get_hotplug_handler(qdev);
hotplug_handler_unplug(hotplug_ctrl, qdev, &error_abort); hotplug_handler_unplug(hotplug_ctrl, qdev, &error_abort);
object_unparent(OBJECT(qdev)); object_unparent(OBJECT(qdev));
@ -229,6 +246,7 @@ static void acpi_pcihp_eject_slot(AcpiPciHpState *s, unsigned bsel, unsigned slo
} }
} }
} }
}
static void acpi_pcihp_update_hotplug_bus(AcpiPciHpState *s, int bsel) static void acpi_pcihp_update_hotplug_bus(AcpiPciHpState *s, int bsel)
{ {
@ -396,6 +414,12 @@ void acpi_pcihp_device_unplug_request_cb(HotplugHandler *hotplug_dev,
return; return;
} }
/*
* pending_deleted_event is used by virtio-net failover to detect the
* end of the unplug operation, the flag is set to false in
* acpi_pcihp_eject_slot() when the operation is completed.
*/
pdev->qdev.pending_deleted_event = true;
s->acpi_pcihp_pci_status[bsel].down |= (1U << slot); s->acpi_pcihp_pci_status[bsel].down |= (1U << slot);
acpi_send_event(DEVICE(hotplug_dev), ACPI_PCI_HOTPLUG_STATUS); acpi_send_event(DEVICE(hotplug_dev), ACPI_PCI_HOTPLUG_STATUS);
} }

View File

@ -49,6 +49,7 @@
#include "sysemu/runstate.h" #include "sysemu/runstate.h"
#include "sysemu/tpm.h" #include "sysemu/tpm.h"
#include "sysemu/kvm.h" #include "sysemu/kvm.h"
#include "sysemu/hvf.h"
#include "hw/loader.h" #include "hw/loader.h"
#include "qapi/error.h" #include "qapi/error.h"
#include "qemu/bitops.h" #include "qemu/bitops.h"
@ -1969,15 +1970,17 @@ static void machvirt_init(MachineState *machine)
exit(1); exit(1);
} }
if (vms->virt && kvm_enabled()) { if (vms->virt && (kvm_enabled() || hvf_enabled())) {
error_report("mach-virt: KVM does not support providing " error_report("mach-virt: %s does not support providing "
"Virtualization extensions to the guest CPU"); "Virtualization extensions to the guest CPU",
kvm_enabled() ? "KVM" : "HVF");
exit(1); exit(1);
} }
if (vms->mte && kvm_enabled()) { if (vms->mte && (kvm_enabled() || hvf_enabled())) {
error_report("mach-virt: KVM does not support providing " error_report("mach-virt: %s does not support providing "
"MTE to the guest CPU"); "MTE to the guest CPU",
kvm_enabled() ? "KVM" : "HVF");
exit(1); exit(1);
} }

View File

@ -61,6 +61,12 @@
} while (0) } while (0)
/* Anonymous BlockBackend for empty drive */
static BlockBackend *blk_create_empty_drive(void)
{
return blk_new(qemu_get_aio_context(), 0, BLK_PERM_ALL);
}
/********************************************************/ /********************************************************/
/* qdev floppy bus */ /* qdev floppy bus */
@ -486,8 +492,7 @@ static void floppy_drive_realize(DeviceState *qdev, Error **errp)
} }
if (!dev->conf.blk) { if (!dev->conf.blk) {
/* Anonymous BlockBackend for an empty drive */ dev->conf.blk = blk_create_empty_drive();
dev->conf.blk = blk_new(qemu_get_aio_context(), 0, BLK_PERM_ALL);
ret = blk_attach_dev(dev->conf.blk, qdev); ret = blk_attach_dev(dev->conf.blk, qdev);
assert(ret == 0); assert(ret == 0);
@ -1161,7 +1166,19 @@ static FDrive *get_drv(FDCtrl *fdctrl, int unit)
static FDrive *get_cur_drv(FDCtrl *fdctrl) static FDrive *get_cur_drv(FDCtrl *fdctrl)
{ {
return get_drv(fdctrl, fdctrl->cur_drv); FDrive *cur_drv = get_drv(fdctrl, fdctrl->cur_drv);
if (!cur_drv->blk) {
/*
* Kludge: empty drive line selected. Create an anonymous
* BlockBackend to avoid NULL deref with various BlockBackend
* API calls within this model (CVE-2021-20196).
* Due to the controller QOM model limitations, we don't
* attach the created to the controller device.
*/
cur_drv->blk = blk_create_empty_drive();
}
return cur_drv;
} }
/* Status A register : 0x00 (read-only) */ /* Status A register : 0x00 (read-only) */

View File

@ -354,6 +354,17 @@ static void escc_reset(DeviceState *d)
cs->rregs[j] = 0; cs->rregs[j] = 0;
cs->wregs[j] = 0; cs->wregs[j] = 0;
} }
/*
* ...but there is an exception. The "Transmit Interrupts and Transmit
* Buffer Empty Bit" section on page 50 of the ESCC datasheet says of
* the STATUS_TXEMPTY bit in R_STATUS: "After a hardware reset
* (including a hardware reset by software), or a channel reset, this
* bit is set to 1". The Sun PROM checks this bit early on startup and
* gets stuck in an infinite loop if it is not set.
*/
cs->rregs[R_STATUS] |= STATUS_TXEMPTY;
escc_reset_chn(cs); escc_reset_chn(cs);
} }
} }
@ -575,6 +586,20 @@ static void escc_mem_write(void *opaque, hwaddr addr,
s->wregs[s->reg] = val; s->wregs[s->reg] = val;
break; break;
case W_TXCTRL1: case W_TXCTRL1:
s->wregs[s->reg] = val;
/*
* The ESCC datasheet states that SPEC_ALLSENT is always set in
* sync mode, and set in async mode when all characters have
* cleared the transmitter. Since writes to SERIAL_DATA use the
* blocking qemu_chr_fe_write_all() function to write each
* character, the guest can never see the state when async data
* is in the process of being transmitted so we can set this bit
* unconditionally regardless of the state of the W_TXCTRL1 mode
* bits.
*/
s->rregs[R_SPEC] |= SPEC_ALLSENT;
escc_update_parameters(s);
break;
case W_TXCTRL2: case W_TXCTRL2:
s->wregs[s->reg] = val; s->wregs[s->reg] = val;
escc_update_parameters(s); escc_update_parameters(s);

View File

@ -3629,6 +3629,12 @@ static void vtd_init(IntelIOMMUState *s)
vtd_spte_rsvd_large[3] = VTD_SPTE_LPAGE_L3_RSVD_MASK(s->aw_bits, vtd_spte_rsvd_large[3] = VTD_SPTE_LPAGE_L3_RSVD_MASK(s->aw_bits,
x86_iommu->dt_supported); x86_iommu->dt_supported);
if (s->scalable_mode) {
vtd_spte_rsvd[1] &= ~VTD_SPTE_SNP;
vtd_spte_rsvd_large[2] &= ~VTD_SPTE_SNP;
vtd_spte_rsvd_large[3] &= ~VTD_SPTE_SNP;
}
if (x86_iommu_ir_supported(x86_iommu)) { if (x86_iommu_ir_supported(x86_iommu)) {
s->ecap |= VTD_ECAP_IR | VTD_ECAP_MHMV; s->ecap |= VTD_ECAP_IR | VTD_ECAP_MHMV;
if (s->intr_eim == ON_OFF_AUTO_ON) { if (s->intr_eim == ON_OFF_AUTO_ON) {

View File

@ -388,6 +388,8 @@ typedef union VTDInvDesc VTDInvDesc;
#define VTD_INV_DESC_DEVICE_IOTLB_RSVD_LO 0xffff0000ffe0fff8 #define VTD_INV_DESC_DEVICE_IOTLB_RSVD_LO 0xffff0000ffe0fff8
/* Rsvd field masks for spte */ /* Rsvd field masks for spte */
#define VTD_SPTE_SNP 0x800ULL
#define VTD_SPTE_PAGE_L1_RSVD_MASK(aw, dt_supported) \ #define VTD_SPTE_PAGE_L1_RSVD_MASK(aw, dt_supported) \
dt_supported ? \ dt_supported ? \
(0x800ULL | ~(VTD_HAW_MASK(aw) | VTD_SL_IGN_COM | VTD_SL_TM)) : \ (0x800ULL | ~(VTD_HAW_MASK(aw) | VTD_SL_IGN_COM | VTD_SL_TM)) : \

View File

@ -143,6 +143,8 @@ static void dt_add_pcie(MicrovmMachineState *mms)
nr_pcie_buses = PCIE_ECAM_SIZE / PCIE_MMCFG_SIZE_MIN; nr_pcie_buses = PCIE_ECAM_SIZE / PCIE_MMCFG_SIZE_MIN;
qemu_fdt_setprop_cells(mms->fdt, nodename, "bus-range", 0, qemu_fdt_setprop_cells(mms->fdt, nodename, "bus-range", 0,
nr_pcie_buses - 1); nr_pcie_buses - 1);
g_free(nodename);
} }
static void dt_add_ioapic(MicrovmMachineState *mms, SysBusDevice *dev) static void dt_add_ioapic(MicrovmMachineState *mms, SysBusDevice *dev)
@ -327,12 +329,17 @@ void dt_setup_microvm(MicrovmMachineState *mms)
dt_setup_sys_bus(mms); dt_setup_sys_bus(mms);
/* add to fw_cfg */ /* add to fw_cfg */
if (debug) {
fprintf(stderr, "%s: add etc/fdt to fw_cfg\n", __func__); fprintf(stderr, "%s: add etc/fdt to fw_cfg\n", __func__);
}
fw_cfg_add_file(x86ms->fw_cfg, "etc/fdt", mms->fdt, size); fw_cfg_add_file(x86ms->fw_cfg, "etc/fdt", mms->fdt, size);
if (debug) { if (debug) {
fprintf(stderr, "%s: writing microvm.fdt\n", __func__); fprintf(stderr, "%s: writing microvm.fdt\n", __func__);
g_file_set_contents("microvm.fdt", mms->fdt, size, NULL); if (!g_file_set_contents("microvm.fdt", mms->fdt, size, NULL)) {
fprintf(stderr, "%s: writing microvm.fdt failed\n", __func__);
return;
}
int ret = system("dtc -I dtb -O dts microvm.fdt"); int ret = system("dtc -I dtb -O dts microvm.fdt");
if (ret != 0) { if (ret != 0) {
fprintf(stderr, "%s: oops, dtc not installed?\n", __func__); fprintf(stderr, "%s: oops, dtc not installed?\n", __func__);

View File

@ -186,7 +186,9 @@ static void gicv3_redist_update_noirqset(GICv3CPUState *cs)
* interrupt has reduced in priority and any other interrupt could * interrupt has reduced in priority and any other interrupt could
* now be the new best one). * now be the new best one).
*/ */
if (!seenbetter && cs->hppi.prio != 0xff && cs->hppi.irq < GIC_INTERNAL) { if (!seenbetter && cs->hppi.prio != 0xff &&
(cs->hppi.irq < GIC_INTERNAL ||
cs->hppi.irq >= GICV3_LPI_INTID_START)) {
gicv3_full_update_noirqset(cs->gic); gicv3_full_update_noirqset(cs->gic);
} }
} }
@ -354,7 +356,7 @@ static void arm_gicv3_post_load(GICv3State *s)
* pending interrupt, but don't set IRQ or FIQ lines. * pending interrupt, but don't set IRQ or FIQ lines.
*/ */
for (i = 0; i < s->num_cpu; i++) { for (i = 0; i < s->num_cpu; i++) {
gicv3_redist_update_lpi(&s->cpu[i]); gicv3_redist_update_lpi_only(&s->cpu[i]);
} }
gicv3_full_update_noirqset(s); gicv3_full_update_noirqset(s);
/* Repopulate the cache of GICv3CPUState pointers for target CPUs */ /* Repopulate the cache of GICv3CPUState pointers for target CPUs */

View File

@ -653,7 +653,7 @@ static uint64_t icv_iar_read(CPUARMState *env, const ARMCPRegInfo *ri)
if (thisgrp == grp && icv_hppi_can_preempt(cs, lr)) { if (thisgrp == grp && icv_hppi_can_preempt(cs, lr)) {
intid = ich_lr_vintid(lr); intid = ich_lr_vintid(lr);
if (intid < INTID_SECURE) { if (!gicv3_intid_is_special(intid)) {
icv_activate_irq(cs, idx, grp); icv_activate_irq(cs, idx, grp);
} else { } else {
/* Interrupt goes from Pending to Invalid */ /* Interrupt goes from Pending to Invalid */
@ -997,7 +997,7 @@ static uint64_t icc_iar0_read(CPUARMState *env, const ARMCPRegInfo *ri)
intid = icc_hppir0_value(cs, env); intid = icc_hppir0_value(cs, env);
} }
if (!(intid >= INTID_SECURE && intid <= INTID_SPURIOUS)) { if (!gicv3_intid_is_special(intid)) {
icc_activate_irq(cs, intid); icc_activate_irq(cs, intid);
} }
@ -1020,7 +1020,7 @@ static uint64_t icc_iar1_read(CPUARMState *env, const ARMCPRegInfo *ri)
intid = icc_hppir1_value(cs, env); intid = icc_hppir1_value(cs, env);
} }
if (!(intid >= INTID_SECURE && intid <= INTID_SPURIOUS)) { if (!gicv3_intid_is_special(intid)) {
icc_activate_irq(cs, intid); icc_activate_irq(cs, intid);
} }
@ -1265,8 +1265,7 @@ static void icv_eoir_write(CPUARMState *env, const ARMCPRegInfo *ri,
trace_gicv3_icv_eoir_write(ri->crm == 8 ? 0 : 1, trace_gicv3_icv_eoir_write(ri->crm == 8 ? 0 : 1,
gicv3_redist_affid(cs), value); gicv3_redist_affid(cs), value);
if (irq >= GICV3_MAXIRQ) { if (gicv3_intid_is_special(irq)) {
/* Also catches special interrupt numbers and LPIs */
return; return;
} }

View File

@ -896,13 +896,14 @@ static bool its_writel(GICv3ITSState *s, hwaddr offset,
switch (offset) { switch (offset) {
case GITS_CTLR: case GITS_CTLR:
s->ctlr |= (value & ~(s->ctlr)); if (value & R_GITS_CTLR_ENABLED_MASK) {
s->ctlr |= ITS_CTLR_ENABLED;
if (s->ctlr & ITS_CTLR_ENABLED) {
extract_table_params(s); extract_table_params(s);
extract_cmdq_params(s); extract_cmdq_params(s);
s->creadr = 0; s->creadr = 0;
process_cmdq(s); process_cmdq(s);
} else {
s->ctlr &= ~ITS_CTLR_ENABLED;
} }
break; break;
case GITS_CBASER: case GITS_CBASER:

View File

@ -50,8 +50,6 @@ static int gicv3_its_post_load(void *opaque, int version_id)
static const VMStateDescription vmstate_its = { static const VMStateDescription vmstate_its = {
.name = "arm_gicv3_its", .name = "arm_gicv3_its",
.version_id = 1,
.minimum_version_id = 1,
.pre_save = gicv3_its_pre_save, .pre_save = gicv3_its_pre_save,
.post_load = gicv3_its_post_load, .post_load = gicv3_its_post_load,
.priority = MIG_PRI_GICV3_ITS, .priority = MIG_PRI_GICV3_ITS,

View File

@ -256,9 +256,10 @@ static MemTxResult gicr_writel(GICv3CPUState *cs, hwaddr offset,
cs->gicr_ctlr |= GICR_CTLR_ENABLE_LPIS; cs->gicr_ctlr |= GICR_CTLR_ENABLE_LPIS;
/* Check for any pending interr in pending table */ /* Check for any pending interr in pending table */
gicv3_redist_update_lpi(cs); gicv3_redist_update_lpi(cs);
gicv3_redist_update(cs);
} else { } else {
cs->gicr_ctlr &= ~GICR_CTLR_ENABLE_LPIS; cs->gicr_ctlr &= ~GICR_CTLR_ENABLE_LPIS;
/* cs->hppi might have been an LPI; recalculate */
gicv3_redist_update(cs);
} }
} }
return MEMTX_OK; return MEMTX_OK;
@ -571,7 +572,7 @@ static void gicv3_redist_check_lpi_priority(GICv3CPUState *cs, int irq)
} }
} }
void gicv3_redist_update_lpi(GICv3CPUState *cs) void gicv3_redist_update_lpi_only(GICv3CPUState *cs)
{ {
/* /*
* This function scans the LPI pending table and for each pending * This function scans the LPI pending table and for each pending
@ -614,6 +615,12 @@ void gicv3_redist_update_lpi(GICv3CPUState *cs)
} }
} }
void gicv3_redist_update_lpi(GICv3CPUState *cs)
{
gicv3_redist_update_lpi_only(cs);
gicv3_redist_update(cs);
}
void gicv3_redist_lpi_pending(GICv3CPUState *cs, int irq, int level) void gicv3_redist_lpi_pending(GICv3CPUState *cs, int irq, int level)
{ {
/* /*
@ -651,6 +658,7 @@ void gicv3_redist_lpi_pending(GICv3CPUState *cs, int irq, int level)
*/ */
if (level) { if (level) {
gicv3_redist_check_lpi_priority(cs, irq); gicv3_redist_check_lpi_priority(cs, irq);
gicv3_redist_update(cs);
} else { } else {
if (irq == cs->hpplpi.irq) { if (irq == cs->hpplpi.irq) {
gicv3_redist_update_lpi(cs); gicv3_redist_update_lpi(cs);
@ -673,8 +681,6 @@ void gicv3_redist_process_lpi(GICv3CPUState *cs, int irq, int level)
/* set/clear the pending bit for this irq */ /* set/clear the pending bit for this irq */
gicv3_redist_lpi_pending(cs, irq, level); gicv3_redist_lpi_pending(cs, irq, level);
gicv3_redist_update(cs);
} }
void gicv3_redist_set_irq(GICv3CPUState *cs, int irq, int level) void gicv3_redist_set_irq(GICv3CPUState *cs, int irq, int level)

View File

@ -411,6 +411,19 @@ FIELD(MAPC, RDBASE, 16, 32)
/* Functions internal to the emulated GICv3 */ /* Functions internal to the emulated GICv3 */
/**
* gicv3_intid_is_special:
* @intid: interrupt ID
*
* Return true if @intid is a special interrupt ID (1020 to
* 1023 inclusive). This corresponds to the GIC spec pseudocode
* IsSpecial() function.
*/
static inline bool gicv3_intid_is_special(int intid)
{
return intid >= INTID_SECURE && intid <= INTID_SPURIOUS;
}
/** /**
* gicv3_redist_update: * gicv3_redist_update:
* @cs: GICv3CPUState for this redistributor * @cs: GICv3CPUState for this redistributor
@ -463,7 +476,24 @@ void gicv3_dist_set_irq(GICv3State *s, int irq, int level);
void gicv3_redist_set_irq(GICv3CPUState *cs, int irq, int level); void gicv3_redist_set_irq(GICv3CPUState *cs, int irq, int level);
void gicv3_redist_process_lpi(GICv3CPUState *cs, int irq, int level); void gicv3_redist_process_lpi(GICv3CPUState *cs, int irq, int level);
void gicv3_redist_lpi_pending(GICv3CPUState *cs, int irq, int level); void gicv3_redist_lpi_pending(GICv3CPUState *cs, int irq, int level);
/**
* gicv3_redist_update_lpi:
* @cs: GICv3CPUState
*
* Scan the LPI pending table and recalculate the highest priority
* pending LPI and also the overall highest priority pending interrupt.
*/
void gicv3_redist_update_lpi(GICv3CPUState *cs); void gicv3_redist_update_lpi(GICv3CPUState *cs);
/**
* gicv3_redist_update_lpi_only:
* @cs: GICv3CPUState
*
* Scan the LPI pending table and recalculate cs->hpplpi only,
* without calling gicv3_redist_update() to recalculate the overall
* highest priority pending interrupt. This should be called after
* an incoming migration has loaded new state.
*/
void gicv3_redist_update_lpi_only(GICv3CPUState *cs);
void gicv3_redist_send_sgi(GICv3CPUState *cs, int grp, int irq, bool ns); void gicv3_redist_send_sgi(GICv3CPUState *cs, int grp, int irq, bool ns);
void gicv3_init_cpuif(GICv3State *s); void gicv3_init_cpuif(GICv3State *s);

View File

@ -718,6 +718,7 @@ static const VMStateDescription vmstate_pmu = {
}, },
.subsections = (const VMStateDescription * []) { .subsections = (const VMStateDescription * []) {
&vmstate_pmu_adb, &vmstate_pmu_adb,
NULL
} }
}; };

View File

@ -209,7 +209,14 @@ static void sifive_u_otp_realize(DeviceState *dev, Error **errp)
TYPE_SIFIVE_U_OTP, SIFIVE_U_OTP_REG_SIZE); TYPE_SIFIVE_U_OTP, SIFIVE_U_OTP_REG_SIZE);
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mmio); sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mmio);
dinfo = drive_get_next(IF_PFLASH);
if (!dinfo) {
dinfo = drive_get_next(IF_NONE); dinfo = drive_get_next(IF_NONE);
if (dinfo) {
warn_report("using \"-drive if=none\" for the OTP is deprecated, "
"use \"-drive if=pflash\" instead.");
}
}
if (dinfo) { if (dinfo) {
int ret; int ret;
uint64_t perm; uint64_t perm;
@ -235,14 +242,10 @@ static void sifive_u_otp_realize(DeviceState *dev, Error **errp)
if (blk_pread(s->blk, 0, s->fuse, filesize) != filesize) { if (blk_pread(s->blk, 0, s->fuse, filesize) != filesize) {
error_setg(errp, "failed to read the initial flash content"); error_setg(errp, "failed to read the initial flash content");
return;
} }
} }
} }
}
static void sifive_u_otp_reset(DeviceState *dev)
{
SiFiveUOTPState *s = SIFIVE_U_OTP(dev);
/* Initialize all fuses' initial value to 0xFFs */ /* Initialize all fuses' initial value to 0xFFs */
memset(s->fuse, 0xff, sizeof(s->fuse)); memset(s->fuse, 0xff, sizeof(s->fuse));
@ -259,13 +262,15 @@ static void sifive_u_otp_reset(DeviceState *dev)
serial_data = s->serial; serial_data = s->serial;
if (blk_pwrite(s->blk, index * SIFIVE_U_OTP_FUSE_WORD, if (blk_pwrite(s->blk, index * SIFIVE_U_OTP_FUSE_WORD,
&serial_data, SIFIVE_U_OTP_FUSE_WORD, 0) < 0) { &serial_data, SIFIVE_U_OTP_FUSE_WORD, 0) < 0) {
error_report("write error index<%d>", index); error_setg(errp, "failed to write index<%d>", index);
return;
} }
serial_data = ~(s->serial); serial_data = ~(s->serial);
if (blk_pwrite(s->blk, (index + 1) * SIFIVE_U_OTP_FUSE_WORD, if (blk_pwrite(s->blk, (index + 1) * SIFIVE_U_OTP_FUSE_WORD,
&serial_data, SIFIVE_U_OTP_FUSE_WORD, 0) < 0) { &serial_data, SIFIVE_U_OTP_FUSE_WORD, 0) < 0) {
error_report("write error index<%d>", index + 1); error_setg(errp, "failed to write index<%d>", index + 1);
return;
} }
} }
@ -279,7 +284,6 @@ static void sifive_u_otp_class_init(ObjectClass *klass, void *data)
device_class_set_props(dc, sifive_u_otp_properties); device_class_set_props(dc, sifive_u_otp_properties);
dc->realize = sifive_u_otp_realize; dc->realize = sifive_u_otp_realize;
dc->reset = sifive_u_otp_reset;
} }
static const TypeInfo sifive_u_otp_info = { static const TypeInfo sifive_u_otp_info = {

View File

@ -929,8 +929,8 @@ void pcie_add_capability(PCIDevice *dev,
uint16_t offset, uint16_t size) uint16_t offset, uint16_t size)
{ {
assert(offset >= PCI_CONFIG_SPACE_SIZE); assert(offset >= PCI_CONFIG_SPACE_SIZE);
assert(offset < offset + size); assert(offset < (uint16_t)(offset + size));
assert(offset + size <= PCIE_CONFIG_SPACE_SIZE); assert((uint16_t)(offset + size) <= PCIE_CONFIG_SPACE_SIZE);
assert(size >= 8); assert(size >= 8);
assert(pci_is_express(dev)); assert(pci_is_express(dev));

View File

@ -1414,7 +1414,7 @@ void spapr_store_hpte(PowerPCCPU *cpu, hwaddr ptex,
kvmppc_write_hpte(ptex, pte0, pte1); kvmppc_write_hpte(ptex, pte0, pte1);
} else { } else {
if (pte0 & HPTE64_V_VALID) { if (pte0 & HPTE64_V_VALID) {
stq_p(spapr->htab + offset + HASH_PTE_SIZE_64 / 2, pte1); stq_p(spapr->htab + offset + HPTE64_DW1, pte1);
/* /*
* When setting valid, we write PTE1 first. This ensures * When setting valid, we write PTE1 first. This ensures
* proper synchronization with the reading code in * proper synchronization with the reading code in
@ -1430,7 +1430,7 @@ void spapr_store_hpte(PowerPCCPU *cpu, hwaddr ptex,
* ppc_hash64_pteg_search() * ppc_hash64_pteg_search()
*/ */
smp_wmb(); smp_wmb();
stq_p(spapr->htab + offset + HASH_PTE_SIZE_64 / 2, pte1); stq_p(spapr->htab + offset + HPTE64_DW1, pte1);
} }
} }
} }
@ -1438,7 +1438,7 @@ void spapr_store_hpte(PowerPCCPU *cpu, hwaddr ptex,
static void spapr_hpte_set_c(PPCVirtualHypervisor *vhyp, hwaddr ptex, static void spapr_hpte_set_c(PPCVirtualHypervisor *vhyp, hwaddr ptex,
uint64_t pte1) uint64_t pte1)
{ {
hwaddr offset = ptex * HASH_PTE_SIZE_64 + 15; hwaddr offset = ptex * HASH_PTE_SIZE_64 + HPTE64_DW1_C;
SpaprMachineState *spapr = SPAPR_MACHINE(vhyp); SpaprMachineState *spapr = SPAPR_MACHINE(vhyp);
if (!spapr->htab) { if (!spapr->htab) {
@ -1454,7 +1454,7 @@ static void spapr_hpte_set_c(PPCVirtualHypervisor *vhyp, hwaddr ptex,
static void spapr_hpte_set_r(PPCVirtualHypervisor *vhyp, hwaddr ptex, static void spapr_hpte_set_r(PPCVirtualHypervisor *vhyp, hwaddr ptex,
uint64_t pte1) uint64_t pte1)
{ {
hwaddr offset = ptex * HASH_PTE_SIZE_64 + 14; hwaddr offset = ptex * HASH_PTE_SIZE_64 + HPTE64_DW1_R;
SpaprMachineState *spapr = SPAPR_MACHINE(vhyp); SpaprMachineState *spapr = SPAPR_MACHINE(vhyp);
if (!spapr->htab) { if (!spapr->htab) {

View File

@ -426,7 +426,7 @@ static void new_hpte_store(void *htab, uint64_t pteg, int slot,
addr += slot * HASH_PTE_SIZE_64; addr += slot * HASH_PTE_SIZE_64;
stq_p(addr, pte0); stq_p(addr, pte0);
stq_p(addr + HASH_PTE_SIZE_64 / 2, pte1); stq_p(addr + HPTE64_DW1, pte1);
} }
static int rehash_hpte(PowerPCCPU *cpu, static int rehash_hpte(PowerPCCPU *cpu,

View File

@ -894,6 +894,7 @@ void esp_hard_reset(ESPState *s)
memset(s->wregs, 0, ESP_REGS); memset(s->wregs, 0, ESP_REGS);
s->tchi_written = 0; s->tchi_written = 0;
s->ti_size = 0; s->ti_size = 0;
s->async_len = 0;
fifo8_reset(&s->fifo); fifo8_reset(&s->fifo);
fifo8_reset(&s->cmdfifo); fifo8_reset(&s->cmdfifo);
s->dma = 0; s->dma = 0;

View File

@ -231,7 +231,7 @@ static void balloon_stats_poll_cb(void *opaque)
return; return;
} }
virtqueue_push(s->svq, s->stats_vq_elem, s->stats_vq_offset); virtqueue_push(s->svq, s->stats_vq_elem, 0);
virtio_notify(vdev, s->svq); virtio_notify(vdev, s->svq);
g_free(s->stats_vq_elem); g_free(s->stats_vq_elem);
s->stats_vq_elem = NULL; s->stats_vq_elem = NULL;
@ -438,7 +438,7 @@ static void virtio_balloon_handle_output(VirtIODevice *vdev, VirtQueue *vq)
memory_region_unref(section.mr); memory_region_unref(section.mr);
} }
virtqueue_push(vq, elem, offset); virtqueue_push(vq, elem, 0);
virtio_notify(vdev, vq); virtio_notify(vdev, vq);
g_free(elem); g_free(elem);
virtio_balloon_pbp_free(&pbp); virtio_balloon_pbp_free(&pbp);
@ -510,6 +510,7 @@ static bool get_free_page_hints(VirtIOBalloon *dev)
VirtIODevice *vdev = VIRTIO_DEVICE(dev); VirtIODevice *vdev = VIRTIO_DEVICE(dev);
VirtQueue *vq = dev->free_page_vq; VirtQueue *vq = dev->free_page_vq;
bool ret = true; bool ret = true;
int i;
while (dev->block_iothread) { while (dev->block_iothread) {
qemu_cond_wait(&dev->free_page_cond, &dev->free_page_lock); qemu_cond_wait(&dev->free_page_cond, &dev->free_page_lock);
@ -544,12 +545,14 @@ static bool get_free_page_hints(VirtIOBalloon *dev)
} }
if (elem->in_num && dev->free_page_hint_status == FREE_PAGE_HINT_S_START) { if (elem->in_num && dev->free_page_hint_status == FREE_PAGE_HINT_S_START) {
qemu_guest_free_page_hint(elem->in_sg[0].iov_base, for (i = 0; i < elem->in_num; i++) {
elem->in_sg[0].iov_len); qemu_guest_free_page_hint(elem->in_sg[i].iov_base,
elem->in_sg[i].iov_len);
}
} }
out: out:
virtqueue_push(vq, elem, 1); virtqueue_push(vq, elem, 0);
g_free(elem); g_free(elem);
return ret; return ret;
} }

View File

@ -817,6 +817,17 @@ static char *virtio_mmio_bus_get_dev_path(DeviceState *dev)
return path; return path;
} }
static void virtio_mmio_vmstate_change(DeviceState *d, bool running)
{
VirtIOMMIOProxy *proxy = VIRTIO_MMIO(d);
if (running) {
virtio_mmio_start_ioeventfd(proxy);
} else {
virtio_mmio_stop_ioeventfd(proxy);
}
}
static void virtio_mmio_bus_class_init(ObjectClass *klass, void *data) static void virtio_mmio_bus_class_init(ObjectClass *klass, void *data)
{ {
BusClass *bus_class = BUS_CLASS(klass); BusClass *bus_class = BUS_CLASS(klass);
@ -832,6 +843,7 @@ static void virtio_mmio_bus_class_init(ObjectClass *klass, void *data)
k->ioeventfd_enabled = virtio_mmio_ioeventfd_enabled; k->ioeventfd_enabled = virtio_mmio_ioeventfd_enabled;
k->ioeventfd_assign = virtio_mmio_ioeventfd_assign; k->ioeventfd_assign = virtio_mmio_ioeventfd_assign;
k->pre_plugged = virtio_mmio_pre_plugged; k->pre_plugged = virtio_mmio_pre_plugged;
k->vmstate_change = virtio_mmio_vmstate_change;
k->has_variable_vring_alignment = true; k->has_variable_vring_alignment = true;
bus_class->max_dev = 1; bus_class->max_dev = 1;
bus_class->get_dev_path = virtio_mmio_bus_get_dev_path; bus_class->get_dev_path = virtio_mmio_bus_get_dev_path;

View File

@ -503,6 +503,7 @@ struct TranslationBlock {
#define CF_USE_ICOUNT 0x00020000 #define CF_USE_ICOUNT 0x00020000
#define CF_INVALID 0x00040000 /* TB is stale. Set with @jmp_lock held */ #define CF_INVALID 0x00040000 /* TB is stale. Set with @jmp_lock held */
#define CF_PARALLEL 0x00080000 /* Generate code for a parallel context */ #define CF_PARALLEL 0x00080000 /* Generate code for a parallel context */
#define CF_NOIRQ 0x00100000 /* Generate an uninterruptible TB */
#define CF_CLUSTER_MASK 0xff000000 /* Top 8 bits are cluster ID */ #define CF_CLUSTER_MASK 0xff000000 /* Top 8 bits are cluster ID */
#define CF_CLUSTER_SHIFT 24 #define CF_CLUSTER_SHIFT 24

View File

@ -21,7 +21,6 @@ static inline void gen_tb_start(const TranslationBlock *tb)
{ {
TCGv_i32 count; TCGv_i32 count;
tcg_ctx->exitreq_label = gen_new_label();
if (tb_cflags(tb) & CF_USE_ICOUNT) { if (tb_cflags(tb) & CF_USE_ICOUNT) {
count = tcg_temp_local_new_i32(); count = tcg_temp_local_new_i32();
} else { } else {
@ -42,7 +41,19 @@ static inline void gen_tb_start(const TranslationBlock *tb)
icount_start_insn = tcg_last_op(); icount_start_insn = tcg_last_op();
} }
/*
* Emit the check against icount_decr.u32 to see if we should exit
* unless we suppress the check with CF_NOIRQ. If we are using
* icount and have suppressed interruption the higher level code
* should have ensured we don't run more instructions than the
* budget.
*/
if (tb_cflags(tb) & CF_NOIRQ) {
tcg_ctx->exitreq_label = NULL;
} else {
tcg_ctx->exitreq_label = gen_new_label();
tcg_gen_brcondi_i32(TCG_COND_LT, count, 0, tcg_ctx->exitreq_label); tcg_gen_brcondi_i32(TCG_COND_LT, count, 0, tcg_ctx->exitreq_label);
}
if (tb_cflags(tb) & CF_USE_ICOUNT) { if (tb_cflags(tb) & CF_USE_ICOUNT) {
tcg_gen_st16_i32(count, cpu_env, tcg_gen_st16_i32(count, cpu_env,
@ -74,8 +85,10 @@ static inline void gen_tb_end(const TranslationBlock *tb, int num_insns)
tcgv_i32_arg(tcg_constant_i32(num_insns))); tcgv_i32_arg(tcg_constant_i32(num_insns)));
} }
if (tcg_ctx->exitreq_label) {
gen_set_label(tcg_ctx->exitreq_label); gen_set_label(tcg_ctx->exitreq_label);
tcg_gen_exit_tb(tb, TB_EXIT_REQUESTED); tcg_gen_exit_tb(tb, TB_EXIT_REQUESTED);
} }
}
#endif #endif

View File

@ -3254,9 +3254,13 @@ int load_elf_binary(struct linux_binprm *bprm, struct image_info *info)
* Otherwise, allocate a private page to hold them. * Otherwise, allocate a private page to hold them.
*/ */
if (TARGET_ARCH_HAS_SIGTRAMP_PAGE) { if (TARGET_ARCH_HAS_SIGTRAMP_PAGE) {
abi_ulong tramp_page = target_mmap(0, TARGET_PAGE_SIZE, abi_long tramp_page = target_mmap(0, TARGET_PAGE_SIZE,
PROT_READ | PROT_WRITE, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANON, -1, 0); MAP_PRIVATE | MAP_ANON, -1, 0);
if (tramp_page == -1) {
return -errno;
}
setup_sigtramp(tramp_page); setup_sigtramp(tramp_page);
target_mprotect(tramp_page, TARGET_PAGE_SIZE, PROT_READ | PROT_EXEC); target_mprotect(tramp_page, TARGET_PAGE_SIZE, PROT_READ | PROT_EXEC);
} }

View File

@ -35,6 +35,11 @@ static inline uintptr_t host_signal_pc(ucontext_t *uc)
return uc->uc_mcontext.pc; return uc->uc_mcontext.pc;
} }
static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc)
{
uc->uc_mcontext.pc = pc;
}
static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc) static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
{ {
struct _aarch64_ctx *hdr; struct _aarch64_ctx *hdr;

View File

@ -15,24 +15,4 @@
/* We have a safe-syscall.inc.S */ /* We have a safe-syscall.inc.S */
#define HAVE_SAFE_SYSCALL #define HAVE_SAFE_SYSCALL
#ifndef __ASSEMBLER__
/* These are defined by the safe-syscall.inc.S file */
extern char safe_syscall_start[];
extern char safe_syscall_end[];
/* Adjust the signal context to rewind out of safe-syscall if we're in it */
static inline void rewind_if_in_safe_syscall(void *puc)
{
ucontext_t *uc = puc;
__u64 *pcreg = &uc->uc_mcontext.pc;
if (*pcreg > (uintptr_t)safe_syscall_start
&& *pcreg < (uintptr_t)safe_syscall_end) {
*pcreg = (uintptr_t)safe_syscall_start;
}
}
#endif /* __ASSEMBLER__ */
#endif #endif

View File

@ -16,6 +16,11 @@ static inline uintptr_t host_signal_pc(ucontext_t *uc)
return uc->uc_mcontext.sc_pc; return uc->uc_mcontext.sc_pc;
} }
static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc)
{
uc->uc_mcontext.sc_pc = pc;
}
static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc) static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
{ {
uint32_t *pc = (uint32_t *)host_signal_pc(uc); uint32_t *pc = (uint32_t *)host_signal_pc(uc);

View File

@ -16,6 +16,11 @@ static inline uintptr_t host_signal_pc(ucontext_t *uc)
return uc->uc_mcontext.arm_pc; return uc->uc_mcontext.arm_pc;
} }
static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc)
{
uc->uc_mcontext.arm_pc = pc;
}
static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc) static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
{ {
/* /*

View File

@ -15,24 +15,4 @@
/* We have a safe-syscall.inc.S */ /* We have a safe-syscall.inc.S */
#define HAVE_SAFE_SYSCALL #define HAVE_SAFE_SYSCALL
#ifndef __ASSEMBLER__
/* These are defined by the safe-syscall.inc.S file */
extern char safe_syscall_start[];
extern char safe_syscall_end[];
/* Adjust the signal context to rewind out of safe-syscall if we're in it */
static inline void rewind_if_in_safe_syscall(void *puc)
{
ucontext_t *uc = puc;
unsigned long *pcreg = &uc->uc_mcontext.arm_pc;
if (*pcreg > (uintptr_t)safe_syscall_start
&& *pcreg < (uintptr_t)safe_syscall_end) {
*pcreg = (uintptr_t)safe_syscall_start;
}
}
#endif /* __ASSEMBLER__ */
#endif #endif

View File

@ -16,6 +16,11 @@ static inline uintptr_t host_signal_pc(ucontext_t *uc)
return uc->uc_mcontext.gregs[REG_EIP]; return uc->uc_mcontext.gregs[REG_EIP];
} }
static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc)
{
uc->uc_mcontext.gregs[REG_EIP] = pc;
}
static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc) static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
{ {
return uc->uc_mcontext.gregs[REG_TRAPNO] == 0xe return uc->uc_mcontext.gregs[REG_TRAPNO] == 0xe

View File

@ -15,24 +15,4 @@
/* We have a safe-syscall.inc.S */ /* We have a safe-syscall.inc.S */
#define HAVE_SAFE_SYSCALL #define HAVE_SAFE_SYSCALL
#ifndef __ASSEMBLER__
/* These are defined by the safe-syscall.inc.S file */
extern char safe_syscall_start[];
extern char safe_syscall_end[];
/* Adjust the signal context to rewind out of safe-syscall if we're in it */
static inline void rewind_if_in_safe_syscall(void *puc)
{
ucontext_t *uc = puc;
greg_t *pcreg = &uc->uc_mcontext.gregs[REG_EIP];
if (*pcreg > (uintptr_t)safe_syscall_start
&& *pcreg < (uintptr_t)safe_syscall_end) {
*pcreg = (uintptr_t)safe_syscall_start;
}
}
#endif /* __ASSEMBLER__ */
#endif #endif

View File

@ -16,6 +16,11 @@ static inline uintptr_t host_signal_pc(ucontext_t *uc)
return uc->uc_mcontext.pc; return uc->uc_mcontext.pc;
} }
static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc)
{
uc->uc_mcontext.pc = pc;
}
#if defined(__misp16) || defined(__mips_micromips) #if defined(__misp16) || defined(__mips_micromips)
#error "Unsupported encoding" #error "Unsupported encoding"
#endif #endif

View File

@ -16,6 +16,11 @@ static inline uintptr_t host_signal_pc(ucontext_t *uc)
return uc->uc_mcontext.regs->nip; return uc->uc_mcontext.regs->nip;
} }
static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc)
{
uc->uc_mcontext.regs->nip = pc;
}
static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc) static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
{ {
return uc->uc_mcontext.regs->trap != 0x400 return uc->uc_mcontext.regs->trap != 0x400

View File

@ -15,24 +15,4 @@
/* We have a safe-syscall.inc.S */ /* We have a safe-syscall.inc.S */
#define HAVE_SAFE_SYSCALL #define HAVE_SAFE_SYSCALL
#ifndef __ASSEMBLER__
/* These are defined by the safe-syscall.inc.S file */
extern char safe_syscall_start[];
extern char safe_syscall_end[];
/* Adjust the signal context to rewind out of safe-syscall if we're in it */
static inline void rewind_if_in_safe_syscall(void *puc)
{
ucontext_t *uc = puc;
unsigned long *pcreg = &uc->uc_mcontext.gp_regs[PT_NIP];
if (*pcreg > (uintptr_t)safe_syscall_start
&& *pcreg < (uintptr_t)safe_syscall_end) {
*pcreg = (uintptr_t)safe_syscall_start;
}
}
#endif /* __ASSEMBLER__ */
#endif #endif

View File

@ -16,6 +16,11 @@ static inline uintptr_t host_signal_pc(ucontext_t *uc)
return uc->uc_mcontext.__gregs[REG_PC]; return uc->uc_mcontext.__gregs[REG_PC];
} }
static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc)
{
uc->uc_mcontext.__gregs[REG_PC] = pc;
}
static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc) static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
{ {
/* /*

View File

@ -11,24 +11,4 @@
/* We have a safe-syscall.inc.S */ /* We have a safe-syscall.inc.S */
#define HAVE_SAFE_SYSCALL #define HAVE_SAFE_SYSCALL
#ifndef __ASSEMBLER__
/* These are defined by the safe-syscall.inc.S file */
extern char safe_syscall_start[];
extern char safe_syscall_end[];
/* Adjust the signal context to rewind out of safe-syscall if we're in it */
static inline void rewind_if_in_safe_syscall(void *puc)
{
ucontext_t *uc = puc;
unsigned long *pcreg = &uc->uc_mcontext.__gregs[REG_PC];
if (*pcreg > (uintptr_t)safe_syscall_start
&& *pcreg < (uintptr_t)safe_syscall_end) {
*pcreg = (uintptr_t)safe_syscall_start;
}
}
#endif /* __ASSEMBLER__ */
#endif #endif

View File

@ -16,6 +16,11 @@ static inline uintptr_t host_signal_pc(ucontext_t *uc)
return uc->uc_mcontext.psw.addr; return uc->uc_mcontext.psw.addr;
} }
static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc)
{
uc->uc_mcontext.psw.addr = pc;
}
static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc) static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
{ {
uint16_t *pinsn = (uint16_t *)host_signal_pc(uc); uint16_t *pinsn = (uint16_t *)host_signal_pc(uc);

View File

@ -15,24 +15,4 @@
/* We have a safe-syscall.inc.S */ /* We have a safe-syscall.inc.S */
#define HAVE_SAFE_SYSCALL #define HAVE_SAFE_SYSCALL
#ifndef __ASSEMBLER__
/* These are defined by the safe-syscall.inc.S file */
extern char safe_syscall_start[];
extern char safe_syscall_end[];
/* Adjust the signal context to rewind out of safe-syscall if we're in it */
static inline void rewind_if_in_safe_syscall(void *puc)
{
ucontext_t *uc = puc;
unsigned long *pcreg = &uc->uc_mcontext.psw.addr;
if (*pcreg > (uintptr_t)safe_syscall_start
&& *pcreg < (uintptr_t)safe_syscall_end) {
*pcreg = (uintptr_t)safe_syscall_start;
}
}
#endif /* __ASSEMBLER__ */
#endif #endif

View File

@ -20,6 +20,15 @@ static inline uintptr_t host_signal_pc(ucontext_t *uc)
#endif #endif
} }
static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc)
{
#ifdef __arch64__
uc->uc_mcontext.mc_gregs[MC_PC] = pc;
#else
uc->uc_mcontext.gregs[REG_PC] = pc;
#endif
}
static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc) static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
{ {
uint32_t insn = *(uint32_t *)host_signal_pc(uc); uint32_t insn = *(uint32_t *)host_signal_pc(uc);

View File

@ -15,6 +15,11 @@ static inline uintptr_t host_signal_pc(ucontext_t *uc)
return uc->uc_mcontext.gregs[REG_RIP]; return uc->uc_mcontext.gregs[REG_RIP];
} }
static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc)
{
uc->uc_mcontext.gregs[REG_RIP] = pc;
}
static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc) static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
{ {
return uc->uc_mcontext.gregs[REG_TRAPNO] == 0xe return uc->uc_mcontext.gregs[REG_TRAPNO] == 0xe

View File

@ -15,24 +15,4 @@
/* We have a safe-syscall.inc.S */ /* We have a safe-syscall.inc.S */
#define HAVE_SAFE_SYSCALL #define HAVE_SAFE_SYSCALL
#ifndef __ASSEMBLER__
/* These are defined by the safe-syscall.inc.S file */
extern char safe_syscall_start[];
extern char safe_syscall_end[];
/* Adjust the signal context to rewind out of safe-syscall if we're in it */
static inline void rewind_if_in_safe_syscall(void *puc)
{
ucontext_t *uc = puc;
greg_t *pcreg = &uc->uc_mcontext.gregs[REG_RIP];
if (*pcreg > (uintptr_t)safe_syscall_start
&& *pcreg < (uintptr_t)safe_syscall_end) {
*pcreg = (uintptr_t)safe_syscall_start;
}
}
#endif /* __ASSEMBLER__ */
#endif #endif

View File

@ -637,6 +637,10 @@
IOCTL(LOOP_SET_STATUS64, IOC_W, MK_PTR(MK_STRUCT(STRUCT_loop_info64))) IOCTL(LOOP_SET_STATUS64, IOC_W, MK_PTR(MK_STRUCT(STRUCT_loop_info64)))
IOCTL(LOOP_GET_STATUS64, IOC_R, MK_PTR(MK_STRUCT(STRUCT_loop_info64))) IOCTL(LOOP_GET_STATUS64, IOC_R, MK_PTR(MK_STRUCT(STRUCT_loop_info64)))
IOCTL(LOOP_CHANGE_FD, 0, TYPE_INT) IOCTL(LOOP_CHANGE_FD, 0, TYPE_INT)
IOCTL(LOOP_SET_CAPACITY, 0, TYPE_INT)
IOCTL(LOOP_SET_DIRECT_IO, 0, TYPE_INT)
IOCTL(LOOP_SET_BLOCK_SIZE, 0, TYPE_INT)
IOCTL(LOOP_CONFIGURE, IOC_W, MK_PTR(MK_STRUCT(STRUCT_loop_config)))
IOCTL(LOOP_CTL_ADD, 0, TYPE_INT) IOCTL(LOOP_CTL_ADD, 0, TYPE_INT)
IOCTL(LOOP_CTL_REMOVE, 0, TYPE_INT) IOCTL(LOOP_CTL_REMOVE, 0, TYPE_INT)

View File

@ -96,6 +96,8 @@ struct loop_info64 {
#define LOOP_CHANGE_FD 0x4C06 #define LOOP_CHANGE_FD 0x4C06
#define LOOP_SET_CAPACITY 0x4C07 #define LOOP_SET_CAPACITY 0x4C07
#define LOOP_SET_DIRECT_IO 0x4C08 #define LOOP_SET_DIRECT_IO 0x4C08
#define LOOP_SET_BLOCK_SIZE 0x4C09
#define LOOP_CONFIGURE 0x4C0A
/* /dev/loop-control interface */ /* /dev/loop-control interface */
#define LOOP_CTL_ADD 0x4C80 #define LOOP_CTL_ADD 0x4C80

View File

@ -127,6 +127,9 @@
#ifdef HAVE_SAFE_SYSCALL #ifdef HAVE_SAFE_SYSCALL
/* The core part of this function is implemented in assembly */ /* The core part of this function is implemented in assembly */
extern long safe_syscall_base(int *pending, long number, ...); extern long safe_syscall_base(int *pending, long number, ...);
/* These are defined by the safe-syscall.inc.S file */
extern char safe_syscall_start[];
extern char safe_syscall_end[];
#define safe_syscall(...) \ #define safe_syscall(...) \
({ \ ({ \

View File

@ -31,6 +31,7 @@
#include "trace.h" #include "trace.h"
#include "signal-common.h" #include "signal-common.h"
#include "host-signal.h" #include "host-signal.h"
#include "safe-syscall.h"
static struct target_sigaction sigact_table[TARGET_NSIG]; static struct target_sigaction sigact_table[TARGET_NSIG];
@ -793,12 +794,20 @@ int queue_signal(CPUArchState *env, int sig, int si_type,
return 1; /* indicates that the signal was queued */ return 1; /* indicates that the signal was queued */
} }
#ifndef HAVE_SAFE_SYSCALL
/* Adjust the signal context to rewind out of safe-syscall if we're in it */
static inline void rewind_if_in_safe_syscall(void *puc) static inline void rewind_if_in_safe_syscall(void *puc)
{ {
/* Default version: never rewind */ #ifdef HAVE_SAFE_SYSCALL
ucontext_t *uc = (ucontext_t *)puc;
uintptr_t pcreg = host_signal_pc(uc);
if (pcreg > (uintptr_t)safe_syscall_start
&& pcreg < (uintptr_t)safe_syscall_end) {
host_signal_set_pc(uc, (uintptr_t)safe_syscall_start);
} }
#endif #endif
}
static void host_signal_handler(int host_sig, siginfo_t *info, void *puc) static void host_signal_handler(int host_sig, siginfo_t *info, void *puc)
{ {

View File

@ -197,8 +197,10 @@
//#define DEBUG_ERESTARTSYS //#define DEBUG_ERESTARTSYS
//#include <linux/msdos_fs.h> //#include <linux/msdos_fs.h>
#define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct linux_dirent [2]) #define VFAT_IOCTL_READDIR_BOTH \
#define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct linux_dirent [2]) _IOC(_IOC_READ, 'r', 1, (sizeof(struct linux_dirent) + 256) * 2)
#define VFAT_IOCTL_READDIR_SHORT \
_IOC(_IOC_READ, 'r', 2, (sizeof(struct linux_dirent) + 256) * 2)
#undef _syscall0 #undef _syscall0
#undef _syscall1 #undef _syscall1
@ -8154,6 +8156,159 @@ static int host_to_target_cpu_mask(const unsigned long *host_mask,
return 0; return 0;
} }
#ifdef TARGET_NR_getdents
static int do_getdents(abi_long dirfd, abi_long arg2, abi_long count)
{
g_autofree void *hdirp = NULL;
void *tdirp;
int hlen, hoff, toff;
int hreclen, treclen;
off64_t prev_diroff = 0;
hdirp = g_try_malloc(count);
if (!hdirp) {
return -TARGET_ENOMEM;
}
#ifdef EMULATE_GETDENTS_WITH_GETDENTS
hlen = sys_getdents(dirfd, hdirp, count);
#else
hlen = sys_getdents64(dirfd, hdirp, count);
#endif
hlen = get_errno(hlen);
if (is_error(hlen)) {
return hlen;
}
tdirp = lock_user(VERIFY_WRITE, arg2, count, 0);
if (!tdirp) {
return -TARGET_EFAULT;
}
for (hoff = toff = 0; hoff < hlen; hoff += hreclen, toff += treclen) {
#ifdef EMULATE_GETDENTS_WITH_GETDENTS
struct linux_dirent *hde = hdirp + hoff;
#else
struct linux_dirent64 *hde = hdirp + hoff;
#endif
struct target_dirent *tde = tdirp + toff;
int namelen;
uint8_t type;
namelen = strlen(hde->d_name);
hreclen = hde->d_reclen;
treclen = offsetof(struct target_dirent, d_name) + namelen + 2;
treclen = QEMU_ALIGN_UP(treclen, __alignof(struct target_dirent));
if (toff + treclen > count) {
/*
* If the host struct is smaller than the target struct, or
* requires less alignment and thus packs into less space,
* then the host can return more entries than we can pass
* on to the guest.
*/
if (toff == 0) {
toff = -TARGET_EINVAL; /* result buffer is too small */
break;
}
/*
* Return what we have, resetting the file pointer to the
* location of the first record not returned.
*/
lseek64(dirfd, prev_diroff, SEEK_SET);
break;
}
prev_diroff = hde->d_off;
tde->d_ino = tswapal(hde->d_ino);
tde->d_off = tswapal(hde->d_off);
tde->d_reclen = tswap16(treclen);
memcpy(tde->d_name, hde->d_name, namelen + 1);
/*
* The getdents type is in what was formerly a padding byte at the
* end of the structure.
*/
#ifdef EMULATE_GETDENTS_WITH_GETDENTS
type = *((uint8_t *)hde + hreclen - 1);
#else
type = hde->d_type;
#endif
*((uint8_t *)tde + treclen - 1) = type;
}
unlock_user(tdirp, arg2, toff);
return toff;
}
#endif /* TARGET_NR_getdents */
#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
static int do_getdents64(abi_long dirfd, abi_long arg2, abi_long count)
{
g_autofree void *hdirp = NULL;
void *tdirp;
int hlen, hoff, toff;
int hreclen, treclen;
off64_t prev_diroff = 0;
hdirp = g_try_malloc(count);
if (!hdirp) {
return -TARGET_ENOMEM;
}
hlen = get_errno(sys_getdents64(dirfd, hdirp, count));
if (is_error(hlen)) {
return hlen;
}
tdirp = lock_user(VERIFY_WRITE, arg2, count, 0);
if (!tdirp) {
return -TARGET_EFAULT;
}
for (hoff = toff = 0; hoff < hlen; hoff += hreclen, toff += treclen) {
struct linux_dirent64 *hde = hdirp + hoff;
struct target_dirent64 *tde = tdirp + toff;
int namelen;
namelen = strlen(hde->d_name) + 1;
hreclen = hde->d_reclen;
treclen = offsetof(struct target_dirent64, d_name) + namelen;
treclen = QEMU_ALIGN_UP(treclen, __alignof(struct target_dirent64));
if (toff + treclen > count) {
/*
* If the host struct is smaller than the target struct, or
* requires less alignment and thus packs into less space,
* then the host can return more entries than we can pass
* on to the guest.
*/
if (toff == 0) {
toff = -TARGET_EINVAL; /* result buffer is too small */
break;
}
/*
* Return what we have, resetting the file pointer to the
* location of the first record not returned.
*/
lseek64(dirfd, prev_diroff, SEEK_SET);
break;
}
prev_diroff = hde->d_off;
tde->d_ino = tswap64(hde->d_ino);
tde->d_off = tswap64(hde->d_off);
tde->d_reclen = tswap16(treclen);
tde->d_type = hde->d_type;
memcpy(tde->d_name, hde->d_name, namelen);
}
unlock_user(tdirp, arg2, toff);
return toff;
}
#endif /* TARGET_NR_getdents64 */
#if defined(TARGET_NR_pivot_root) && defined(__NR_pivot_root) #if defined(TARGET_NR_pivot_root) && defined(__NR_pivot_root)
_syscall2(int, pivot_root, const char *, new_root, const char *, put_old) _syscall2(int, pivot_root, const char *, new_root, const char *, put_old)
#endif #endif
@ -10244,162 +10399,11 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
#endif #endif
#ifdef TARGET_NR_getdents #ifdef TARGET_NR_getdents
case TARGET_NR_getdents: case TARGET_NR_getdents:
#ifdef EMULATE_GETDENTS_WITH_GETDENTS return do_getdents(arg1, arg2, arg3);
#if TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64
{
struct target_dirent *target_dirp;
struct linux_dirent *dirp;
abi_long count = arg3;
dirp = g_try_malloc(count);
if (!dirp) {
return -TARGET_ENOMEM;
}
ret = get_errno(sys_getdents(arg1, dirp, count));
if (!is_error(ret)) {
struct linux_dirent *de;
struct target_dirent *tde;
int len = ret;
int reclen, treclen;
int count1, tnamelen;
count1 = 0;
de = dirp;
if (!(target_dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
return -TARGET_EFAULT;
tde = target_dirp;
while (len > 0) {
reclen = de->d_reclen;
tnamelen = reclen - offsetof(struct linux_dirent, d_name);
assert(tnamelen >= 0);
treclen = tnamelen + offsetof(struct target_dirent, d_name);
assert(count1 + treclen <= count);
tde->d_reclen = tswap16(treclen);
tde->d_ino = tswapal(de->d_ino);
tde->d_off = tswapal(de->d_off);
memcpy(tde->d_name, de->d_name, tnamelen);
de = (struct linux_dirent *)((char *)de + reclen);
len -= reclen;
tde = (struct target_dirent *)((char *)tde + treclen);
count1 += treclen;
}
ret = count1;
unlock_user(target_dirp, arg2, ret);
}
g_free(dirp);
}
#else
{
struct linux_dirent *dirp;
abi_long count = arg3;
if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
return -TARGET_EFAULT;
ret = get_errno(sys_getdents(arg1, dirp, count));
if (!is_error(ret)) {
struct linux_dirent *de;
int len = ret;
int reclen;
de = dirp;
while (len > 0) {
reclen = de->d_reclen;
if (reclen > len)
break;
de->d_reclen = tswap16(reclen);
tswapls(&de->d_ino);
tswapls(&de->d_off);
de = (struct linux_dirent *)((char *)de + reclen);
len -= reclen;
}
}
unlock_user(dirp, arg2, ret);
}
#endif
#else
/* Implement getdents in terms of getdents64 */
{
struct linux_dirent64 *dirp;
abi_long count = arg3;
dirp = lock_user(VERIFY_WRITE, arg2, count, 0);
if (!dirp) {
return -TARGET_EFAULT;
}
ret = get_errno(sys_getdents64(arg1, dirp, count));
if (!is_error(ret)) {
/* Convert the dirent64 structs to target dirent. We do this
* in-place, since we can guarantee that a target_dirent is no
* larger than a dirent64; however this means we have to be
* careful to read everything before writing in the new format.
*/
struct linux_dirent64 *de;
struct target_dirent *tde;
int len = ret;
int tlen = 0;
de = dirp;
tde = (struct target_dirent *)dirp;
while (len > 0) {
int namelen, treclen;
int reclen = de->d_reclen;
uint64_t ino = de->d_ino;
int64_t off = de->d_off;
uint8_t type = de->d_type;
namelen = strlen(de->d_name);
treclen = offsetof(struct target_dirent, d_name)
+ namelen + 2;
treclen = QEMU_ALIGN_UP(treclen, sizeof(abi_long));
memmove(tde->d_name, de->d_name, namelen + 1);
tde->d_ino = tswapal(ino);
tde->d_off = tswapal(off);
tde->d_reclen = tswap16(treclen);
/* The target_dirent type is in what was formerly a padding
* byte at the end of the structure:
*/
*(((char *)tde) + treclen - 1) = type;
de = (struct linux_dirent64 *)((char *)de + reclen);
tde = (struct target_dirent *)((char *)tde + treclen);
len -= reclen;
tlen += treclen;
}
ret = tlen;
}
unlock_user(dirp, arg2, ret);
}
#endif
return ret;
#endif /* TARGET_NR_getdents */ #endif /* TARGET_NR_getdents */
#if defined(TARGET_NR_getdents64) && defined(__NR_getdents64) #if defined(TARGET_NR_getdents64) && defined(__NR_getdents64)
case TARGET_NR_getdents64: case TARGET_NR_getdents64:
{ return do_getdents64(arg1, arg2, arg3);
struct linux_dirent64 *dirp;
abi_long count = arg3;
if (!(dirp = lock_user(VERIFY_WRITE, arg2, count, 0)))
return -TARGET_EFAULT;
ret = get_errno(sys_getdents64(arg1, dirp, count));
if (!is_error(ret)) {
struct linux_dirent64 *de;
int len = ret;
int reclen;
de = dirp;
while (len > 0) {
reclen = de->d_reclen;
if (reclen > len)
break;
de->d_reclen = tswap16(reclen);
tswap64s((uint64_t *)&de->d_ino);
tswap64s((uint64_t *)&de->d_off);
de = (struct linux_dirent64 *)((char *)de + reclen);
len -= reclen;
}
}
unlock_user(dirp, arg2, ret);
}
return ret;
#endif /* TARGET_NR_getdents64 */ #endif /* TARGET_NR_getdents64 */
#if defined(TARGET_NR__newselect) #if defined(TARGET_NR__newselect)
case TARGET_NR__newselect: case TARGET_NR__newselect:

View File

@ -437,11 +437,11 @@ struct target_dirent {
}; };
struct target_dirent64 { struct target_dirent64 {
uint64_t d_ino; abi_ullong d_ino;
int64_t d_off; abi_llong d_off;
unsigned short d_reclen; abi_ushort d_reclen;
unsigned char d_type; unsigned char d_type;
char d_name[256]; char d_name[];
}; };
@ -1219,6 +1219,10 @@ struct target_rtc_pll_info {
#define TARGET_LOOP_SET_STATUS64 0x4C04 #define TARGET_LOOP_SET_STATUS64 0x4C04
#define TARGET_LOOP_GET_STATUS64 0x4C05 #define TARGET_LOOP_GET_STATUS64 0x4C05
#define TARGET_LOOP_CHANGE_FD 0x4C06 #define TARGET_LOOP_CHANGE_FD 0x4C06
#define TARGET_LOOP_SET_CAPACITY 0x4C07
#define TARGET_LOOP_SET_DIRECT_IO 0x4C08
#define TARGET_LOOP_SET_BLOCK_SIZE 0x4C09
#define TARGET_LOOP_CONFIGURE 0x4C0A
#define TARGET_LOOP_CTL_ADD 0x4C80 #define TARGET_LOOP_CTL_ADD 0x4C80
#define TARGET_LOOP_CTL_REMOVE 0x4C81 #define TARGET_LOOP_CTL_REMOVE 0x4C81
@ -2714,7 +2718,7 @@ struct linux_dirent {
long d_ino; long d_ino;
unsigned long d_off; unsigned long d_off;
unsigned short d_reclen; unsigned short d_reclen;
char d_name[256]; /* We must not include limits.h! */ char d_name[];
}; };
struct linux_dirent64 { struct linux_dirent64 {
@ -2722,7 +2726,7 @@ struct linux_dirent64 {
int64_t d_off; int64_t d_off;
unsigned short d_reclen; unsigned short d_reclen;
unsigned char d_type; unsigned char d_type;
char d_name[256]; char d_name[];
}; };
struct target_mq_attr { struct target_mq_attr {

View File

@ -201,6 +201,12 @@ STRUCT(loop_info64,
MK_ARRAY(TYPE_CHAR, 32), /* lo_encrypt_key */ MK_ARRAY(TYPE_CHAR, 32), /* lo_encrypt_key */
MK_ARRAY(TYPE_ULONGLONG, 2)) /* lo_init */ MK_ARRAY(TYPE_ULONGLONG, 2)) /* lo_init */
STRUCT(loop_config,
TYPE_INT, /* fd */
TYPE_INT, /* block_size */
MK_STRUCT(STRUCT_loop_info64), /* info */
MK_ARRAY(TYPE_ULONGLONG, 8)) /* __reserved */
/* mag tape ioctls */ /* mag tape ioctls */
STRUCT(mtop, TYPE_SHORT, TYPE_INT) STRUCT(mtop, TYPE_SHORT, TYPE_INT)
STRUCT(mtget, TYPE_LONG, TYPE_LONG, TYPE_LONG, TYPE_LONG, TYPE_LONG, STRUCT(mtget, TYPE_LONG, TYPE_LONG, TYPE_LONG, TYPE_LONG, TYPE_LONG,

View File

@ -329,9 +329,7 @@ if not get_option('hax').disabled()
endif endif
endif endif
if targetos == 'netbsd' if targetos == 'netbsd'
if cc.has_header_symbol('nvmm.h', 'nvmm_cpu_stop', required: get_option('nvmm'))
nvmm = cc.find_library('nvmm', required: get_option('nvmm')) nvmm = cc.find_library('nvmm', required: get_option('nvmm'))
endif
if nvmm.found() if nvmm.found()
accelerators += 'CONFIG_NVMM' accelerators += 'CONFIG_NVMM'
endif endif
@ -681,6 +679,9 @@ iconv = not_found
curses = not_found curses = not_found
if have_system and not get_option('curses').disabled() if have_system and not get_option('curses').disabled()
curses_test = ''' curses_test = '''
#if defined(__APPLE__) || defined(__OpenBSD__)
#define _XOPEN_SOURCE_EXTENDED 1
#endif
#include <locale.h> #include <locale.h>
#include <curses.h> #include <curses.h>
#include <wchar.h> #include <wchar.h>
@ -704,7 +705,7 @@ if have_system and not get_option('curses').disabled()
endif endif
endforeach endforeach
msg = get_option('curses').enabled() ? 'curses library not found' : '' msg = get_option('curses').enabled() ? 'curses library not found' : ''
curses_compile_args = ['-DNCURSES_WIDECHAR'] curses_compile_args = ['-DNCURSES_WIDECHAR=1']
if curses.found() if curses.found()
if cc.links(curses_test, args: curses_compile_args, dependencies: [curses]) if cc.links(curses_test, args: curses_compile_args, dependencies: [curses])
curses = declare_dependency(compile_args: curses_compile_args, dependencies: [curses]) curses = declare_dependency(compile_args: curses_compile_args, dependencies: [curses])
@ -1553,8 +1554,6 @@ config_host_data.set('CONFIG_INOTIFY',
cc.has_header_symbol('sys/inotify.h', 'inotify_init')) cc.has_header_symbol('sys/inotify.h', 'inotify_init'))
config_host_data.set('CONFIG_INOTIFY1', config_host_data.set('CONFIG_INOTIFY1',
cc.has_header_symbol('sys/inotify.h', 'inotify_init1')) cc.has_header_symbol('sys/inotify.h', 'inotify_init1'))
config_host_data.set('CONFIG_IOVEC',
cc.has_header_symbol('sys/uio.h', 'struct iovec'))
config_host_data.set('CONFIG_MACHINE_BSWAP_H', config_host_data.set('CONFIG_MACHINE_BSWAP_H',
cc.has_header_symbol('machine/bswap.h', 'bswap32', cc.has_header_symbol('machine/bswap.h', 'bswap32',
prefix: '''#include <sys/endian.h> prefix: '''#include <sys/endian.h>
@ -1567,8 +1566,6 @@ config_host_data.set('CONFIG_SYSMACROS',
cc.has_header_symbol('sys/sysmacros.h', 'makedev')) cc.has_header_symbol('sys/sysmacros.h', 'makedev'))
config_host_data.set('HAVE_OPTRESET', config_host_data.set('HAVE_OPTRESET',
cc.has_header_symbol('getopt.h', 'optreset')) cc.has_header_symbol('getopt.h', 'optreset'))
config_host_data.set('HAVE_UTMPX',
cc.has_header_symbol('utmpx.h', 'struct utmpx'))
config_host_data.set('HAVE_IPPROTO_MPTCP', config_host_data.set('HAVE_IPPROTO_MPTCP',
cc.has_header_symbol('netinet/in.h', 'IPPROTO_MPTCP')) cc.has_header_symbol('netinet/in.h', 'IPPROTO_MPTCP'))
@ -1580,6 +1577,14 @@ config_host_data.set('HAVE_STRUCT_STAT_ST_ATIM',
cc.has_member('struct stat', 'st_atim', cc.has_member('struct stat', 'st_atim',
prefix: '#include <sys/stat.h>')) prefix: '#include <sys/stat.h>'))
# has_type
config_host_data.set('CONFIG_IOVEC',
cc.has_type('struct iovec',
prefix: '#include <sys/uio.h>'))
config_host_data.set('HAVE_UTMPX',
cc.has_type('struct utmpx',
prefix: '#include <utmpx.h>'))
config_host_data.set('CONFIG_EVENTFD', cc.links(''' config_host_data.set('CONFIG_EVENTFD', cc.links('''
#include <sys/eventfd.h> #include <sys/eventfd.h>
int main(void) { return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); }''')) int main(void) { return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); }'''))
@ -1621,7 +1626,7 @@ config_host_data.set('CONFIG_POSIX_MADVISE', cc.links(gnu_source_prefix + '''
#include <stddef.h> #include <stddef.h>
int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }''')) int main(void) { return posix_madvise(NULL, 0, POSIX_MADV_DONTNEED); }'''))
config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_W_TID', cc.links(''' config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_W_TID', cc.links(gnu_source_prefix + '''
#include <pthread.h> #include <pthread.h>
static void *f(void *p) { return NULL; } static void *f(void *p) { return NULL; }
@ -1632,7 +1637,7 @@ config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_W_TID', cc.links('''
pthread_setname_np(thread, "QEMU"); pthread_setname_np(thread, "QEMU");
return 0; return 0;
}''', dependencies: threads)) }''', dependencies: threads))
config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_WO_TID', cc.links(''' config_host_data.set('CONFIG_PTHREAD_SETNAME_NP_WO_TID', cc.links(gnu_source_prefix + '''
#include <pthread.h> #include <pthread.h>
static void *f(void *p) { pthread_setname_np("QEMU"); return NULL; } static void *f(void *p) { pthread_setname_np("QEMU"); return NULL; }
@ -1668,8 +1673,10 @@ config_host_data.set('HAVE_MLOCKALL', cc.links(gnu_source_prefix + '''
have_l2tpv3 = false have_l2tpv3 = false
if not get_option('l2tpv3').disabled() and have_system if not get_option('l2tpv3').disabled() and have_system
have_l2tpv3 = (cc.has_header_symbol('sys/socket.h', 'struct mmsghdr') have_l2tpv3 = cc.has_type('struct mmsghdr',
and cc.has_header('linux/ip.h')) prefix: gnu_source_prefix + '''
#include <sys/socket.h>
#include <linux/ip.h>''')
endif endif
config_host_data.set('CONFIG_L2TPV3', have_l2tpv3) config_host_data.set('CONFIG_L2TPV3', have_l2tpv3)
@ -1695,7 +1702,7 @@ config_host_data.set('CONFIG_NETMAP', have_netmap)
# xfs headers will not try to redefine structs from linux headers # xfs headers will not try to redefine structs from linux headers
# if this macro is set. # if this macro is set.
config_host_data.set('HAVE_FSXATTR', cc.links(''' config_host_data.set('HAVE_FSXATTR', cc.links('''
#include <linux/fs.h>' #include <linux/fs.h>
struct fsxattr foo; struct fsxattr foo;
int main(void) { int main(void) {
return 0; return 0;

View File

@ -1418,6 +1418,9 @@ static int nbd_receive_request(NBDClient *client, NBDRequest *request,
if (ret < 0) { if (ret < 0) {
return ret; return ret;
} }
if (ret == 0) {
return -EIO;
}
/* Request /* Request
[ 0 .. 3] magic (NBD_REQUEST_MAGIC) [ 0 .. 3] magic (NBD_REQUEST_MAGIC)
@ -2506,16 +2509,8 @@ static coroutine_fn int nbd_handle_request(NBDClient *client,
if (request->flags & NBD_CMD_FLAG_FAST_ZERO) { if (request->flags & NBD_CMD_FLAG_FAST_ZERO) {
flags |= BDRV_REQ_NO_FALLBACK; flags |= BDRV_REQ_NO_FALLBACK;
} }
ret = 0; ret = blk_pwrite_zeroes(exp->common.blk, request->from, request->len,
/* FIXME simplify this when blk_pwrite_zeroes switches to 64-bit */ flags);
while (ret >= 0 && request->len) {
int align = client->check_align ?: 1;
int len = MIN(request->len, QEMU_ALIGN_DOWN(BDRV_REQUEST_MAX_BYTES,
align));
ret = blk_pwrite_zeroes(exp->common.blk, request->from, len, flags);
request->len -= len;
request->from += len;
}
return nbd_send_generic_reply(client, request->handle, ret, return nbd_send_generic_reply(client, request->handle, ret,
"writing to file failed", errp); "writing to file failed", errp);
@ -2529,16 +2524,7 @@ static coroutine_fn int nbd_handle_request(NBDClient *client,
"flush failed", errp); "flush failed", errp);
case NBD_CMD_TRIM: case NBD_CMD_TRIM:
ret = 0; ret = blk_co_pdiscard(exp->common.blk, request->from, request->len);
/* FIXME simplify this when blk_co_pdiscard switches to 64-bit */
while (ret >= 0 && request->len) {
int align = client->check_align ?: 1;
int len = MIN(request->len, QEMU_ALIGN_DOWN(BDRV_REQUEST_MAX_BYTES,
align));
ret = blk_co_pdiscard(exp->common.blk, request->from, len);
request->len -= len;
request->from += len;
}
if (ret >= 0 && request->flags & NBD_CMD_FLAG_FUA) { if (ret >= 0 && request->flags & NBD_CMD_FLAG_FUA) {
ret = blk_co_flush(exp->common.blk); ret = blk_co_flush(exp->common.blk);
} }

View File

@ -170,9 +170,17 @@ static bool vhost_vdpa_check_peer_type(NetClientState *nc, ObjectClass *oc,
return true; return true;
} }
/** Dummy receive in case qemu falls back to userland tap networking */
static ssize_t vhost_vdpa_receive(NetClientState *nc, const uint8_t *buf,
size_t size)
{
return 0;
}
static NetClientInfo net_vhost_vdpa_info = { static NetClientInfo net_vhost_vdpa_info = {
.type = NET_CLIENT_DRIVER_VHOST_VDPA, .type = NET_CLIENT_DRIVER_VHOST_VDPA,
.size = sizeof(VhostVDPAState), .size = sizeof(VhostVDPAState),
.receive = vhost_vdpa_receive,
.cleanup = vhost_vdpa_cleanup, .cleanup = vhost_vdpa_cleanup,
.has_vnet_hdr = vhost_vdpa_has_vnet_hdr, .has_vnet_hdr = vhost_vdpa_has_vnet_hdr,
.has_ufo = vhost_vdpa_has_ufo, .has_ufo = vhost_vdpa_has_ufo,

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More