Compare commits
133
Commits
v5.2.0-rc2
..
v5.2.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
553032db17 | ||
|
|
d73c46e4a8 | ||
|
|
8132122889 | ||
|
|
915976bd98 | ||
|
|
944fdc5e27 | ||
|
|
37c0c885d1 | ||
|
|
ea8208249d | ||
|
|
6cfdaa88cf | ||
|
|
24bdcc9608 | ||
|
|
92ea027017 | ||
|
|
8e84bf984a | ||
|
|
6fc5183a65 | ||
|
|
dd3d2340c4 | ||
|
|
1a6ab01d3f | ||
|
|
c0e0a9b131 | ||
|
|
cef64a0b34 | ||
|
|
28afbc1f11 | ||
|
|
82d469e139 | ||
|
|
558f5c42ef | ||
|
|
d536d9578e | ||
|
|
c8bf9a9169 | ||
|
|
9925990d01 | ||
|
|
f012bec890 | ||
|
|
d2abc563e4 | ||
|
|
ad6f932fe8 | ||
|
|
c2cb511634 | ||
|
|
afae37d98a | ||
|
|
23895cbd82 | ||
|
|
8e242b3cb4 | ||
|
|
bb0990d174 | ||
|
|
fb764373ea | ||
|
|
cf254988a5 | ||
|
|
272fa7491f | ||
|
|
683685e72d | ||
|
|
6ab64cc2a5 | ||
|
|
c6ff78563a | ||
|
|
773ee3f1ea | ||
|
|
0daf34fd3a | ||
|
|
e8eee8d3d9 | ||
|
|
7f0cff6e34 | ||
|
|
c5d7cfdaac | ||
|
|
71266bb4e9 | ||
|
|
392d8e95c7 | ||
|
|
4faf359acc | ||
|
|
acebed948c | ||
|
|
6951595183 | ||
|
|
75bf6e17f9 | ||
|
|
12bff81b4d | ||
|
|
d9f2ac3de9 | ||
|
|
155e1c82ed | ||
|
|
66278f8aeb | ||
|
|
9eeeb80ad4 | ||
|
|
c67d732c39 | ||
|
|
7170311674 | ||
|
|
de8ee7d47c | ||
|
|
6e84a91477 | ||
|
|
57bdec5c46 | ||
|
|
98554b3b56 | ||
|
|
98e8779770 | ||
|
|
534f80e1df | ||
|
|
1352d5688d | ||
|
|
8e9419b790 | ||
|
|
ac74e282d4 | ||
|
|
69272bec1a | ||
|
|
8c175c63ee | ||
|
|
e4b937d3c4 | ||
|
|
7a3d37a3f2 | ||
|
|
3d6519968b | ||
|
|
d8e5bbdd0d | ||
|
|
8cc30eb140 | ||
|
|
48e5c7f34c | ||
|
|
e3a232cccd | ||
|
|
7761e07c3f | ||
|
|
5983021eb6 | ||
|
|
6ca2aa5cfb | ||
|
|
88a8b27e55 | ||
|
|
7aed584ca6 | ||
|
|
f369797617 | ||
|
|
923e931188 | ||
|
|
7fbd7e7103 | ||
|
|
4b265c79a8 | ||
|
|
ff85db769f | ||
|
|
a4e2fff1b1 | ||
|
|
e67ad058e4 | ||
|
|
e2c6cd5674 | ||
|
|
3d275bd17c | ||
|
|
b696f2c6ba | ||
|
|
269ff671c5 | ||
|
|
c2aa8a3d7e | ||
|
|
3428455df9 | ||
|
|
8e26ae7bb5 | ||
|
|
2b37e9f843 | ||
|
|
6d24795ee7 | ||
|
|
29cf16db23 | ||
|
|
c6a89b45bd | ||
|
|
65baabca22 | ||
|
|
ca31e3072f | ||
|
|
dccdb0f82a | ||
|
|
ac9574bc87 | ||
|
|
933c8fe781 | ||
|
|
fc107d8684 | ||
|
|
f6b8104d0b | ||
|
|
4c946b2236 | ||
|
|
2817fbcee0 | ||
|
|
df058222e7 | ||
|
|
3d87c2d943 | ||
|
|
a4bc212add | ||
|
|
a0546a7b6f | ||
|
|
4b19e9b815 | ||
|
|
9e13d59884 | ||
|
|
f8fd3ebac3 | ||
|
|
2387aaced7 | ||
|
|
0aecd06049 | ||
|
|
a652a3ec69 | ||
|
|
c8228ac355 | ||
|
|
08d5406798 | ||
|
|
52b75ea8ec | ||
|
|
3c363c073e | ||
|
|
76a24781cc | ||
|
|
54248d4d73 | ||
|
|
dfa9c6c656 | ||
|
|
7a5f00dde3 | ||
|
|
1b539bd6db | ||
|
|
3214b0f094 | ||
|
|
6e1e9ff2d3 | ||
|
|
51e98b6d21 | ||
|
|
1c914cd120 | ||
|
|
15b2260bef | ||
|
|
58ad6ae0cb | ||
|
|
8526e39e99 | ||
|
|
dc0b4d94d4 | ||
|
|
e6ffd75782 | ||
|
|
f9b4908895 |
No files matched your search
+2
-1
@@ -18,6 +18,7 @@ freebsd_12_task:
|
||||
- gmake -j$(sysctl -n hw.ncpu) check V=1
|
||||
|
||||
macos_task:
|
||||
timeout_in: 90m
|
||||
osx_instance:
|
||||
image: catalina-base
|
||||
install_script:
|
||||
@@ -32,6 +33,7 @@ macos_task:
|
||||
- gmake check V=1
|
||||
|
||||
macos_xcode_task:
|
||||
timeout_in: 90m
|
||||
osx_instance:
|
||||
# this is an alias for the latest Xcode
|
||||
image: catalina-xcode
|
||||
@@ -85,7 +87,6 @@ windows_msys2_task:
|
||||
C:\tools\msys64\usr\bin\bash.exe -lc "pacman --noconfirm -S --needed \
|
||||
diffutils git grep make pkg-config sed \
|
||||
mingw-w64-x86_64-python \
|
||||
mingw-w64-x86_64-python-setuptools \
|
||||
mingw-w64-x86_64-toolchain \
|
||||
mingw-w64-x86_64-SDL2 \
|
||||
mingw-w64-x86_64-SDL2_image \
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
*.c.inc diff=c
|
||||
*.h.inc diff=c
|
||||
@@ -247,6 +247,15 @@ build-user:
|
||||
CONFIGURE_ARGS: --disable-tools --disable-system
|
||||
MAKE_CHECK_ARGS: check-tcg
|
||||
|
||||
# Only build the softmmu targets we have check-tcg tests for
|
||||
build-some-softmmu:
|
||||
<<: *native_build_job_definition
|
||||
variables:
|
||||
IMAGE: debian-all-test-cross
|
||||
CONFIGURE_ARGS: --disable-tools --enable-debug-tcg
|
||||
TARGETS: xtensa-softmmu arm-softmmu aarch64-softmmu alpha-softmmu
|
||||
MAKE_CHECK_ARGS: check-tcg
|
||||
|
||||
# Run check-tcg against linux-user (with plugins)
|
||||
# we skip sparc64-linux-user until it has been fixed somewhat
|
||||
# we skip cris-linux-user as it doesn't use the common run loop
|
||||
@@ -258,6 +267,14 @@ build-user-plugins:
|
||||
MAKE_CHECK_ARGS: check-tcg
|
||||
timeout: 1h 30m
|
||||
|
||||
build-some-softmmu-plugins:
|
||||
<<: *native_build_job_definition
|
||||
variables:
|
||||
IMAGE: debian-all-test-cross
|
||||
CONFIGURE_ARGS: --disable-tools --disable-user --enable-plugins --enable-debug-tcg
|
||||
TARGETS: xtensa-softmmu arm-softmmu aarch64-softmmu alpha-softmmu
|
||||
MAKE_CHECK_ARGS: check-tcg
|
||||
|
||||
build-clang:
|
||||
<<: *native_build_job_definition
|
||||
variables:
|
||||
@@ -398,6 +415,24 @@ check-crypto-only-gnutls:
|
||||
IMAGE: centos7
|
||||
MAKE_CHECK_ARGS: check
|
||||
|
||||
# We don't need to exercise every backend with every front-end
|
||||
build-trace-multi-user:
|
||||
<<: *native_build_job_definition
|
||||
variables:
|
||||
IMAGE: ubuntu2004
|
||||
CONFIGURE_ARGS: --enable-trace-backends=log,simple,syslog --disable-system
|
||||
|
||||
build-trace-ftrace-system:
|
||||
<<: *native_build_job_definition
|
||||
variables:
|
||||
IMAGE: ubuntu2004
|
||||
CONFIGURE_ARGS: --enable-trace-backends=ftrace --target-list=x86_64-softmmu
|
||||
|
||||
build-trace-ust-system:
|
||||
<<: *native_build_job_definition
|
||||
variables:
|
||||
IMAGE: ubuntu2004
|
||||
CONFIGURE_ARGS: --enable-trace-backends=ust --target-list=x86_64-softmmu
|
||||
|
||||
check-patch:
|
||||
stage: build
|
||||
|
||||
-45
@@ -232,25 +232,6 @@ jobs:
|
||||
- TEST_CMD=""
|
||||
|
||||
|
||||
# We don't need to exercise every backend with every front-end
|
||||
- name: "GCC trace log,simple,syslog (user)"
|
||||
env:
|
||||
- CONFIG="--enable-trace-backends=log,simple,syslog --disable-system"
|
||||
- TEST_CMD=""
|
||||
|
||||
|
||||
- name: "GCC trace ftrace (x86_64-softmmu)"
|
||||
env:
|
||||
- CONFIG="--enable-trace-backends=ftrace --target-list=x86_64-softmmu"
|
||||
- TEST_CMD=""
|
||||
|
||||
|
||||
- name: "GCC trace ust (x86_64-softmmu)"
|
||||
env:
|
||||
- CONFIG="--enable-trace-backends=ust --target-list=x86_64-softmmu"
|
||||
- TEST_CMD=""
|
||||
|
||||
|
||||
# Using newer GCC with sanitizers
|
||||
- name: "GCC9 with sanitizers (softmmu)"
|
||||
dist: bionic
|
||||
@@ -301,32 +282,6 @@ jobs:
|
||||
- ${SRC_DIR}/configure ${CONFIG} --extra-cflags="-g3 -O0 -fsanitize=thread" || { cat config.log meson-logs/meson-log.txt && exit 1; }
|
||||
|
||||
|
||||
# Run check-tcg against linux-user
|
||||
- name: "GCC check-tcg (user)"
|
||||
env:
|
||||
- CONFIG="--disable-system --enable-debug-tcg"
|
||||
- TEST_BUILD_CMD="make build-tcg"
|
||||
- TEST_CMD="make check-tcg"
|
||||
- CACHE_NAME="${TRAVIS_BRANCH}-linux-gcc-debug-tcg"
|
||||
|
||||
|
||||
# Run check-tcg against softmmu targets
|
||||
- name: "GCC check-tcg (some-softmmu)"
|
||||
env:
|
||||
- CONFIG="--enable-debug-tcg --target-list=xtensa-softmmu,arm-softmmu,aarch64-softmmu,alpha-softmmu"
|
||||
- TEST_BUILD_CMD="make build-tcg"
|
||||
- TEST_CMD="make check-tcg"
|
||||
- CACHE_NAME="${TRAVIS_BRANCH}-linux-gcc-debug-tcg"
|
||||
|
||||
|
||||
# Run check-tcg against softmmu targets (with plugins)
|
||||
- name: "GCC plugins check-tcg (some-softmmu)"
|
||||
env:
|
||||
- CONFIG="--enable-plugins --enable-debug-tcg --target-list=xtensa-softmmu,arm-softmmu,aarch64-softmmu,alpha-softmmu"
|
||||
- TEST_BUILD_CMD="make build-tcg"
|
||||
- TEST_CMD="make check-tcg"
|
||||
- CACHE_NAME="${TRAVIS_BRANCH}-linux-gcc-debug-tcg"
|
||||
|
||||
- name: "[aarch64] GCC check-tcg"
|
||||
arch: arm64
|
||||
dist: focal
|
||||
|
||||
+9
-1
@@ -158,6 +158,7 @@ F: disas/arm.c
|
||||
F: disas/arm-a64.cc
|
||||
F: disas/libvixl/
|
||||
F: docs/system/target-arm.rst
|
||||
F: docs/system/arm/cpu-features.rst
|
||||
|
||||
ARM SMMU
|
||||
M: Eric Auger <eric.auger@redhat.com>
|
||||
@@ -558,7 +559,7 @@ S: Maintained
|
||||
F: hw/*/allwinner-h3*
|
||||
F: include/hw/*/allwinner-h3*
|
||||
F: hw/arm/orangepi.c
|
||||
F: docs/system/orangepi.rst
|
||||
F: docs/system/arm/orangepi.rst
|
||||
|
||||
ARM PrimeCell and CMSDK devices
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
@@ -762,6 +763,7 @@ F: include/hw/*/npcm7xx*
|
||||
F: tests/qtest/npcm7xx*
|
||||
F: pc-bios/npcm7xx_bootrom.bin
|
||||
F: roms/vbootrom
|
||||
F: docs/system/arm/nuvoton.rst
|
||||
|
||||
nSeries
|
||||
M: Andrzej Zaborowski <balrogg@gmail.com>
|
||||
@@ -801,6 +803,7 @@ F: hw/arm/raspi_platform.h
|
||||
F: hw/*/bcm283*
|
||||
F: include/hw/arm/raspi*
|
||||
F: include/hw/*/bcm283*
|
||||
F: docs/system/arm/raspi.rst
|
||||
|
||||
Real View
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
@@ -855,6 +858,7 @@ R: Leif Lindholm <leif@nuviainc.com>
|
||||
L: qemu-arm@nongnu.org
|
||||
S: Maintained
|
||||
F: hw/arm/sbsa-ref.c
|
||||
F: docs/system/arm/sbsa.rst
|
||||
|
||||
Sharp SL-5500 (Collie) PDA
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
@@ -999,6 +1003,7 @@ F: include/hw/*/*aspeed*
|
||||
F: include/hw/misc/pca9552*.h
|
||||
F: hw/net/ftgmac100.c
|
||||
F: include/hw/net/ftgmac100.h
|
||||
F: docs/system/arm/aspeed.rst
|
||||
|
||||
NRF51
|
||||
M: Joel Stanley <joel@jms.id.au>
|
||||
@@ -1603,6 +1608,7 @@ L: qemu-arm@nongnu.org
|
||||
S: Maintained
|
||||
F: hw/*/omap*
|
||||
F: include/hw/arm/omap.h
|
||||
F: docs/system/arm/sx1.rst
|
||||
|
||||
IPack
|
||||
M: Alberto Garcia <berto@igalia.com>
|
||||
@@ -1882,6 +1888,7 @@ M: Klaus Jensen <its@irrelevant.dk>
|
||||
L: qemu-block@nongnu.org
|
||||
S: Supported
|
||||
F: hw/block/nvme*
|
||||
F: include/block/nvme.h
|
||||
F: tests/qtest/nvme-test.c
|
||||
F: docs/specs/nvme.txt
|
||||
T: git git://git.infradead.org/qemu-nvme.git nvme-next
|
||||
@@ -2972,6 +2979,7 @@ R: Fam Zheng <fam@euphon.net>
|
||||
L: qemu-block@nongnu.org
|
||||
S: Supported
|
||||
F: block/nvme*
|
||||
F: include/block/nvme.h
|
||||
T: git https://github.com/stefanha/qemu.git block
|
||||
|
||||
Bootdevice
|
||||
|
||||
+4
-2
@@ -2239,8 +2239,10 @@ static int kvm_init(MachineState *ms)
|
||||
|
||||
kvm_memory_listener_register(s, &s->memory_listener,
|
||||
&address_space_memory, 0);
|
||||
memory_listener_register(&kvm_io_listener,
|
||||
&address_space_io);
|
||||
if (kvm_eventfds_allowed) {
|
||||
memory_listener_register(&kvm_io_listener,
|
||||
&address_space_io);
|
||||
}
|
||||
memory_listener_register(&kvm_coalesced_pio_listener,
|
||||
&address_space_io);
|
||||
|
||||
|
||||
+5
-1
@@ -73,7 +73,8 @@ qauthz_list_file_load(QAuthZListFile *fauthz, Error **errp)
|
||||
|
||||
pdict = qobject_to(QDict, obj);
|
||||
if (!pdict) {
|
||||
error_setg(errp, QERR_INVALID_PARAMETER_TYPE, "obj", "dict");
|
||||
error_setg(errp, "File '%s' must contain a JSON object",
|
||||
fauthz->filename);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
@@ -128,6 +129,9 @@ qauthz_list_file_complete(UserCreatable *uc, Error **errp)
|
||||
}
|
||||
|
||||
fauthz->list = qauthz_list_file_load(fauthz, errp);
|
||||
if (!fauthz->list) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!fauthz->refresh) {
|
||||
return;
|
||||
|
||||
@@ -84,6 +84,12 @@ qauthz_pam_prop_get_service(Object *obj,
|
||||
static void
|
||||
qauthz_pam_complete(UserCreatable *uc, Error **errp)
|
||||
{
|
||||
QAuthZPAM *pauthz = QAUTHZ_PAM(uc);
|
||||
|
||||
if (!pauthz->service) {
|
||||
error_setg(errp, "The 'service' property must be set");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -65,11 +65,25 @@ qauthz_simple_finalize(Object *obj)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
qauthz_simple_complete(UserCreatable *uc, Error **errp)
|
||||
{
|
||||
QAuthZSimple *sauthz = QAUTHZ_SIMPLE(uc);
|
||||
|
||||
if (!sauthz->identity) {
|
||||
error_setg(errp, "The 'identity' property must be set");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
qauthz_simple_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
QAuthZClass *authz = QAUTHZ_CLASS(oc);
|
||||
UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
|
||||
|
||||
ucc->complete = qauthz_simple_complete;
|
||||
authz->is_allowed = qauthz_simple_is_allowed;
|
||||
|
||||
object_class_property_add_str(oc, "identity",
|
||||
|
||||
+117
-92
@@ -41,6 +41,16 @@
|
||||
|
||||
typedef struct BDRVNVMeState BDRVNVMeState;
|
||||
|
||||
/* Same index is used for queues and IRQs */
|
||||
#define INDEX_ADMIN 0
|
||||
#define INDEX_IO(n) (1 + n)
|
||||
|
||||
/* This driver shares a single MSIX IRQ for the admin and I/O queues */
|
||||
enum {
|
||||
MSIX_SHARED_IRQ_IDX = 0,
|
||||
MSIX_IRQ_COUNT = 1
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
int32_t head, tail;
|
||||
uint8_t *queue;
|
||||
@@ -81,18 +91,10 @@ typedef struct {
|
||||
QEMUBH *completion_bh;
|
||||
} NVMeQueuePair;
|
||||
|
||||
#define INDEX_ADMIN 0
|
||||
#define INDEX_IO(n) (1 + n)
|
||||
|
||||
/* This driver shares a single MSIX IRQ for the admin and I/O queues */
|
||||
enum {
|
||||
MSIX_SHARED_IRQ_IDX = 0,
|
||||
MSIX_IRQ_COUNT = 1
|
||||
};
|
||||
|
||||
struct BDRVNVMeState {
|
||||
AioContext *aio_context;
|
||||
QEMUVFIOState *vfio;
|
||||
void *bar0_wo_map;
|
||||
/* Memory mapped registers */
|
||||
volatile struct {
|
||||
uint32_t sq_tail;
|
||||
@@ -103,7 +105,7 @@ struct BDRVNVMeState {
|
||||
* [1..]: io queues.
|
||||
*/
|
||||
NVMeQueuePair **queues;
|
||||
int nr_queues;
|
||||
unsigned queue_count;
|
||||
size_t page_size;
|
||||
/* How many uint32_t elements does each doorbell entry take. */
|
||||
size_t doorbell_scale;
|
||||
@@ -159,28 +161,32 @@ static QemuOptsList runtime_opts = {
|
||||
},
|
||||
};
|
||||
|
||||
static void nvme_init_queue(BDRVNVMeState *s, NVMeQueue *q,
|
||||
int nentries, int entry_bytes, Error **errp)
|
||||
/* Returns true on success, false on failure. */
|
||||
static bool nvme_init_queue(BDRVNVMeState *s, NVMeQueue *q,
|
||||
unsigned nentries, size_t entry_bytes, Error **errp)
|
||||
{
|
||||
size_t bytes;
|
||||
int r;
|
||||
|
||||
bytes = ROUND_UP(nentries * entry_bytes, s->page_size);
|
||||
bytes = ROUND_UP(nentries * entry_bytes, qemu_real_host_page_size);
|
||||
q->head = q->tail = 0;
|
||||
q->queue = qemu_try_memalign(s->page_size, bytes);
|
||||
q->queue = qemu_try_memalign(qemu_real_host_page_size, bytes);
|
||||
if (!q->queue) {
|
||||
error_setg(errp, "Cannot allocate queue");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
memset(q->queue, 0, bytes);
|
||||
r = qemu_vfio_dma_map(s->vfio, q->queue, bytes, false, &q->iova);
|
||||
if (r) {
|
||||
error_setg(errp, "Cannot map queue");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void nvme_free_queue_pair(NVMeQueuePair *q)
|
||||
{
|
||||
trace_nvme_free_queue_pair(q->index, q);
|
||||
if (q->completion_bh) {
|
||||
qemu_bh_delete(q->completion_bh);
|
||||
}
|
||||
@@ -204,31 +210,33 @@ static void nvme_free_req_queue_cb(void *opaque)
|
||||
|
||||
static NVMeQueuePair *nvme_create_queue_pair(BDRVNVMeState *s,
|
||||
AioContext *aio_context,
|
||||
int idx, int size,
|
||||
unsigned idx, size_t size,
|
||||
Error **errp)
|
||||
{
|
||||
int i, r;
|
||||
Error *local_err = NULL;
|
||||
NVMeQueuePair *q;
|
||||
uint64_t prp_list_iova;
|
||||
size_t bytes;
|
||||
|
||||
q = g_try_new0(NVMeQueuePair, 1);
|
||||
if (!q) {
|
||||
return NULL;
|
||||
}
|
||||
q->prp_list_pages = qemu_try_memalign(s->page_size,
|
||||
s->page_size * NVME_NUM_REQS);
|
||||
trace_nvme_create_queue_pair(idx, q, size, aio_context,
|
||||
event_notifier_get_fd(s->irq_notifier));
|
||||
bytes = QEMU_ALIGN_UP(s->page_size * NVME_NUM_REQS,
|
||||
qemu_real_host_page_size);
|
||||
q->prp_list_pages = qemu_try_memalign(qemu_real_host_page_size, bytes);
|
||||
if (!q->prp_list_pages) {
|
||||
goto fail;
|
||||
}
|
||||
memset(q->prp_list_pages, 0, s->page_size * NVME_NUM_REQS);
|
||||
memset(q->prp_list_pages, 0, bytes);
|
||||
qemu_mutex_init(&q->lock);
|
||||
q->s = s;
|
||||
q->index = idx;
|
||||
qemu_co_queue_init(&q->free_req_queue);
|
||||
q->completion_bh = aio_bh_new(aio_context, nvme_process_completion_bh, q);
|
||||
r = qemu_vfio_dma_map(s->vfio, q->prp_list_pages,
|
||||
s->page_size * NVME_NUM_REQS,
|
||||
r = qemu_vfio_dma_map(s->vfio, q->prp_list_pages, bytes,
|
||||
false, &prp_list_iova);
|
||||
if (r) {
|
||||
goto fail;
|
||||
@@ -243,16 +251,12 @@ static NVMeQueuePair *nvme_create_queue_pair(BDRVNVMeState *s,
|
||||
req->prp_list_iova = prp_list_iova + i * s->page_size;
|
||||
}
|
||||
|
||||
nvme_init_queue(s, &q->sq, size, NVME_SQ_ENTRY_BYTES, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
if (!nvme_init_queue(s, &q->sq, size, NVME_SQ_ENTRY_BYTES, errp)) {
|
||||
goto fail;
|
||||
}
|
||||
q->sq.doorbell = &s->doorbells[idx * s->doorbell_scale].sq_tail;
|
||||
|
||||
nvme_init_queue(s, &q->cq, size, NVME_CQ_ENTRY_BYTES, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
if (!nvme_init_queue(s, &q->cq, size, NVME_CQ_ENTRY_BYTES, errp)) {
|
||||
goto fail;
|
||||
}
|
||||
q->cq.doorbell = &s->doorbells[idx * s->doorbell_scale].cq_head;
|
||||
@@ -292,7 +296,7 @@ static NVMeRequest *nvme_get_free_req(NVMeQueuePair *q)
|
||||
|
||||
while (q->free_req_head == -1) {
|
||||
if (qemu_in_coroutine()) {
|
||||
trace_nvme_free_req_queue_wait(q);
|
||||
trace_nvme_free_req_queue_wait(q->s, q->index);
|
||||
qemu_co_queue_wait(&q->free_req_queue, &q->lock);
|
||||
} else {
|
||||
qemu_mutex_unlock(&q->lock);
|
||||
@@ -399,8 +403,8 @@ static bool nvme_process_completion(NVMeQueuePair *q)
|
||||
}
|
||||
cid = le16_to_cpu(c->cid);
|
||||
if (cid == 0 || cid > NVME_QUEUE_SIZE) {
|
||||
fprintf(stderr, "Unexpected CID in completion queue: %" PRIu32 "\n",
|
||||
cid);
|
||||
warn_report("NVMe: Unexpected CID in completion queue: %"PRIu32", "
|
||||
"queue size: %u", cid, NVME_QUEUE_SIZE);
|
||||
continue;
|
||||
}
|
||||
trace_nvme_complete_command(s, q->index, cid);
|
||||
@@ -465,7 +469,7 @@ static void nvme_submit_command(NVMeQueuePair *q, NVMeRequest *req,
|
||||
assert(!req->cb);
|
||||
req->cb = cb;
|
||||
req->opaque = opaque;
|
||||
cmd->cid = cpu_to_le32(req->cid);
|
||||
cmd->cid = cpu_to_le16(req->cid);
|
||||
|
||||
trace_nvme_submit_command(q->s, q->index, req->cid);
|
||||
nvme_trace_command(cmd);
|
||||
@@ -479,16 +483,17 @@ static void nvme_submit_command(NVMeQueuePair *q, NVMeRequest *req,
|
||||
qemu_mutex_unlock(&q->lock);
|
||||
}
|
||||
|
||||
static void nvme_cmd_sync_cb(void *opaque, int ret)
|
||||
static void nvme_admin_cmd_sync_cb(void *opaque, int ret)
|
||||
{
|
||||
int *pret = opaque;
|
||||
*pret = ret;
|
||||
aio_wait_kick();
|
||||
}
|
||||
|
||||
static int nvme_cmd_sync(BlockDriverState *bs, NVMeQueuePair *q,
|
||||
NvmeCmd *cmd)
|
||||
static int nvme_admin_cmd_sync(BlockDriverState *bs, NvmeCmd *cmd)
|
||||
{
|
||||
BDRVNVMeState *s = bs->opaque;
|
||||
NVMeQueuePair *q = s->queues[INDEX_ADMIN];
|
||||
AioContext *aio_context = bdrv_get_aio_context(bs);
|
||||
NVMeRequest *req;
|
||||
int ret = -EINPROGRESS;
|
||||
@@ -496,15 +501,17 @@ static int nvme_cmd_sync(BlockDriverState *bs, NVMeQueuePair *q,
|
||||
if (!req) {
|
||||
return -EBUSY;
|
||||
}
|
||||
nvme_submit_command(q, req, cmd, nvme_cmd_sync_cb, &ret);
|
||||
nvme_submit_command(q, req, cmd, nvme_admin_cmd_sync_cb, &ret);
|
||||
|
||||
AIO_WAIT_WHILE(aio_context, ret == -EINPROGRESS);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void nvme_identify(BlockDriverState *bs, int namespace, Error **errp)
|
||||
/* Returns true on success, false on failure. */
|
||||
static bool nvme_identify(BlockDriverState *bs, int namespace, Error **errp)
|
||||
{
|
||||
BDRVNVMeState *s = bs->opaque;
|
||||
bool ret = false;
|
||||
union {
|
||||
NvmeIdCtrl ctrl;
|
||||
NvmeIdNs ns;
|
||||
@@ -517,21 +524,22 @@ static void nvme_identify(BlockDriverState *bs, int namespace, Error **errp)
|
||||
.opcode = NVME_ADM_CMD_IDENTIFY,
|
||||
.cdw10 = cpu_to_le32(0x1),
|
||||
};
|
||||
size_t id_size = QEMU_ALIGN_UP(sizeof(*id), qemu_real_host_page_size);
|
||||
|
||||
id = qemu_try_memalign(s->page_size, sizeof(*id));
|
||||
id = qemu_try_memalign(qemu_real_host_page_size, id_size);
|
||||
if (!id) {
|
||||
error_setg(errp, "Cannot allocate buffer for identify response");
|
||||
goto out;
|
||||
}
|
||||
r = qemu_vfio_dma_map(s->vfio, id, sizeof(*id), true, &iova);
|
||||
r = qemu_vfio_dma_map(s->vfio, id, id_size, true, &iova);
|
||||
if (r) {
|
||||
error_setg(errp, "Cannot map buffer for DMA");
|
||||
goto out;
|
||||
}
|
||||
|
||||
memset(id, 0, sizeof(*id));
|
||||
memset(id, 0, id_size);
|
||||
cmd.dptr.prp1 = cpu_to_le64(iova);
|
||||
if (nvme_cmd_sync(bs, s->queues[INDEX_ADMIN], &cmd)) {
|
||||
if (nvme_admin_cmd_sync(bs, &cmd)) {
|
||||
error_setg(errp, "Failed to identify controller");
|
||||
goto out;
|
||||
}
|
||||
@@ -551,10 +559,10 @@ static void nvme_identify(BlockDriverState *bs, int namespace, Error **errp)
|
||||
s->supports_write_zeroes = !!(oncs & NVME_ONCS_WRITE_ZEROES);
|
||||
s->supports_discard = !!(oncs & NVME_ONCS_DSM);
|
||||
|
||||
memset(id, 0, sizeof(*id));
|
||||
memset(id, 0, id_size);
|
||||
cmd.cdw10 = 0;
|
||||
cmd.nsid = cpu_to_le32(namespace);
|
||||
if (nvme_cmd_sync(bs, s->queues[INDEX_ADMIN], &cmd)) {
|
||||
if (nvme_admin_cmd_sync(bs, &cmd)) {
|
||||
error_setg(errp, "Failed to identify namespace");
|
||||
goto out;
|
||||
}
|
||||
@@ -581,10 +589,13 @@ static void nvme_identify(BlockDriverState *bs, int namespace, Error **errp)
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = true;
|
||||
s->blkshift = lbaf->ds;
|
||||
out:
|
||||
qemu_vfio_dma_unmap(s->vfio, id);
|
||||
qemu_vfree(id);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool nvme_poll_queue(NVMeQueuePair *q)
|
||||
@@ -594,6 +605,7 @@ static bool nvme_poll_queue(NVMeQueuePair *q)
|
||||
const size_t cqe_offset = q->cq.head * NVME_CQ_ENTRY_BYTES;
|
||||
NvmeCqe *cqe = (NvmeCqe *)&q->cq.queue[cqe_offset];
|
||||
|
||||
trace_nvme_poll_queue(q->s, q->index);
|
||||
/*
|
||||
* Do an early check for completions. q->lock isn't needed because
|
||||
* nvme_process_completion() only runs in the event loop thread and
|
||||
@@ -618,7 +630,7 @@ static bool nvme_poll_queues(BDRVNVMeState *s)
|
||||
bool progress = false;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < s->nr_queues; i++) {
|
||||
for (i = 0; i < s->queue_count; i++) {
|
||||
if (nvme_poll_queue(s->queues[i])) {
|
||||
progress = true;
|
||||
}
|
||||
@@ -639,11 +651,12 @@ static void nvme_handle_event(EventNotifier *n)
|
||||
static bool nvme_add_io_queue(BlockDriverState *bs, Error **errp)
|
||||
{
|
||||
BDRVNVMeState *s = bs->opaque;
|
||||
int n = s->nr_queues;
|
||||
unsigned n = s->queue_count;
|
||||
NVMeQueuePair *q;
|
||||
NvmeCmd cmd;
|
||||
int queue_size = NVME_QUEUE_SIZE;
|
||||
unsigned queue_size = NVME_QUEUE_SIZE;
|
||||
|
||||
assert(n <= UINT16_MAX);
|
||||
q = nvme_create_queue_pair(s, bdrv_get_aio_context(bs),
|
||||
n, queue_size, errp);
|
||||
if (!q) {
|
||||
@@ -652,26 +665,26 @@ static bool nvme_add_io_queue(BlockDriverState *bs, Error **errp)
|
||||
cmd = (NvmeCmd) {
|
||||
.opcode = NVME_ADM_CMD_CREATE_CQ,
|
||||
.dptr.prp1 = cpu_to_le64(q->cq.iova),
|
||||
.cdw10 = cpu_to_le32(((queue_size - 1) << 16) | (n & 0xFFFF)),
|
||||
.cdw11 = cpu_to_le32(0x3),
|
||||
.cdw10 = cpu_to_le32(((queue_size - 1) << 16) | n),
|
||||
.cdw11 = cpu_to_le32(NVME_CQ_IEN | NVME_CQ_PC),
|
||||
};
|
||||
if (nvme_cmd_sync(bs, s->queues[INDEX_ADMIN], &cmd)) {
|
||||
error_setg(errp, "Failed to create CQ io queue [%d]", n);
|
||||
if (nvme_admin_cmd_sync(bs, &cmd)) {
|
||||
error_setg(errp, "Failed to create CQ io queue [%u]", n);
|
||||
goto out_error;
|
||||
}
|
||||
cmd = (NvmeCmd) {
|
||||
.opcode = NVME_ADM_CMD_CREATE_SQ,
|
||||
.dptr.prp1 = cpu_to_le64(q->sq.iova),
|
||||
.cdw10 = cpu_to_le32(((queue_size - 1) << 16) | (n & 0xFFFF)),
|
||||
.cdw11 = cpu_to_le32(0x1 | (n << 16)),
|
||||
.cdw10 = cpu_to_le32(((queue_size - 1) << 16) | n),
|
||||
.cdw11 = cpu_to_le32(NVME_SQ_PC | (n << 16)),
|
||||
};
|
||||
if (nvme_cmd_sync(bs, s->queues[INDEX_ADMIN], &cmd)) {
|
||||
error_setg(errp, "Failed to create SQ io queue [%d]", n);
|
||||
if (nvme_admin_cmd_sync(bs, &cmd)) {
|
||||
error_setg(errp, "Failed to create SQ io queue [%u]", n);
|
||||
goto out_error;
|
||||
}
|
||||
s->queues = g_renew(NVMeQueuePair *, s->queues, n + 1);
|
||||
s->queues[n] = q;
|
||||
s->nr_queues++;
|
||||
s->queue_count++;
|
||||
return true;
|
||||
out_error:
|
||||
nvme_free_queue_pair(q);
|
||||
@@ -684,7 +697,6 @@ static bool nvme_poll_cb(void *opaque)
|
||||
BDRVNVMeState *s = container_of(e, BDRVNVMeState,
|
||||
irq_notifier[MSIX_SHARED_IRQ_IDX]);
|
||||
|
||||
trace_nvme_poll_cb(s);
|
||||
return nvme_poll_queues(s);
|
||||
}
|
||||
|
||||
@@ -692,12 +704,12 @@ static int nvme_init(BlockDriverState *bs, const char *device, int namespace,
|
||||
Error **errp)
|
||||
{
|
||||
BDRVNVMeState *s = bs->opaque;
|
||||
NVMeQueuePair *q;
|
||||
AioContext *aio_context = bdrv_get_aio_context(bs);
|
||||
int ret;
|
||||
uint64_t cap;
|
||||
uint64_t timeout_ms;
|
||||
uint64_t deadline, now;
|
||||
Error *local_err = NULL;
|
||||
volatile NvmeBar *regs = NULL;
|
||||
|
||||
qemu_co_mutex_init(&s->dma_map_lock);
|
||||
@@ -727,15 +739,29 @@ static int nvme_init(BlockDriverState *bs, const char *device, int namespace,
|
||||
* Initialization". */
|
||||
|
||||
cap = le64_to_cpu(regs->cap);
|
||||
trace_nvme_controller_capability_raw(cap);
|
||||
trace_nvme_controller_capability("Maximum Queue Entries Supported",
|
||||
1 + NVME_CAP_MQES(cap));
|
||||
trace_nvme_controller_capability("Contiguous Queues Required",
|
||||
NVME_CAP_CQR(cap));
|
||||
trace_nvme_controller_capability("Doorbell Stride",
|
||||
2 << (2 + NVME_CAP_DSTRD(cap)));
|
||||
trace_nvme_controller_capability("Subsystem Reset Supported",
|
||||
NVME_CAP_NSSRS(cap));
|
||||
trace_nvme_controller_capability("Memory Page Size Minimum",
|
||||
1 << (12 + NVME_CAP_MPSMIN(cap)));
|
||||
trace_nvme_controller_capability("Memory Page Size Maximum",
|
||||
1 << (12 + NVME_CAP_MPSMAX(cap)));
|
||||
if (!NVME_CAP_CSS(cap)) {
|
||||
error_setg(errp, "Device doesn't support NVMe command set");
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
s->page_size = MAX(4096, 1 << NVME_CAP_MPSMIN(cap));
|
||||
s->page_size = 1u << (12 + NVME_CAP_MPSMIN(cap));
|
||||
s->doorbell_scale = (4 << NVME_CAP_DSTRD(cap)) / sizeof(uint32_t);
|
||||
bs->bl.opt_mem_alignment = s->page_size;
|
||||
bs->bl.request_alignment = s->page_size;
|
||||
timeout_ms = MIN(500 * NVME_CAP_TO(cap), 30000);
|
||||
|
||||
/* Reset device to get a clean state. */
|
||||
@@ -752,8 +778,10 @@ static int nvme_init(BlockDriverState *bs, const char *device, int namespace,
|
||||
}
|
||||
}
|
||||
|
||||
s->doorbells = qemu_vfio_pci_map_bar(s->vfio, 0, sizeof(NvmeBar),
|
||||
NVME_DOORBELL_SIZE, PROT_WRITE, errp);
|
||||
s->bar0_wo_map = qemu_vfio_pci_map_bar(s->vfio, 0, 0,
|
||||
sizeof(NvmeBar) + NVME_DOORBELL_SIZE,
|
||||
PROT_WRITE, errp);
|
||||
s->doorbells = (void *)((uintptr_t)s->bar0_wo_map + sizeof(NvmeBar));
|
||||
if (!s->doorbells) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
@@ -761,19 +789,18 @@ static int nvme_init(BlockDriverState *bs, const char *device, int namespace,
|
||||
|
||||
/* Set up admin queue. */
|
||||
s->queues = g_new(NVMeQueuePair *, 1);
|
||||
s->queues[INDEX_ADMIN] = nvme_create_queue_pair(s, aio_context, 0,
|
||||
NVME_QUEUE_SIZE,
|
||||
errp);
|
||||
if (!s->queues[INDEX_ADMIN]) {
|
||||
q = nvme_create_queue_pair(s, aio_context, 0, NVME_QUEUE_SIZE, errp);
|
||||
if (!q) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
s->nr_queues = 1;
|
||||
QEMU_BUILD_BUG_ON(NVME_QUEUE_SIZE & 0xF000);
|
||||
regs->aqa = cpu_to_le32((NVME_QUEUE_SIZE << AQA_ACQS_SHIFT) |
|
||||
(NVME_QUEUE_SIZE << AQA_ASQS_SHIFT));
|
||||
regs->asq = cpu_to_le64(s->queues[INDEX_ADMIN]->sq.iova);
|
||||
regs->acq = cpu_to_le64(s->queues[INDEX_ADMIN]->cq.iova);
|
||||
s->queues[INDEX_ADMIN] = q;
|
||||
s->queue_count = 1;
|
||||
QEMU_BUILD_BUG_ON((NVME_QUEUE_SIZE - 1) & 0xF000);
|
||||
regs->aqa = cpu_to_le32(((NVME_QUEUE_SIZE - 1) << AQA_ACQS_SHIFT) |
|
||||
((NVME_QUEUE_SIZE - 1) << AQA_ASQS_SHIFT));
|
||||
regs->asq = cpu_to_le64(q->sq.iova);
|
||||
regs->acq = cpu_to_le64(q->cq.iova);
|
||||
|
||||
/* After setting up all control registers we can enable device now. */
|
||||
regs->cc = cpu_to_le32((ctz32(NVME_CQ_ENTRY_BYTES) << CC_IOCQES_SHIFT) |
|
||||
@@ -801,9 +828,7 @@ static int nvme_init(BlockDriverState *bs, const char *device, int namespace,
|
||||
&s->irq_notifier[MSIX_SHARED_IRQ_IDX],
|
||||
false, nvme_handle_event, nvme_poll_cb);
|
||||
|
||||
nvme_identify(bs, namespace, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
if (!nvme_identify(bs, namespace, errp)) {
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
@@ -869,7 +894,7 @@ static int nvme_enable_disable_write_cache(BlockDriverState *bs, bool enable,
|
||||
.cdw11 = cpu_to_le32(enable ? 0x01 : 0x00),
|
||||
};
|
||||
|
||||
ret = nvme_cmd_sync(bs, s->queues[INDEX_ADMIN], &cmd);
|
||||
ret = nvme_admin_cmd_sync(bs, &cmd);
|
||||
if (ret) {
|
||||
error_setg(errp, "Failed to configure NVMe write cache");
|
||||
}
|
||||
@@ -878,10 +903,9 @@ static int nvme_enable_disable_write_cache(BlockDriverState *bs, bool enable,
|
||||
|
||||
static void nvme_close(BlockDriverState *bs)
|
||||
{
|
||||
int i;
|
||||
BDRVNVMeState *s = bs->opaque;
|
||||
|
||||
for (i = 0; i < s->nr_queues; ++i) {
|
||||
for (unsigned i = 0; i < s->queue_count; ++i) {
|
||||
nvme_free_queue_pair(s->queues[i]);
|
||||
}
|
||||
g_free(s->queues);
|
||||
@@ -889,8 +913,8 @@ static void nvme_close(BlockDriverState *bs)
|
||||
&s->irq_notifier[MSIX_SHARED_IRQ_IDX],
|
||||
false, NULL, NULL);
|
||||
event_notifier_cleanup(&s->irq_notifier[MSIX_SHARED_IRQ_IDX]);
|
||||
qemu_vfio_pci_unmap_bar(s->vfio, 0, (void *)s->doorbells,
|
||||
sizeof(NvmeBar), NVME_DOORBELL_SIZE);
|
||||
qemu_vfio_pci_unmap_bar(s->vfio, 0, s->bar0_wo_map,
|
||||
0, sizeof(NvmeBar) + NVME_DOORBELL_SIZE);
|
||||
qemu_vfio_close(s->vfio);
|
||||
|
||||
g_free(s->device);
|
||||
@@ -994,11 +1018,12 @@ static coroutine_fn int nvme_cmd_map_qiov(BlockDriverState *bs, NvmeCmd *cmd,
|
||||
for (i = 0; i < qiov->niov; ++i) {
|
||||
bool retry = true;
|
||||
uint64_t iova;
|
||||
size_t len = QEMU_ALIGN_UP(qiov->iov[i].iov_len,
|
||||
qemu_real_host_page_size);
|
||||
try_map:
|
||||
r = qemu_vfio_dma_map(s->vfio,
|
||||
qiov->iov[i].iov_base,
|
||||
qiov->iov[i].iov_len,
|
||||
true, &iova);
|
||||
len, true, &iova);
|
||||
if (r == -ENOMEM && retry) {
|
||||
retry = false;
|
||||
trace_nvme_dma_flush_queue_wait(s);
|
||||
@@ -1106,7 +1131,7 @@ static coroutine_fn int nvme_co_prw_aligned(BlockDriverState *bs,
|
||||
};
|
||||
|
||||
trace_nvme_prw_aligned(s, is_write, offset, bytes, flags, qiov->niov);
|
||||
assert(s->nr_queues > 1);
|
||||
assert(s->queue_count > 1);
|
||||
req = nvme_get_free_req(ioq);
|
||||
assert(req);
|
||||
|
||||
@@ -1142,8 +1167,9 @@ static inline bool nvme_qiov_aligned(BlockDriverState *bs,
|
||||
BDRVNVMeState *s = bs->opaque;
|
||||
|
||||
for (i = 0; i < qiov->niov; ++i) {
|
||||
if (!QEMU_PTR_IS_ALIGNED(qiov->iov[i].iov_base, s->page_size) ||
|
||||
!QEMU_IS_ALIGNED(qiov->iov[i].iov_len, s->page_size)) {
|
||||
if (!QEMU_PTR_IS_ALIGNED(qiov->iov[i].iov_base,
|
||||
qemu_real_host_page_size) ||
|
||||
!QEMU_IS_ALIGNED(qiov->iov[i].iov_len, qemu_real_host_page_size)) {
|
||||
trace_nvme_qiov_unaligned(qiov, i, qiov->iov[i].iov_base,
|
||||
qiov->iov[i].iov_len, s->page_size);
|
||||
return false;
|
||||
@@ -1159,7 +1185,7 @@ static int nvme_co_prw(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
|
||||
int r;
|
||||
uint8_t *buf = NULL;
|
||||
QEMUIOVector local_qiov;
|
||||
|
||||
size_t len = QEMU_ALIGN_UP(bytes, qemu_real_host_page_size);
|
||||
assert(QEMU_IS_ALIGNED(offset, s->page_size));
|
||||
assert(QEMU_IS_ALIGNED(bytes, s->page_size));
|
||||
assert(bytes <= s->max_transfer);
|
||||
@@ -1169,7 +1195,7 @@ static int nvme_co_prw(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
|
||||
}
|
||||
s->stats.unaligned_accesses++;
|
||||
trace_nvme_prw_buffered(s, offset, bytes, qiov->niov, is_write);
|
||||
buf = qemu_try_memalign(s->page_size, bytes);
|
||||
buf = qemu_try_memalign(qemu_real_host_page_size, len);
|
||||
|
||||
if (!buf) {
|
||||
return -ENOMEM;
|
||||
@@ -1216,7 +1242,7 @@ static coroutine_fn int nvme_co_flush(BlockDriverState *bs)
|
||||
.ret = -EINPROGRESS,
|
||||
};
|
||||
|
||||
assert(s->nr_queues > 1);
|
||||
assert(s->queue_count > 1);
|
||||
req = nvme_get_free_req(ioq);
|
||||
assert(req);
|
||||
nvme_submit_command(ioq, req, &cmd, nvme_rw_cb, &data);
|
||||
@@ -1268,7 +1294,7 @@ static coroutine_fn int nvme_co_pwrite_zeroes(BlockDriverState *bs,
|
||||
cmd.cdw12 = cpu_to_le32(cdw12);
|
||||
|
||||
trace_nvme_write_zeroes(s, offset, bytes, flags);
|
||||
assert(s->nr_queues > 1);
|
||||
assert(s->queue_count > 1);
|
||||
req = nvme_get_free_req(ioq);
|
||||
assert(req);
|
||||
|
||||
@@ -1311,7 +1337,7 @@ static int coroutine_fn nvme_co_pdiscard(BlockDriverState *bs,
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
assert(s->nr_queues > 1);
|
||||
assert(s->queue_count > 1);
|
||||
|
||||
buf = qemu_try_memalign(s->page_size, s->page_size);
|
||||
if (!buf) {
|
||||
@@ -1391,7 +1417,7 @@ static void nvme_detach_aio_context(BlockDriverState *bs)
|
||||
{
|
||||
BDRVNVMeState *s = bs->opaque;
|
||||
|
||||
for (int i = 0; i < s->nr_queues; i++) {
|
||||
for (unsigned i = 0; i < s->queue_count; i++) {
|
||||
NVMeQueuePair *q = s->queues[i];
|
||||
|
||||
qemu_bh_delete(q->completion_bh);
|
||||
@@ -1412,7 +1438,7 @@ static void nvme_attach_aio_context(BlockDriverState *bs,
|
||||
aio_set_event_notifier(new_context, &s->irq_notifier[MSIX_SHARED_IRQ_IDX],
|
||||
false, nvme_handle_event, nvme_poll_cb);
|
||||
|
||||
for (int i = 0; i < s->nr_queues; i++) {
|
||||
for (unsigned i = 0; i < s->queue_count; i++) {
|
||||
NVMeQueuePair *q = s->queues[i];
|
||||
|
||||
q->completion_bh =
|
||||
@@ -1429,11 +1455,10 @@ static void nvme_aio_plug(BlockDriverState *bs)
|
||||
|
||||
static void nvme_aio_unplug(BlockDriverState *bs)
|
||||
{
|
||||
int i;
|
||||
BDRVNVMeState *s = bs->opaque;
|
||||
assert(s->plugged);
|
||||
s->plugged = false;
|
||||
for (i = INDEX_IO(0); i < s->nr_queues; i++) {
|
||||
for (unsigned i = INDEX_IO(0); i < s->queue_count; i++) {
|
||||
NVMeQueuePair *q = s->queues[i];
|
||||
qemu_mutex_lock(&q->lock);
|
||||
nvme_kick(q);
|
||||
|
||||
@@ -2010,14 +2010,17 @@ static int zero_in_l2_slice(BlockDriverState *bs, uint64_t offset,
|
||||
continue;
|
||||
}
|
||||
|
||||
/* First update L2 entries */
|
||||
qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_slice);
|
||||
if (unmap) {
|
||||
qcow2_free_any_cluster(bs, old_l2_entry, QCOW2_DISCARD_REQUEST);
|
||||
}
|
||||
set_l2_entry(s, l2_slice, l2_index + i, new_l2_entry);
|
||||
if (has_subclusters(s)) {
|
||||
set_l2_bitmap(s, l2_slice, l2_index + i, new_l2_bitmap);
|
||||
}
|
||||
|
||||
/* Then decrease the refcount */
|
||||
if (unmap) {
|
||||
qcow2_free_any_cluster(bs, old_l2_entry, QCOW2_DISCARD_REQUEST);
|
||||
}
|
||||
}
|
||||
|
||||
qcow2_cache_put(s->l2_table_cache, (void **) &l2_slice);
|
||||
|
||||
+17
-13
@@ -134,25 +134,29 @@ qed_aio_write_postfill(void *s, void *acb, uint64_t start, size_t len, uint64_t
|
||||
qed_aio_write_main(void *s, void *acb, int ret, uint64_t offset, size_t len) "s %p acb %p ret %d offset %"PRIu64" len %zu"
|
||||
|
||||
# nvme.c
|
||||
nvme_kick(void *s, int queue) "s %p queue %d"
|
||||
nvme_controller_capability_raw(uint64_t value) "0x%08"PRIx64
|
||||
nvme_controller_capability(const char *desc, uint64_t value) "%s: %"PRIu64
|
||||
nvme_kick(void *s, unsigned q_index) "s %p q #%u"
|
||||
nvme_dma_flush_queue_wait(void *s) "s %p"
|
||||
nvme_error(int cmd_specific, int sq_head, int sqid, int cid, int status) "cmd_specific %d sq_head %d sqid %d cid %d status 0x%x"
|
||||
nvme_process_completion(void *s, int index, int inflight) "s %p queue %d inflight %d"
|
||||
nvme_process_completion_queue_plugged(void *s, int index) "s %p queue %d"
|
||||
nvme_complete_command(void *s, int index, int cid) "s %p queue %d cid %d"
|
||||
nvme_submit_command(void *s, int index, int cid) "s %p queue %d cid %d"
|
||||
nvme_process_completion(void *s, unsigned q_index, int inflight) "s %p q #%u inflight %d"
|
||||
nvme_process_completion_queue_plugged(void *s, unsigned q_index) "s %p q #%u"
|
||||
nvme_complete_command(void *s, unsigned q_index, int cid) "s %p q #%u cid %d"
|
||||
nvme_submit_command(void *s, unsigned q_index, int cid) "s %p q #%u cid %d"
|
||||
nvme_submit_command_raw(int c0, int c1, int c2, int c3, int c4, int c5, int c6, int c7) "%02x %02x %02x %02x %02x %02x %02x %02x"
|
||||
nvme_handle_event(void *s) "s %p"
|
||||
nvme_poll_cb(void *s) "s %p"
|
||||
nvme_prw_aligned(void *s, int is_write, uint64_t offset, uint64_t bytes, int flags, int niov) "s %p is_write %d offset %"PRId64" bytes %"PRId64" flags %d niov %d"
|
||||
nvme_write_zeroes(void *s, uint64_t offset, uint64_t bytes, int flags) "s %p offset %"PRId64" bytes %"PRId64" flags %d"
|
||||
nvme_poll_queue(void *s, unsigned q_index) "s %p q #%u"
|
||||
nvme_prw_aligned(void *s, int is_write, uint64_t offset, uint64_t bytes, int flags, int niov) "s %p is_write %d offset 0x%"PRIx64" bytes %"PRId64" flags %d niov %d"
|
||||
nvme_write_zeroes(void *s, uint64_t offset, uint64_t bytes, int flags) "s %p offset 0x%"PRIx64" bytes %"PRId64" flags %d"
|
||||
nvme_qiov_unaligned(const void *qiov, int n, void *base, size_t size, int align) "qiov %p n %d base %p size 0x%zx align 0x%x"
|
||||
nvme_prw_buffered(void *s, uint64_t offset, uint64_t bytes, int niov, int is_write) "s %p offset %"PRId64" bytes %"PRId64" niov %d is_write %d"
|
||||
nvme_rw_done(void *s, int is_write, uint64_t offset, uint64_t bytes, int ret) "s %p is_write %d offset %"PRId64" bytes %"PRId64" ret %d"
|
||||
nvme_dsm(void *s, uint64_t offset, uint64_t bytes) "s %p offset %"PRId64" bytes %"PRId64""
|
||||
nvme_dsm_done(void *s, uint64_t offset, uint64_t bytes, int ret) "s %p offset %"PRId64" bytes %"PRId64" ret %d"
|
||||
nvme_prw_buffered(void *s, uint64_t offset, uint64_t bytes, int niov, int is_write) "s %p offset 0x%"PRIx64" bytes %"PRId64" niov %d is_write %d"
|
||||
nvme_rw_done(void *s, int is_write, uint64_t offset, uint64_t bytes, int ret) "s %p is_write %d offset 0x%"PRIx64" bytes %"PRId64" ret %d"
|
||||
nvme_dsm(void *s, uint64_t offset, uint64_t bytes) "s %p offset 0x%"PRIx64" bytes %"PRId64""
|
||||
nvme_dsm_done(void *s, uint64_t offset, uint64_t bytes, int ret) "s %p offset 0x%"PRIx64" bytes %"PRId64" ret %d"
|
||||
nvme_dma_map_flush(void *s) "s %p"
|
||||
nvme_free_req_queue_wait(void *q) "q %p"
|
||||
nvme_free_req_queue_wait(void *s, unsigned q_index) "s %p q #%u"
|
||||
nvme_create_queue_pair(unsigned q_index, void *q, unsigned size, void *aio_context, int fd) "index %u q %p size %u aioctx %p fd %d"
|
||||
nvme_free_queue_pair(unsigned q_index, void *q) "index %u q %p"
|
||||
nvme_cmd_map_qiov(void *s, void *cmd, void *req, void *qiov, int entries) "s %p cmd %p req %p qiov %p entries %d"
|
||||
nvme_cmd_map_qiov_pages(void *s, int i, uint64_t page) "s %p page[%d] 0x%"PRIx64
|
||||
nvme_cmd_map_qiov_iov(void *s, int i, void *page, int pages) "s %p iov[%d] %p pages %d"
|
||||
|
||||
@@ -1912,9 +1912,6 @@ fi
|
||||
|
||||
case "$meson" in
|
||||
git | internal)
|
||||
if ! $python -c 'import pkg_resources' > /dev/null 2>&1; then
|
||||
error_exit "Python setuptools not found"
|
||||
fi
|
||||
meson="$python ${source_path}/meson/meson.py"
|
||||
;;
|
||||
*) meson=$(command -v "$meson") ;;
|
||||
@@ -4832,6 +4829,13 @@ if have_backend "dtrace"; then
|
||||
trace_backend_stap="no"
|
||||
if has 'stap' ; then
|
||||
trace_backend_stap="yes"
|
||||
|
||||
# Workaround to avoid dtrace(1) producing a file with 'hidden' symbol
|
||||
# visibility. Define STAP_SDT_V2 to produce 'default' symbol visibility
|
||||
# instead. QEMU --enable-modules depends on this because the SystemTap
|
||||
# semaphores are linked into the main binary and not the module's shared
|
||||
# object.
|
||||
QEMU_CFLAGS="$QEMU_CFLAGS -DSTAP_SDT_V2"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
+4
-4
@@ -19,7 +19,7 @@ interface to implement because such device can be easily connected
|
||||
to systems with different CPU architectures (x86, PowerPC, Arm, etc.).
|
||||
|
||||
In 2020, CTU CAN FD controller model has been added as part
|
||||
of the bachelor theses of Jan Charvat. This controller is complete
|
||||
of the bachelor thesis of Jan Charvat. This controller is complete
|
||||
open-source/design/hardware solution. The core designer
|
||||
of the project is Ondrej Ille, the financial support has been
|
||||
provided by CTU, and more companies including Volkswagen subsidiaries.
|
||||
@@ -31,7 +31,7 @@ testing lead to goal change to provide environment which provides complete
|
||||
emulated environment for testing and RTEMS GSoC slot has been donated
|
||||
to work on CAN hardware emulation on QEMU.
|
||||
|
||||
Examples how to use CAN emulation for SJA1000 based borads
|
||||
Examples how to use CAN emulation for SJA1000 based boards
|
||||
==========================================================
|
||||
|
||||
When QEMU with CAN PCI support is compiled then one of the next
|
||||
@@ -106,8 +106,8 @@ This open-source core provides CAN FD support. CAN FD drames are
|
||||
delivered even to the host systems when SocketCAN interface is found
|
||||
CAN FD capable.
|
||||
|
||||
The PCIe borad emulation is provided for now (the device identifier is
|
||||
ctucan_pci). The defauld build defines two CTU CAN FD cores
|
||||
The PCIe board emulation is provided for now (the device identifier is
|
||||
ctucan_pci). The default build defines two CTU CAN FD cores
|
||||
on the board.
|
||||
|
||||
Example how to connect the canbus0-bus (virtual wire) to the host
|
||||
|
||||
@@ -530,7 +530,7 @@ descriptor table (split virtqueue) or descriptor ring (packed
|
||||
virtqueue). However, it can't work when we process descriptors
|
||||
out-of-order because some entries which store the information of
|
||||
inflight descriptors in available ring (split virtqueue) or descriptor
|
||||
ring (packed virtqueue) might be overrided by new entries. To solve
|
||||
ring (packed virtqueue) might be overridden by new entries. To solve
|
||||
this problem, slave need to allocate an extra buffer to store this
|
||||
information of inflight descriptors and share it with master for
|
||||
persistent. ``VHOST_USER_GET_INFLIGHT_FD`` and
|
||||
|
||||
@@ -60,6 +60,7 @@ if build_docs
|
||||
'tools': {
|
||||
'qemu-img.1': (have_tools ? 'man1' : ''),
|
||||
'qemu-nbd.8': (have_tools ? 'man8' : ''),
|
||||
'qemu-pr-helper.8': (have_tools ? 'man8' : ''),
|
||||
'qemu-trace-stap.1': (config_host.has_key('CONFIG_TRACE_SYSTEMTAP') ? 'man1' : ''),
|
||||
'virtfs-proxy-helper.1': (have_virtfs_proxy_helper ? 'man1' : ''),
|
||||
'virtiofsd.1': (have_virtiofsd ? 'man1' : ''),
|
||||
|
||||
+1
-1
@@ -328,7 +328,7 @@ between the snapshots. Each of the passes include the following steps:
|
||||
1. loading the snapshot
|
||||
2. replaying to examine the breakpoints
|
||||
3. if breakpoint or watchpoint was met
|
||||
- loading the snaphot again
|
||||
- loading the snapshot again
|
||||
- replaying to the required breakpoint
|
||||
4. else
|
||||
- proceeding to the p.1 with the earlier snapshot
|
||||
|
||||
@@ -198,7 +198,7 @@ This is how it is being done:
|
||||
* user distance 121 and beyond will be interpreted as 160
|
||||
* user distance 10 stays 10
|
||||
|
||||
The reasoning behind this aproximation is to avoid any round up to the local
|
||||
The reasoning behind this approximation is to avoid any round up to the local
|
||||
distance (10), keeping it exclusive to the 4th NUMA level (which is still
|
||||
exclusive to the node_id). All other ranges were chosen under the developer
|
||||
discretion of what would be (somewhat) sensible considering the user input.
|
||||
|
||||
@@ -47,6 +47,7 @@ Supported devices
|
||||
* GPIO Controller (Master only)
|
||||
* UART
|
||||
* Ethernet controllers
|
||||
* Front LEDs (PCA9552 on I2C bus)
|
||||
|
||||
|
||||
Missing devices
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
Raspberry Pi boards (``raspi0``, ``raspi1ap``, ``raspi2b``, ``raspi3ap``, ``raspi3b``)
|
||||
======================================================================================
|
||||
|
||||
|
||||
QEMU provides models of the following Raspberry Pi boards:
|
||||
|
||||
``raspi0`` and ``raspi1ap``
|
||||
ARM1176JZF-S core, 512 MiB of RAM
|
||||
``raspi2b``
|
||||
Cortex-A7 (4 cores), 1 GiB of RAM
|
||||
``raspi3ap``
|
||||
Cortex-A53 (4 cores), 512 MiB of RAM
|
||||
``raspi3b``
|
||||
Cortex-A53 (4 cores), 1 GiB of RAM
|
||||
|
||||
|
||||
Implemented devices
|
||||
-------------------
|
||||
|
||||
* ARM1176JZF-S, Cortex-A7 or Cortex-A53 CPU
|
||||
* Interrupt controller
|
||||
* DMA controller
|
||||
* Clock and reset controller (CPRMAN)
|
||||
* System Timer
|
||||
* GPIO controller
|
||||
* Serial ports (BCM2835 AUX - 16550 based - and PL011)
|
||||
* Random Number Generator (RNG)
|
||||
* Frame Buffer
|
||||
* USB host (USBH)
|
||||
* GPIO controller
|
||||
* SD/MMC host controller
|
||||
* SoC thermal sensor
|
||||
* USB2 host controller (DWC2 and MPHI)
|
||||
* MailBox controller (MBOX)
|
||||
* VideoCore firmware (property)
|
||||
|
||||
|
||||
Missing devices
|
||||
---------------
|
||||
|
||||
* Peripheral SPI controller (SPI)
|
||||
* Analog to Digital Converter (ADC)
|
||||
* Pulse Width Modulation (PWM)
|
||||
@@ -1,16 +1,22 @@
|
||||
Sharp XScale-based PDA models (``akita``, ``borzoi``, ``spitz``, ``terrier``)
|
||||
=============================================================================
|
||||
Sharp XScale-based PDA models (``akita``, ``borzoi``, ``spitz``, ``terrier``, ``tosa``)
|
||||
=======================================================================================
|
||||
|
||||
The XScale-based clamshell PDA models (\"Spitz\", \"Akita\", \"Borzoi\"
|
||||
and \"Terrier\") emulation includes the following peripherals:
|
||||
The Sharp Zaurus are PDAs based on XScale, able to run Linux ('SL series').
|
||||
|
||||
- Intel PXA270 System-on-chip (ARMv5TE core)
|
||||
The SL-6000 (\"Tosa\"), released in 2005, uses a PXA255 System-on-chip.
|
||||
|
||||
- NAND Flash memory
|
||||
The SL-C3000 (\"Spitz\"), SL-C1000 (\"Akita\"), SL-C3100 (\"Borzoi\") and
|
||||
SL-C3200 (\"Terrier\") use a PXA270.
|
||||
|
||||
The clamshell PDA models emulation includes the following peripherals:
|
||||
|
||||
- Intel PXA255/PXA270 System-on-chip (ARMv5TE core)
|
||||
|
||||
- NAND Flash memory - not in \"Tosa\"
|
||||
|
||||
- IBM/Hitachi DSCM microdrive in a PXA PCMCIA slot - not in \"Akita\"
|
||||
|
||||
- On-chip OHCI USB controller
|
||||
- On-chip OHCI USB controller - not in \"Tosa\"
|
||||
|
||||
- On-chip LCD controller
|
||||
|
||||
|
||||
File renamed without changes.
@@ -346,6 +346,13 @@ This machine has been renamed ``fuloong2e``.
|
||||
These machine types are very old and likely can not be used for live migration
|
||||
from old QEMU versions anymore. A newer machine type should be used instead.
|
||||
|
||||
Raspberry Pi ``raspi2`` and ``raspi3`` machines (since 5.2)
|
||||
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
|
||||
|
||||
The Raspberry Pi machines come in various models (A, A+, B, B+). To be able
|
||||
to distinguish which model QEMU is implementing, the ``raspi2`` and ``raspi3``
|
||||
machines have been renamed ``raspi2b`` and ``raspi3b``.
|
||||
|
||||
Device options
|
||||
--------------
|
||||
|
||||
@@ -473,7 +480,7 @@ default configuration.
|
||||
|
||||
The CPU model runnability guarantee won't apply anymore to
|
||||
existing CPU models. Management software that needs runnability
|
||||
guarantees must resolve the CPU model aliases using te
|
||||
guarantees must resolve the CPU model aliases using the
|
||||
``alias-of`` field returned by the ``query-cpu-definitions`` QMP
|
||||
command.
|
||||
|
||||
@@ -660,7 +667,7 @@ Splitting RAM by default between NUMA nodes had the same issues as ``mem``
|
||||
parameter with the difference that the role of the user plays QEMU using
|
||||
implicit generic or board specific splitting rule.
|
||||
Use ``memdev`` with *memory-backend-ram* backend or ``mem`` (if
|
||||
it's supported by used machine type) to define mapping explictly instead.
|
||||
it's supported by used machine type) to define mapping explicitly instead.
|
||||
Users of existing VMs, wishing to preserve the same RAM distribution, should
|
||||
configure it explicitly using ``-numa node,memdev`` options. Current RAM
|
||||
distribution can be retrieved using HMP command ``info numa`` and if separate
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
.. _gdb_005fusage:
|
||||
.. _GDB usage:
|
||||
|
||||
GDB usage
|
||||
---------
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
====================
|
||||
microvm Machine Type
|
||||
====================
|
||||
'microvm' virtual platform (``microvm``)
|
||||
========================================
|
||||
|
||||
``microvm`` is a machine type inspired by ``Firecracker`` and
|
||||
constructed after its machine model.
|
||||
@@ -0,0 +1,7 @@
|
||||
i440fx PC (``pc-i440fx``, ``pc``)
|
||||
=================================
|
||||
|
||||
Peripherals
|
||||
~~~~~~~~~~~
|
||||
|
||||
.. include:: ../target-i386-desc.rst.inc
|
||||
@@ -1,4 +1,4 @@
|
||||
.. _disk_005fimages:
|
||||
.. _disk images:
|
||||
|
||||
Disk Images
|
||||
-----------
|
||||
|
||||
@@ -21,6 +21,7 @@ Contents:
|
||||
monitor
|
||||
images
|
||||
net
|
||||
virtio-net-failover
|
||||
usb
|
||||
ivshmem
|
||||
linuxboot
|
||||
@@ -28,6 +29,9 @@ Contents:
|
||||
tls
|
||||
gdb
|
||||
managed-startup
|
||||
cpu-hotplug
|
||||
virtio-pmem
|
||||
pr-manager
|
||||
targets
|
||||
security
|
||||
deprecated
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.. _pcsys_005fmonitor:
|
||||
.. _QEMU monitor:
|
||||
|
||||
QEMU Monitor
|
||||
------------
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.. _mux_005fkeys:
|
||||
.. _keys in the character backend multiplexer:
|
||||
|
||||
Keys in the character backend multiplexer
|
||||
-----------------------------------------
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
======================================
|
||||
===============================
|
||||
Persistent reservation managers
|
||||
======================================
|
||||
===============================
|
||||
|
||||
SCSI persistent Reservations allow restricting access to block devices
|
||||
SCSI persistent reservations allow restricting access to block devices
|
||||
to specific initiators in a shared storage setup. When implementing
|
||||
clustering of virtual machines, it is a common requirement for virtual
|
||||
machines to send persistent reservation SCSI commands. However,
|
||||
@@ -50,39 +50,11 @@ Alternatively, using ``-blockdev``::
|
||||
-blockdev node-name=hd,driver=raw,file.driver=host_device,file.filename=/dev/sdb,file.pr-manager=helper0
|
||||
-device scsi-block,drive=hd
|
||||
|
||||
----------------------------------
|
||||
Invoking :program:`qemu-pr-helper`
|
||||
----------------------------------
|
||||
|
||||
QEMU provides an implementation of the persistent reservation helper,
|
||||
called :program:`qemu-pr-helper`. The helper should be started as a
|
||||
system service and supports the following option:
|
||||
|
||||
-d, --daemon run in the background
|
||||
-q, --quiet decrease verbosity
|
||||
-v, --verbose increase verbosity
|
||||
-f, --pidfile=path PID file when running as a daemon
|
||||
-k, --socket=path path to the socket
|
||||
-T, --trace=trace-opts tracing options
|
||||
|
||||
By default, the socket and PID file are placed in the runtime state
|
||||
directory, for example :file:`/var/run/qemu-pr-helper.sock` and
|
||||
:file:`/var/run/qemu-pr-helper.pid`. The PID file is not created
|
||||
unless :option:`-d` is passed too.
|
||||
|
||||
:program:`qemu-pr-helper` can also use the systemd socket activation
|
||||
protocol. In this case, the systemd socket unit should specify a
|
||||
Unix stream socket, like this::
|
||||
|
||||
[Socket]
|
||||
ListenStream=/var/run/qemu-pr-helper.sock
|
||||
|
||||
After connecting to the socket, :program:`qemu-pr-helper`` can optionally drop
|
||||
root privileges, except for those capabilities that are needed for
|
||||
its operation. To do this, add the following options:
|
||||
|
||||
-u, --user=user user to drop privileges to
|
||||
-g, --group=group group to drop privileges to
|
||||
You will also need to ensure that the helper program
|
||||
:command:`qemu-pr-helper` is running, and that it has been
|
||||
set up to use the same socket filename as your QEMU commandline
|
||||
specifies. See the qemu-pr-helper documentation or manpage for
|
||||
further details.
|
||||
|
||||
---------------------------------------------
|
||||
Multipath devices and persistent reservations
|
||||
@@ -90,6 +90,7 @@ undocumented; you can get a complete list by running
|
||||
arm/nuvoton
|
||||
arm/orangepi
|
||||
arm/palm
|
||||
arm/raspi
|
||||
arm/xscale
|
||||
arm/collie
|
||||
arm/sx1
|
||||
|
||||
@@ -1,14 +1,23 @@
|
||||
.. _QEMU-PC-System-emulator:
|
||||
|
||||
x86 (PC) System emulator
|
||||
------------------------
|
||||
x86 System emulator
|
||||
-------------------
|
||||
|
||||
.. _pcsys_005fdevices:
|
||||
|
||||
Peripherals
|
||||
~~~~~~~~~~~
|
||||
Board-specific documentation
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. include:: target-i386-desc.rst.inc
|
||||
..
|
||||
This table of contents should be kept sorted alphabetically
|
||||
by the title text of each file, which isn't the same ordering
|
||||
as an alphabetical sort by filename.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
i386/microvm
|
||||
i386/pc
|
||||
|
||||
.. include:: cpu-models-x86.rst.inc
|
||||
|
||||
|
||||
+3
-3
@@ -8,7 +8,7 @@ plug virtual USB devices or real host USB devices (only works with
|
||||
certain host operating systems). QEMU will automatically create and
|
||||
connect virtual USB hubs as necessary to connect multiple USB devices.
|
||||
|
||||
.. _usb_005fdevices:
|
||||
.. _Connecting USB devices:
|
||||
|
||||
Connecting USB devices
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
@@ -27,8 +27,8 @@ option or the ``device_add`` monitor command. Available devices are:
|
||||
activated.
|
||||
|
||||
``usb-storage,drive=drive_id``
|
||||
Mass storage device backed by drive_id (see
|
||||
:ref:`disk_005fimages`)
|
||||
Mass storage device backed by drive_id (see the :ref:`disk images`
|
||||
chapter in the System Emulation Users Guide)
|
||||
|
||||
``usb-uas``
|
||||
USB attached SCSI device, see
|
||||
|
||||
File renamed without changes.
@@ -0,0 +1,76 @@
|
||||
|
||||
===========
|
||||
virtio pmem
|
||||
===========
|
||||
|
||||
This document explains the setup and usage of the virtio pmem device.
|
||||
The virtio pmem device is a paravirtualized persistent memory device
|
||||
on regular (i.e non-NVDIMM) storage.
|
||||
|
||||
Usecase
|
||||
-------
|
||||
|
||||
Virtio pmem allows to bypass the guest page cache and directly use
|
||||
host page cache. This reduces guest memory footprint as the host can
|
||||
make efficient memory reclaim decisions under memory pressure.
|
||||
|
||||
How does virtio-pmem compare to the nvdimm emulation?
|
||||
-----------------------------------------------------
|
||||
|
||||
NVDIMM emulation on regular (i.e. non-NVDIMM) host storage does not
|
||||
persist the guest writes as there are no defined semantics in the device
|
||||
specification. The virtio pmem device provides guest write persistence
|
||||
on non-NVDIMM host storage.
|
||||
|
||||
virtio pmem usage
|
||||
-----------------
|
||||
|
||||
A virtio pmem device backed by a memory-backend-file can be created on
|
||||
the QEMU command line as in the following example::
|
||||
|
||||
-object memory-backend-file,id=mem1,share,mem-path=./virtio_pmem.img,size=4G
|
||||
-device virtio-pmem-pci,memdev=mem1,id=nv1
|
||||
|
||||
where:
|
||||
|
||||
- "object memory-backend-file,id=mem1,share,mem-path=<image>, size=<image size>"
|
||||
creates a backend file with the specified size.
|
||||
|
||||
- "device virtio-pmem-pci,id=nvdimm1,memdev=mem1" creates a virtio pmem
|
||||
pci device whose storage is provided by above memory backend device.
|
||||
|
||||
Multiple virtio pmem devices can be created if multiple pairs of "-object"
|
||||
and "-device" are provided.
|
||||
|
||||
Hotplug
|
||||
-------
|
||||
|
||||
Virtio pmem devices can be hotplugged via the QEMU monitor. First, the
|
||||
memory backing has to be added via 'object_add'; afterwards, the virtio
|
||||
pmem device can be added via 'device_add'.
|
||||
|
||||
For example, the following commands add another 4GB virtio pmem device to
|
||||
the guest::
|
||||
|
||||
(qemu) object_add memory-backend-file,id=mem2,share=on,mem-path=virtio_pmem2.img,size=4G
|
||||
(qemu) device_add virtio-pmem-pci,id=virtio_pmem2,memdev=mem2
|
||||
|
||||
Guest Data Persistence
|
||||
----------------------
|
||||
|
||||
Guest data persistence on non-NVDIMM requires guest userspace applications
|
||||
to perform fsync/msync. This is different from a real nvdimm backend where
|
||||
no additional fsync/msync is required. This is to persist guest writes in
|
||||
host backing file which otherwise remains in host page cache and there is
|
||||
risk of losing the data in case of power failure.
|
||||
|
||||
With virtio pmem device, MAP_SYNC mmap flag is not supported. This provides
|
||||
a hint to application to perform fsync for write persistence.
|
||||
|
||||
Limitations
|
||||
-----------
|
||||
|
||||
- Real nvdimm device backend is not supported.
|
||||
- virtio pmem hotunplug is not supported.
|
||||
- ACPI NVDIMM features like regions/namespaces are not supported.
|
||||
- ndctl command is not supported.
|
||||
@@ -1,4 +1,4 @@
|
||||
.. _vnc_005fsecurity:
|
||||
.. _VNC security:
|
||||
|
||||
VNC security
|
||||
------------
|
||||
|
||||
@@ -22,6 +22,8 @@ man_pages = [
|
||||
['Fabrice Bellard'], 1),
|
||||
('qemu-nbd', 'qemu-nbd', u'QEMU Disk Network Block Device Server',
|
||||
['Anthony Liguori <anthony@codemonkey.ws>'], 8),
|
||||
('qemu-pr-helper', 'qemu-pr-helper', 'QEMU persistent reservation helper',
|
||||
[], 8),
|
||||
('qemu-trace-stap', 'qemu-trace-stap', u'QEMU SystemTap trace tool',
|
||||
[], 1),
|
||||
('virtfs-proxy-helper', 'virtfs-proxy-helper',
|
||||
|
||||
@@ -12,6 +12,7 @@ Contents:
|
||||
|
||||
qemu-img
|
||||
qemu-nbd
|
||||
qemu-pr-helper
|
||||
qemu-trace-stap
|
||||
virtfs-proxy-helper
|
||||
virtiofsd
|
||||
@@ -0,0 +1,90 @@
|
||||
QEMU persistent reservation helper
|
||||
==================================
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
**qemu-pr-helper** [*OPTION*]
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
Implements the persistent reservation helper for QEMU.
|
||||
|
||||
SCSI persistent reservations allow restricting access to block devices
|
||||
to specific initiators in a shared storage setup. When implementing
|
||||
clustering of virtual machines, it is a common requirement for virtual
|
||||
machines to send persistent reservation SCSI commands. However,
|
||||
the operating system restricts sending these commands to unprivileged
|
||||
programs because incorrect usage can disrupt regular operation of the
|
||||
storage fabric. QEMU's SCSI passthrough devices ``scsi-block``
|
||||
and ``scsi-generic`` support passing guest persistent reservation
|
||||
requests to a privileged external helper program. :program:`qemu-pr-helper`
|
||||
is that external helper; it creates a socket which QEMU can
|
||||
connect to to communicate with it.
|
||||
|
||||
If you want to run VMs in a setup like this, this helper should be
|
||||
started as a system service, and you should read the QEMU manual
|
||||
section on "persistent reservation managers" to find out how to
|
||||
configure QEMU to connect to the socket created by
|
||||
:program:`qemu-pr-helper`.
|
||||
|
||||
After connecting to the socket, :program:`qemu-pr-helper` can
|
||||
optionally drop root privileges, except for those capabilities that
|
||||
are needed for its operation.
|
||||
|
||||
:program:`qemu-pr-helper` can also use the systemd socket activation
|
||||
protocol. In this case, the systemd socket unit should specify a
|
||||
Unix stream socket, like this::
|
||||
|
||||
[Socket]
|
||||
ListenStream=/var/run/qemu-pr-helper.sock
|
||||
|
||||
Options
|
||||
-------
|
||||
|
||||
.. program:: qemu-pr-helper
|
||||
|
||||
.. option:: -d, --daemon
|
||||
|
||||
run in the background (and create a PID file)
|
||||
|
||||
.. option:: -q, --quiet
|
||||
|
||||
decrease verbosity
|
||||
|
||||
.. option:: -v, --verbose
|
||||
|
||||
increase verbosity
|
||||
|
||||
.. option:: -f, --pidfile=PATH
|
||||
|
||||
PID file when running as a daemon. By default the PID file
|
||||
is created in the system runtime state directory, for example
|
||||
:file:`/var/run/qemu-pr-helper.pid`.
|
||||
|
||||
.. option:: -k, --socket=PATH
|
||||
|
||||
path to the socket. By default the socket is created in
|
||||
the system runtime state directory, for example
|
||||
:file:`/var/run/qemu-pr-helper.sock`.
|
||||
|
||||
.. option:: -T, --trace [[enable=]PATTERN][,events=FILE][,file=FILE]
|
||||
|
||||
.. include:: ../qemu-option-trace.rst.inc
|
||||
|
||||
.. option:: -u, --user=USER
|
||||
|
||||
user to drop privileges to
|
||||
|
||||
.. option:: -g, --group=GROUP
|
||||
|
||||
group to drop privileges to
|
||||
|
||||
.. option:: -h, --help
|
||||
|
||||
Display a help message and exit.
|
||||
|
||||
.. option:: -V, --version
|
||||
|
||||
Display version information and exit.
|
||||
@@ -174,7 +174,7 @@ Using ':' as the separator a rule is of the form:
|
||||
- 'bad' - If a client tries to use a name matching 'key' it's
|
||||
denied using EPERM; when the server passes an attribute
|
||||
name matching 'prepend' it's hidden. In many ways it's use is very like
|
||||
'ok' as either an explict terminator or for special handling of certain
|
||||
'ok' as either an explicit terminator or for special handling of certain
|
||||
patterns.
|
||||
|
||||
**key** is a string tested as a prefix on an attribute name originating
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
|
||||
========================
|
||||
QEMU virtio pmem
|
||||
========================
|
||||
|
||||
This document explains the setup and usage of the virtio pmem device
|
||||
which is available since QEMU v4.1.0.
|
||||
|
||||
The virtio pmem device is a paravirtualized persistent memory device
|
||||
on regular (i.e non-NVDIMM) storage.
|
||||
|
||||
Usecase
|
||||
--------
|
||||
|
||||
Virtio pmem allows to bypass the guest page cache and directly use
|
||||
host page cache. This reduces guest memory footprint as the host can
|
||||
make efficient memory reclaim decisions under memory pressure.
|
||||
|
||||
o How does virtio-pmem compare to the nvdimm emulation supported by QEMU?
|
||||
|
||||
NVDIMM emulation on regular (i.e. non-NVDIMM) host storage does not
|
||||
persist the guest writes as there are no defined semantics in the device
|
||||
specification. The virtio pmem device provides guest write persistence
|
||||
on non-NVDIMM host storage.
|
||||
|
||||
virtio pmem usage
|
||||
-----------------
|
||||
|
||||
A virtio pmem device backed by a memory-backend-file can be created on
|
||||
the QEMU command line as in the following example::
|
||||
|
||||
-object memory-backend-file,id=mem1,share,mem-path=./virtio_pmem.img,size=4G
|
||||
-device virtio-pmem-pci,memdev=mem1,id=nv1
|
||||
|
||||
where:
|
||||
|
||||
- "object memory-backend-file,id=mem1,share,mem-path=<image>, size=<image size>"
|
||||
creates a backend file with the specified size.
|
||||
|
||||
- "device virtio-pmem-pci,id=nvdimm1,memdev=mem1" creates a virtio pmem
|
||||
pci device whose storage is provided by above memory backend device.
|
||||
|
||||
Multiple virtio pmem devices can be created if multiple pairs of "-object"
|
||||
and "-device" are provided.
|
||||
|
||||
Hotplug
|
||||
-------
|
||||
|
||||
Virtio pmem devices can be hotplugged via the QEMU monitor. First, the
|
||||
memory backing has to be added via 'object_add'; afterwards, the virtio
|
||||
pmem device can be added via 'device_add'.
|
||||
|
||||
For example, the following commands add another 4GB virtio pmem device to
|
||||
the guest::
|
||||
|
||||
(qemu) object_add memory-backend-file,id=mem2,share=on,mem-path=virtio_pmem2.img,size=4G
|
||||
(qemu) device_add virtio-pmem-pci,id=virtio_pmem2,memdev=mem2
|
||||
|
||||
Guest Data Persistence
|
||||
----------------------
|
||||
|
||||
Guest data persistence on non-NVDIMM requires guest userspace applications
|
||||
to perform fsync/msync. This is different from a real nvdimm backend where
|
||||
no additional fsync/msync is required. This is to persist guest writes in
|
||||
host backing file which otherwise remains in host page cache and there is
|
||||
risk of losing the data in case of power failure.
|
||||
|
||||
With virtio pmem device, MAP_SYNC mmap flag is not supported. This provides
|
||||
a hint to application to perform fsync for write persistence.
|
||||
|
||||
Limitations
|
||||
------------
|
||||
- Real nvdimm device backend is not supported.
|
||||
- virtio pmem hotunplug is not supported.
|
||||
- ACPI NVDIMM features like regions/namespaces are not supported.
|
||||
- ndctl command is not supported.
|
||||
+1
-1
@@ -675,7 +675,7 @@ static void pxa2xx_ssp_write(void *opaque, hwaddr addr,
|
||||
if (value & SSCR0_MOD)
|
||||
printf("%s: Attempt to use network mode\n", __func__);
|
||||
if (s->enable && SSCR0_DSS(value) < 4)
|
||||
printf("%s: Wrong data size: %i bits\n", __func__,
|
||||
printf("%s: Wrong data size: %u bits\n", __func__,
|
||||
SSCR0_DSS(value));
|
||||
if (!(value & SSCR0_SSE)) {
|
||||
s->sssr = 0;
|
||||
|
||||
+1
-1
@@ -586,7 +586,7 @@ struct SpitzLCDTG {
|
||||
static void spitz_bl_update(SpitzLCDTG *s)
|
||||
{
|
||||
if (s->bl_power && s->bl_intensity)
|
||||
zaurus_printf("LCD Backlight now at %i/63\n", s->bl_intensity);
|
||||
zaurus_printf("LCD Backlight now at %u/63\n", s->bl_intensity);
|
||||
else
|
||||
zaurus_printf("LCD Backlight now off\n");
|
||||
}
|
||||
|
||||
+1
-1
@@ -150,7 +150,7 @@ static void tosa_gpio_setup(PXA2xxState *cpu,
|
||||
|
||||
static uint32_t tosa_ssp_tansfer(SSISlave *dev, uint32_t value)
|
||||
{
|
||||
fprintf(stderr, "TG: %d %02x\n", value >> 5, value & 0x1f);
|
||||
fprintf(stderr, "TG: %u %02x\n", value >> 5, value & 0x1f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -858,7 +858,7 @@ static void set_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
|
||||
Property *prop = opaque;
|
||||
PCIHostDeviceAddress *addr = qdev_get_prop_ptr(dev, prop);
|
||||
char *str, *p;
|
||||
const char *e;
|
||||
char *e;
|
||||
unsigned long val;
|
||||
unsigned long dom = 0, bus = 0;
|
||||
unsigned int slot = 0, func = 0;
|
||||
@@ -873,23 +873,23 @@ static void set_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
|
||||
}
|
||||
|
||||
p = str;
|
||||
if (qemu_strtoul(p, &e, 16, &val) < 0 || val > 0xffff || e == p) {
|
||||
goto inval;
|
||||
}
|
||||
if (*e != ':') {
|
||||
val = strtoul(p, &e, 16);
|
||||
if (e == p || *e != ':') {
|
||||
goto inval;
|
||||
}
|
||||
bus = val;
|
||||
|
||||
p = (char *)e + 1;
|
||||
if (qemu_strtoul(p, &e, 16, &val) < 0 || val > 0x1f || e == p) {
|
||||
p = e + 1;
|
||||
val = strtoul(p, &e, 16);
|
||||
if (e == p) {
|
||||
goto inval;
|
||||
}
|
||||
if (*e == ':') {
|
||||
dom = bus;
|
||||
bus = val;
|
||||
p = (char *)e + 1;
|
||||
if (qemu_strtoul(p, &e, 16, &val) < 0 || val > 0x1f || e == p) {
|
||||
p = e + 1;
|
||||
val = strtoul(p, &e, 16);
|
||||
if (e == p) {
|
||||
goto inval;
|
||||
}
|
||||
}
|
||||
@@ -898,13 +898,14 @@ static void set_pci_host_devaddr(Object *obj, Visitor *v, const char *name,
|
||||
if (*e != '.') {
|
||||
goto inval;
|
||||
}
|
||||
p = (char *)e + 1;
|
||||
if (qemu_strtoul(p, &e, 10, &val) < 0 || val > 7 || e == p) {
|
||||
p = e + 1;
|
||||
val = strtoul(p, &e, 10);
|
||||
if (e == p) {
|
||||
goto inval;
|
||||
}
|
||||
func = val;
|
||||
|
||||
if (bus > 0xff) {
|
||||
if (dom > 0xffff || bus > 0xff || slot > 0x1f || func > 7) {
|
||||
goto inval;
|
||||
}
|
||||
|
||||
|
||||
+5
-1
@@ -649,10 +649,14 @@ static const MemoryRegionOps tcx_blit_ops = {
|
||||
.read = tcx_blit_readl,
|
||||
.write = tcx_blit_writel,
|
||||
.endianness = DEVICE_NATIVE_ENDIAN,
|
||||
.valid = {
|
||||
.impl = {
|
||||
.min_access_size = 4,
|
||||
.max_access_size = 4,
|
||||
},
|
||||
.valid = {
|
||||
.min_access_size = 4,
|
||||
.max_access_size = 8,
|
||||
},
|
||||
};
|
||||
|
||||
static const MemoryRegionOps tcx_rblit_ops = {
|
||||
|
||||
@@ -276,6 +276,8 @@ void ide_atapi_cmd_reply_end(IDEState *s)
|
||||
s->packet_transfer_size -= size;
|
||||
s->elementary_transfer_size -= size;
|
||||
s->io_buffer_index += size;
|
||||
assert(size <= s->io_buffer_total_len);
|
||||
assert(s->io_buffer_index <= s->io_buffer_total_len);
|
||||
|
||||
/* Some adapters process PIO data right away. In that case, we need
|
||||
* to avoid mutual recursion between ide_transfer_start
|
||||
|
||||
+8
-10
@@ -300,22 +300,20 @@ static const MemoryRegionOps icu_ops = {
|
||||
static void rxicu_realize(DeviceState *dev, Error **errp)
|
||||
{
|
||||
RXICUState *icu = RX_ICU(dev);
|
||||
int i, j;
|
||||
int i;
|
||||
|
||||
if (icu->init_sense == NULL) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR,
|
||||
"rx_icu: trigger-level property must be set.");
|
||||
return;
|
||||
}
|
||||
for (i = j = 0; i < NR_IRQS; i++) {
|
||||
if (icu->init_sense[j] == i) {
|
||||
icu->src[i].sense = TRG_LEVEL;
|
||||
if (j < icu->nr_sense) {
|
||||
j++;
|
||||
}
|
||||
} else {
|
||||
icu->src[i].sense = TRG_PEDGE;
|
||||
}
|
||||
|
||||
for (i = 0; i < NR_IRQS; i++) {
|
||||
icu->src[i].sense = TRG_PEDGE;
|
||||
}
|
||||
for (i = 0; i < icu->nr_sense; i++) {
|
||||
uint8_t irqno = icu->init_sense[i];
|
||||
icu->src[irqno].sense = TRG_LEVEL;
|
||||
}
|
||||
icu->req_irq = -1;
|
||||
}
|
||||
|
||||
+18
-84
@@ -36,9 +36,10 @@ typedef struct KVMEnabledCPU {
|
||||
static QLIST_HEAD(, KVMEnabledCPU)
|
||||
kvm_enabled_cpus = QLIST_HEAD_INITIALIZER(&kvm_enabled_cpus);
|
||||
|
||||
static bool kvm_cpu_is_enabled(unsigned long vcpu_id)
|
||||
static bool kvm_cpu_is_enabled(CPUState *cs)
|
||||
{
|
||||
KVMEnabledCPU *enabled_cpu;
|
||||
unsigned long vcpu_id = kvm_arch_vcpu_id(cs);
|
||||
|
||||
QLIST_FOREACH(enabled_cpu, &kvm_enabled_cpus, node) {
|
||||
if (enabled_cpu->vcpu_id == vcpu_id) {
|
||||
@@ -146,45 +147,6 @@ int kvmppc_xive_cpu_synchronize_state(XiveTCTX *tctx, Error **errp)
|
||||
return s.ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate the vCPU IPIs from the vCPU context. This will allocate
|
||||
* the XIVE IPI interrupt on the chip on which the vCPU is running.
|
||||
* This gives a better distribution of IPIs when the guest has a lot
|
||||
* of vCPUs. When the vCPUs are pinned, this will make the IPI local
|
||||
* to the chip of the vCPU. It will reduce rerouting between interrupt
|
||||
* controllers and gives better performance.
|
||||
*/
|
||||
typedef struct {
|
||||
SpaprXive *xive;
|
||||
Error *err;
|
||||
int rc;
|
||||
} XiveInitIPI;
|
||||
|
||||
static void kvmppc_xive_reset_ipi_on_cpu(CPUState *cs, run_on_cpu_data arg)
|
||||
{
|
||||
unsigned long ipi = kvm_arch_vcpu_id(cs);
|
||||
XiveInitIPI *s = arg.host_ptr;
|
||||
uint64_t state = 0;
|
||||
|
||||
s->rc = kvm_device_access(s->xive->fd, KVM_DEV_XIVE_GRP_SOURCE, ipi,
|
||||
&state, true, &s->err);
|
||||
}
|
||||
|
||||
static int kvmppc_xive_reset_ipi(SpaprXive *xive, CPUState *cs, Error **errp)
|
||||
{
|
||||
XiveInitIPI s = {
|
||||
.xive = xive,
|
||||
.err = NULL,
|
||||
.rc = 0,
|
||||
};
|
||||
|
||||
run_on_cpu(cs, kvmppc_xive_reset_ipi_on_cpu, RUN_ON_CPU_HOST_PTR(&s));
|
||||
if (s.err) {
|
||||
error_propagate(errp, s.err);
|
||||
}
|
||||
return s.rc;
|
||||
}
|
||||
|
||||
int kvmppc_xive_cpu_connect(XiveTCTX *tctx, Error **errp)
|
||||
{
|
||||
ERRP_GUARD();
|
||||
@@ -195,7 +157,7 @@ int kvmppc_xive_cpu_connect(XiveTCTX *tctx, Error **errp)
|
||||
assert(xive->fd != -1);
|
||||
|
||||
/* Check if CPU was hot unplugged and replugged. */
|
||||
if (kvm_cpu_is_enabled(kvm_arch_vcpu_id(tctx->cs))) {
|
||||
if (kvm_cpu_is_enabled(tctx->cs)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -214,12 +176,6 @@ int kvmppc_xive_cpu_connect(XiveTCTX *tctx, Error **errp)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Create/reset the vCPU IPI */
|
||||
ret = kvmppc_xive_reset_ipi(xive, tctx->cs, errp);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
kvm_cpu_enable(tctx->cs);
|
||||
return 0;
|
||||
}
|
||||
@@ -279,12 +235,6 @@ int kvmppc_xive_source_reset_one(XiveSource *xsrc, int srcno, Error **errp)
|
||||
|
||||
assert(xive->fd != -1);
|
||||
|
||||
/*
|
||||
* The vCPU IPIs are now allocated in kvmppc_xive_cpu_connect()
|
||||
* and not with all sources in kvmppc_xive_source_reset()
|
||||
*/
|
||||
assert(srcno >= SPAPR_XIRQ_BASE);
|
||||
|
||||
if (xive_source_irq_is_lsi(xsrc, srcno)) {
|
||||
state |= KVM_XIVE_LEVEL_SENSITIVE;
|
||||
if (xsrc->status[srcno] & XIVE_STATUS_ASSERTED) {
|
||||
@@ -296,28 +246,12 @@ int kvmppc_xive_source_reset_one(XiveSource *xsrc, int srcno, Error **errp)
|
||||
true, errp);
|
||||
}
|
||||
|
||||
/*
|
||||
* To be valid, a source must have been claimed by the machine (valid
|
||||
* entry in the EAS table) and if it is a vCPU IPI, the vCPU should
|
||||
* have been enabled, which means the IPI has been allocated in
|
||||
* kvmppc_xive_cpu_connect().
|
||||
*/
|
||||
static bool xive_source_is_valid(SpaprXive *xive, int i)
|
||||
{
|
||||
return xive_eas_is_valid(&xive->eat[i]) &&
|
||||
(i >= SPAPR_XIRQ_BASE || kvm_cpu_is_enabled(i));
|
||||
}
|
||||
|
||||
static int kvmppc_xive_source_reset(XiveSource *xsrc, Error **errp)
|
||||
{
|
||||
SpaprXive *xive = SPAPR_XIVE(xsrc->xive);
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Skip the vCPU IPIs. These are created/reset when the vCPUs are
|
||||
* connected in kvmppc_xive_cpu_connect()
|
||||
*/
|
||||
for (i = SPAPR_XIRQ_BASE; i < xsrc->nr_irqs; i++) {
|
||||
for (i = 0; i < xsrc->nr_irqs; i++) {
|
||||
int ret;
|
||||
|
||||
if (!xive_eas_is_valid(&xive->eat[i])) {
|
||||
@@ -399,7 +333,7 @@ static void kvmppc_xive_source_get_state(XiveSource *xsrc)
|
||||
for (i = 0; i < xsrc->nr_irqs; i++) {
|
||||
uint8_t pq;
|
||||
|
||||
if (!xive_source_is_valid(xive, i)) {
|
||||
if (!xive_eas_is_valid(&xive->eat[i])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -582,7 +516,7 @@ static void kvmppc_xive_change_state_handler(void *opaque, int running,
|
||||
uint8_t pq;
|
||||
uint8_t old_pq;
|
||||
|
||||
if (!xive_source_is_valid(xive, i)) {
|
||||
if (!xive_eas_is_valid(&xive->eat[i])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -610,7 +544,7 @@ static void kvmppc_xive_change_state_handler(void *opaque, int running,
|
||||
for (i = 0; i < xsrc->nr_irqs; i++) {
|
||||
uint8_t pq;
|
||||
|
||||
if (!xive_source_is_valid(xive, i)) {
|
||||
if (!xive_eas_is_valid(&xive->eat[i])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -713,22 +647,22 @@ int kvmppc_xive_post_load(SpaprXive *xive, int version_id)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We can only restore the source config if the source has been
|
||||
* previously set in KVM. Since we don't do that at reset time
|
||||
* when restoring a VM, let's do it now.
|
||||
*/
|
||||
ret = kvmppc_xive_source_reset(&xive->source, &local_err);
|
||||
if (ret < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Restore the EAT */
|
||||
for (i = 0; i < xive->nr_irqs; i++) {
|
||||
if (!xive_source_is_valid(xive, i)) {
|
||||
if (!xive_eas_is_valid(&xive->eat[i])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* We can only restore the source config if the source has been
|
||||
* previously set in KVM. Since we don't do that for all interrupts
|
||||
* at reset time anymore, let's do it now.
|
||||
*/
|
||||
ret = kvmppc_xive_source_reset_one(&xive->source, i, &local_err);
|
||||
if (ret < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = kvmppc_xive_set_source_config(xive, i, &xive->eat[i], &local_err);
|
||||
if (ret < 0) {
|
||||
goto fail;
|
||||
|
||||
@@ -495,6 +495,10 @@ static void dp8393x_do_transmit_packets(dp8393xState *s)
|
||||
} else {
|
||||
/* Remove existing FCS */
|
||||
tx_len -= 4;
|
||||
if (tx_len < 0) {
|
||||
SONIC_ERROR("tx_len is %d\n", tx_len);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (s->regs[SONIC_RCR] & (SONIC_RCR_LB1 | SONIC_RCR_LB0)) {
|
||||
|
||||
@@ -1596,13 +1596,13 @@ e1000e_write_packet_to_guest(E1000ECore *core, struct NetRxPkt *pkt,
|
||||
(const char *) &fcs_pad, e1000x_fcs_len(core->mac));
|
||||
}
|
||||
}
|
||||
desc_offset += desc_size;
|
||||
if (desc_offset >= total_size) {
|
||||
is_last = true;
|
||||
}
|
||||
} else { /* as per intel docs; skip descriptors with null buf addr */
|
||||
trace_e1000e_rx_null_descriptor();
|
||||
}
|
||||
desc_offset += desc_size;
|
||||
if (desc_offset >= total_size) {
|
||||
is_last = true;
|
||||
}
|
||||
|
||||
e1000e_write_rx_descr(core, desc, is_last ? core->rx_pkt : NULL,
|
||||
rss_info, do_ps ? ps_hdr_len : 0, &bastate.written);
|
||||
|
||||
+12
-5
@@ -732,6 +732,13 @@ static void s390_pci_iommu_free(S390pciState *s, PCIBus *bus, int32_t devfn)
|
||||
|
||||
table->iommu[PCI_SLOT(devfn)] = NULL;
|
||||
g_hash_table_destroy(iommu->iotlb);
|
||||
/*
|
||||
* An attached PCI device may have memory listeners, eg. VFIO PCI.
|
||||
* The associated subregion will already have been unmapped in
|
||||
* s390_pci_iommu_disable in response to the guest deconfigure request.
|
||||
* Remove the listeners now before destroying the address space.
|
||||
*/
|
||||
address_space_remove_listeners(&iommu->as);
|
||||
address_space_destroy(&iommu->as);
|
||||
object_unparent(OBJECT(&iommu->mr));
|
||||
object_unparent(OBJECT(iommu));
|
||||
@@ -770,11 +777,11 @@ static void s390_pci_init_default_group(void)
|
||||
group = s390_group_create(ZPCI_DEFAULT_FN_GRP);
|
||||
resgrp = &group->zpci_group;
|
||||
resgrp->fr = 1;
|
||||
stq_p(&resgrp->dasm, 0);
|
||||
stq_p(&resgrp->msia, ZPCI_MSI_ADDR);
|
||||
stw_p(&resgrp->mui, DEFAULT_MUI);
|
||||
stw_p(&resgrp->i, 128);
|
||||
stw_p(&resgrp->maxstbl, 128);
|
||||
resgrp->dasm = 0;
|
||||
resgrp->msia = ZPCI_MSI_ADDR;
|
||||
resgrp->mui = DEFAULT_MUI;
|
||||
resgrp->i = 128;
|
||||
resgrp->maxstbl = 128;
|
||||
resgrp->version = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -281,7 +281,13 @@ int clp_service_call(S390CPU *cpu, uint8_t r2, uintptr_t ra)
|
||||
goto out;
|
||||
}
|
||||
|
||||
memcpy(resquery, &pbdev->zpci_fn, sizeof(*resquery));
|
||||
stq_p(&resquery->sdma, pbdev->zpci_fn.sdma);
|
||||
stq_p(&resquery->edma, pbdev->zpci_fn.edma);
|
||||
stw_p(&resquery->pchid, pbdev->zpci_fn.pchid);
|
||||
resquery->flags = pbdev->zpci_fn.flags;
|
||||
resquery->pfgid = pbdev->zpci_fn.pfgid;
|
||||
stl_p(&resquery->fid, pbdev->zpci_fn.fid);
|
||||
stl_p(&resquery->uid, pbdev->zpci_fn.uid);
|
||||
|
||||
for (i = 0; i < PCI_BAR_COUNT; i++) {
|
||||
uint32_t data = pci_get_long(pbdev->pdev->config +
|
||||
@@ -312,7 +318,13 @@ int clp_service_call(S390CPU *cpu, uint8_t r2, uintptr_t ra)
|
||||
stw_p(&resgrp->hdr.rsp, CLP_RC_QUERYPCIFG_PFGID);
|
||||
goto out;
|
||||
}
|
||||
memcpy(resgrp, &group->zpci_group, sizeof(ClpRspQueryPciGrp));
|
||||
resgrp->fr = group->zpci_group.fr;
|
||||
stq_p(&resgrp->dasm, group->zpci_group.dasm);
|
||||
stq_p(&resgrp->msia, group->zpci_group.msia);
|
||||
stw_p(&resgrp->mui, group->zpci_group.mui);
|
||||
stw_p(&resgrp->i, group->zpci_group.i);
|
||||
stw_p(&resgrp->maxstbl, group->zpci_group.maxstbl);
|
||||
resgrp->version = group->zpci_group.version;
|
||||
stw_p(&resgrp->hdr.rsp, CLP_RC_OK);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -156,12 +156,12 @@ static void s390_pci_read_group(S390PCIBusDevice *pbdev,
|
||||
if (cap->flags & VFIO_DEVICE_INFO_ZPCI_FLAG_REFRESH) {
|
||||
resgrp->fr = 1;
|
||||
}
|
||||
stq_p(&resgrp->dasm, cap->dasm);
|
||||
stq_p(&resgrp->msia, cap->msi_addr);
|
||||
stw_p(&resgrp->mui, cap->mui);
|
||||
stw_p(&resgrp->i, cap->noi);
|
||||
stw_p(&resgrp->maxstbl, cap->maxstbl);
|
||||
stb_p(&resgrp->version, cap->version);
|
||||
resgrp->dasm = cap->dasm;
|
||||
resgrp->msia = cap->msi_addr;
|
||||
resgrp->mui = cap->mui;
|
||||
resgrp->i = cap->noi;
|
||||
resgrp->maxstbl = cap->maxstbl;
|
||||
resgrp->version = cap->version;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -486,6 +486,10 @@ static void s390_machine_reset(MachineState *machine)
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
CPU_FOREACH(t) {
|
||||
run_on_cpu(t, s390_do_cpu_set_diag318, RUN_ON_CPU_HOST_ULONG(0));
|
||||
}
|
||||
s390_ipl_clear_reset_request();
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,6 @@ config USB_XHCI_NEC
|
||||
|
||||
config USB_XHCI_SYSBUS
|
||||
bool
|
||||
default y
|
||||
select USB_XHCI
|
||||
|
||||
config USB_MUSB
|
||||
|
||||
+7
-4
@@ -311,7 +311,7 @@ bool vfio_mig_active(void)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool vfio_devices_all_stopped_and_saving(VFIOContainer *container)
|
||||
static bool vfio_devices_all_saving(VFIOContainer *container)
|
||||
{
|
||||
VFIOGroup *group;
|
||||
VFIODevice *vbasedev;
|
||||
@@ -329,8 +329,11 @@ static bool vfio_devices_all_stopped_and_saving(VFIOContainer *container)
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((migration->device_state & VFIO_DEVICE_STATE_SAVING) &&
|
||||
!(migration->device_state & VFIO_DEVICE_STATE_RUNNING)) {
|
||||
if (migration->device_state & VFIO_DEVICE_STATE_SAVING) {
|
||||
if ((vbasedev->pre_copy_dirty_page_tracking == ON_OFF_AUTO_OFF)
|
||||
&& (migration->device_state & VFIO_DEVICE_STATE_RUNNING)) {
|
||||
return false;
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
return false;
|
||||
@@ -1125,7 +1128,7 @@ static void vfio_listerner_log_sync(MemoryListener *listener,
|
||||
return;
|
||||
}
|
||||
|
||||
if (vfio_devices_all_stopped_and_saving(container)) {
|
||||
if (vfio_devices_all_saving(container)) {
|
||||
vfio_sync_dirty_bitmap(container, section);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -535,7 +535,7 @@ void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
|
||||
}
|
||||
|
||||
/*
|
||||
* Assume we have no GMS memory, but allow it to be overrided by device
|
||||
* Assume we have no GMS memory, but allow it to be overridden by device
|
||||
* option (experimental). The spec doesn't actually allow zero GMS when
|
||||
* when IVD (IGD VGA Disable) is clear, but the claim is that it's unused,
|
||||
* so let's not waste VM memory for it.
|
||||
|
||||
+1
-1
@@ -882,7 +882,7 @@ int vfio_migration_probe(VFIODevice *vbasedev, Error **errp)
|
||||
Error *local_err = NULL;
|
||||
int ret = -ENOTSUP;
|
||||
|
||||
if (!container->dirty_pages_supported) {
|
||||
if (!vbasedev->enable_migration || !container->dirty_pages_supported) {
|
||||
goto add_blocker;
|
||||
}
|
||||
|
||||
|
||||
@@ -3182,6 +3182,9 @@ static void vfio_instance_init(Object *obj)
|
||||
static Property vfio_pci_dev_properties[] = {
|
||||
DEFINE_PROP_PCI_HOST_DEVADDR("host", VFIOPCIDevice, host),
|
||||
DEFINE_PROP_STRING("sysfsdev", VFIOPCIDevice, vbasedev.sysfsdev),
|
||||
DEFINE_PROP_ON_OFF_AUTO("x-pre-copy-dirty-page-tracking", VFIOPCIDevice,
|
||||
vbasedev.pre_copy_dirty_page_tracking,
|
||||
ON_OFF_AUTO_ON),
|
||||
DEFINE_PROP_ON_OFF_AUTO("display", VFIOPCIDevice,
|
||||
display, ON_OFF_AUTO_OFF),
|
||||
DEFINE_PROP_UINT32("xres", VFIOPCIDevice, display_xres, 0),
|
||||
@@ -3194,6 +3197,8 @@ static Property vfio_pci_dev_properties[] = {
|
||||
VFIO_FEATURE_ENABLE_REQ_BIT, true),
|
||||
DEFINE_PROP_BIT("x-igd-opregion", VFIOPCIDevice, features,
|
||||
VFIO_FEATURE_ENABLE_IGD_OPREGION_BIT, false),
|
||||
DEFINE_PROP_BOOL("x-enable-migration", VFIOPCIDevice,
|
||||
vbasedev.enable_migration, false),
|
||||
DEFINE_PROP_BOOL("x-no-mmap", VFIOPCIDevice, vbasedev.no_mmap, false),
|
||||
DEFINE_PROP_BOOL("x-balloon-allowed", VFIOPCIDevice,
|
||||
vbasedev.ram_block_discard_allowed, false),
|
||||
|
||||
+12
-6
@@ -501,6 +501,11 @@ typedef struct QEMU_PACKED NvmeCreateCq {
|
||||
#define NVME_CQ_FLAGS_PC(cq_flags) (cq_flags & 0x1)
|
||||
#define NVME_CQ_FLAGS_IEN(cq_flags) ((cq_flags >> 1) & 0x1)
|
||||
|
||||
enum NvmeFlagsCq {
|
||||
NVME_CQ_PC = 1,
|
||||
NVME_CQ_IEN = 2,
|
||||
};
|
||||
|
||||
typedef struct QEMU_PACKED NvmeCreateSq {
|
||||
uint8_t opcode;
|
||||
uint8_t flags;
|
||||
@@ -518,12 +523,13 @@ typedef struct QEMU_PACKED NvmeCreateSq {
|
||||
#define NVME_SQ_FLAGS_PC(sq_flags) (sq_flags & 0x1)
|
||||
#define NVME_SQ_FLAGS_QPRIO(sq_flags) ((sq_flags >> 1) & 0x3)
|
||||
|
||||
enum NvmeQueueFlags {
|
||||
NVME_Q_PC = 1,
|
||||
NVME_Q_PRIO_URGENT = 0,
|
||||
NVME_Q_PRIO_HIGH = 1,
|
||||
NVME_Q_PRIO_NORMAL = 2,
|
||||
NVME_Q_PRIO_LOW = 3,
|
||||
enum NvmeFlagsSq {
|
||||
NVME_SQ_PC = 1,
|
||||
|
||||
NVME_SQ_PRIO_URGENT = 0,
|
||||
NVME_SQ_PRIO_HIGH = 1,
|
||||
NVME_SQ_PRIO_NORMAL = 2,
|
||||
NVME_SQ_PRIO_LOW = 3,
|
||||
};
|
||||
|
||||
typedef struct QEMU_PACKED NvmeIdentify {
|
||||
|
||||
@@ -144,10 +144,10 @@ typedef struct ClpReqQueryPciGrp {
|
||||
ClpReqHdr hdr;
|
||||
uint32_t fmt;
|
||||
uint64_t reserved1;
|
||||
#define CLP_REQ_QPCIG_MASK_PFGID 0xff
|
||||
uint32_t g;
|
||||
uint32_t reserved2;
|
||||
uint64_t reserved3;
|
||||
uint8_t reserved2[3];
|
||||
uint8_t g;
|
||||
uint32_t reserved3;
|
||||
uint64_t reserved4;
|
||||
} QEMU_PACKED ClpReqQueryPciGrp;
|
||||
|
||||
/* Query PCI function group response */
|
||||
|
||||
@@ -123,12 +123,14 @@ typedef struct VFIODevice {
|
||||
bool needs_reset;
|
||||
bool no_mmap;
|
||||
bool ram_block_discard_allowed;
|
||||
bool enable_migration;
|
||||
VFIODeviceOps *ops;
|
||||
unsigned int num_irqs;
|
||||
unsigned int num_regions;
|
||||
unsigned int flags;
|
||||
VFIOMigration *migration;
|
||||
Error *migration_blocker;
|
||||
OnOffAuto pre_copy_dirty_page_tracking;
|
||||
} VFIODevice;
|
||||
|
||||
struct VFIODeviceOps {
|
||||
|
||||
@@ -199,6 +199,7 @@ extern const char *host_net_devices[];
|
||||
|
||||
/* from net.c */
|
||||
int net_client_parse(QemuOptsList *opts_list, const char *str);
|
||||
void show_netdevs(void);
|
||||
int net_init_clients(Error **errp);
|
||||
void net_check_clients(void);
|
||||
void net_cleanup(void);
|
||||
|
||||
@@ -205,6 +205,24 @@ do_kernel_trap(CPUARMState *env)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool insn_is_linux_bkpt(uint32_t opcode, bool is_thumb)
|
||||
{
|
||||
/*
|
||||
* Return true if this insn is one of the three magic UDF insns
|
||||
* which the kernel treats as breakpoint insns.
|
||||
*/
|
||||
if (!is_thumb) {
|
||||
return (opcode & 0x0fffffff) == 0x07f001f0;
|
||||
} else {
|
||||
/*
|
||||
* Note that we get the two halves of the 32-bit T32 insn
|
||||
* in the opposite order to the value the kernel uses in
|
||||
* its undef_hook struct.
|
||||
*/
|
||||
return ((opcode & 0xffff) == 0xde01) || (opcode == 0xa000f7f0);
|
||||
}
|
||||
}
|
||||
|
||||
void cpu_loop(CPUARMState *env)
|
||||
{
|
||||
CPUState *cs = env_cpu(env);
|
||||
@@ -234,6 +252,16 @@ void cpu_loop(CPUARMState *env)
|
||||
/* FIXME - what to do if get_user() fails? */
|
||||
get_user_code_u32(opcode, env->regs[15], env);
|
||||
|
||||
/*
|
||||
* The Linux kernel treats some UDF patterns specially
|
||||
* to use as breakpoints (instead of the architectural
|
||||
* bkpt insn). These should trigger a SIGTRAP rather
|
||||
* than SIGILL.
|
||||
*/
|
||||
if (insn_is_linux_bkpt(opcode, env->thumb)) {
|
||||
goto excp_debug;
|
||||
}
|
||||
|
||||
rc = EmulateAll(opcode, &ts->fpa, env);
|
||||
if (rc == 0) { /* illegal instruction */
|
||||
info.si_signo = TARGET_SIGILL;
|
||||
|
||||
+12
-8
@@ -490,10 +490,15 @@ if have_system and not get_option('curses').disabled()
|
||||
return 0;
|
||||
}'''
|
||||
|
||||
curses = dependency((targetos == 'windows' ? 'ncurses' : 'ncursesw'),
|
||||
required: false,
|
||||
method: 'pkg-config',
|
||||
static: enable_static)
|
||||
curses_dep_list = targetos == 'windows' ? ['ncurses', 'ncursesw'] : ['ncursesw']
|
||||
foreach curses_dep : curses_dep_list
|
||||
if not curses.found()
|
||||
curses = dependency(curses_dep,
|
||||
required: false,
|
||||
method: 'pkg-config',
|
||||
static: enable_static)
|
||||
endif
|
||||
endforeach
|
||||
msg = get_option('curses').enabled() ? 'curses library not found' : ''
|
||||
if curses.found()
|
||||
if cc.links(curses_test, dependencies: [curses])
|
||||
@@ -649,9 +654,8 @@ if get_option('vnc').enabled()
|
||||
vnc = declare_dependency() # dummy dependency
|
||||
png = dependency('libpng', required: get_option('vnc_png'),
|
||||
method: 'pkg-config', static: enable_static)
|
||||
jpeg = cc.find_library('jpeg', has_headers: ['jpeglib.h'],
|
||||
required: get_option('vnc_jpeg'),
|
||||
static: enable_static)
|
||||
jpeg = dependency('libjpeg', required: get_option('vnc_jpeg'),
|
||||
method: 'pkg-config', static: enable_static)
|
||||
sasl = cc.find_library('sasl2', has_headers: ['sasl/sasl.h'],
|
||||
required: get_option('vnc_sasl'),
|
||||
static: enable_static)
|
||||
@@ -1951,7 +1955,7 @@ if host_machine.system() == 'windows'
|
||||
'@OUTPUT@',
|
||||
get_option('prefix'),
|
||||
meson.current_source_dir(),
|
||||
host_machine.cpu_family(),
|
||||
host_machine.cpu(),
|
||||
'--',
|
||||
'-DDISPLAYVERSION=' + meson.project_version(),
|
||||
]
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "qemu/option.h"
|
||||
#include "qemu/timer.h"
|
||||
#include "qemu/sockets.h"
|
||||
#include "qemu/help_option.h"
|
||||
#include "monitor/monitor-internal.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qapi/clone-visitor.h"
|
||||
@@ -1631,7 +1632,12 @@ void hmp_netdev_add(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
Error *err = NULL;
|
||||
QemuOpts *opts;
|
||||
const char *type = qdict_get_try_str(qdict, "type");
|
||||
|
||||
if (type && is_help_option(type)) {
|
||||
show_netdevs();
|
||||
return;
|
||||
}
|
||||
opts = qemu_opts_from_qdict(qemu_find_opts("netdev"), qdict, &err);
|
||||
if (err) {
|
||||
goto out;
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
#include "qemu/config-file.h"
|
||||
#include "qemu/ctype.h"
|
||||
#include "qemu/iov.h"
|
||||
#include "qemu/qemu-print.h"
|
||||
#include "qemu/main-loop.h"
|
||||
#include "qemu/option.h"
|
||||
#include "qapi/error.h"
|
||||
@@ -411,10 +412,14 @@ void qemu_del_nic(NICState *nic)
|
||||
|
||||
qemu_macaddr_set_free(&nic->conf->macaddr);
|
||||
|
||||
/* If this is a peer NIC and peer has already been deleted, free it now. */
|
||||
if (nic->peer_deleted) {
|
||||
for (i = 0; i < queues; i++) {
|
||||
qemu_free_net_client(qemu_get_subqueue(nic, i)->peer);
|
||||
for (i = 0; i < queues; i++) {
|
||||
NetClientState *nc = qemu_get_subqueue(nic, i);
|
||||
/* If this is a peer NIC and peer has already been deleted, free it now. */
|
||||
if (nic->peer_deleted) {
|
||||
qemu_free_net_client(nc->peer);
|
||||
} else if (nc->peer) {
|
||||
/* if there are RX packets pending, complete them */
|
||||
qemu_purge_queued_packets(nc->peer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1025,7 +1030,7 @@ static int net_client_init1(const Netdev *netdev, bool is_netdev, Error **errp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void show_netdevs(void)
|
||||
void show_netdevs(void)
|
||||
{
|
||||
int idx;
|
||||
const char *available_netdevs[] = {
|
||||
@@ -1055,9 +1060,9 @@ static void show_netdevs(void)
|
||||
#endif
|
||||
};
|
||||
|
||||
printf("Available netdev backend types:\n");
|
||||
qemu_printf("Available netdev backend types:\n");
|
||||
for (idx = 0; idx < ARRAY_SIZE(available_netdevs); idx++) {
|
||||
puts(available_netdevs[idx]);
|
||||
qemu_printf("%s\n", available_netdevs[idx]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1068,42 +1073,35 @@ static int net_client_init(QemuOpts *opts, bool is_netdev, Error **errp)
|
||||
int ret = -1;
|
||||
Visitor *v = opts_visitor_new(opts);
|
||||
|
||||
const char *type = qemu_opt_get(opts, "type");
|
||||
/* Parse convenience option format ip6-net=fec0::0[/64] */
|
||||
const char *ip6_net = qemu_opt_get(opts, "ipv6-net");
|
||||
|
||||
if (is_netdev && type && is_help_option(type)) {
|
||||
show_netdevs();
|
||||
exit(0);
|
||||
} else {
|
||||
/* Parse convenience option format ip6-net=fec0::0[/64] */
|
||||
const char *ip6_net = qemu_opt_get(opts, "ipv6-net");
|
||||
if (ip6_net) {
|
||||
char *prefix_addr;
|
||||
unsigned long prefix_len = 64; /* Default 64bit prefix length. */
|
||||
|
||||
if (ip6_net) {
|
||||
char *prefix_addr;
|
||||
unsigned long prefix_len = 64; /* Default 64bit prefix length. */
|
||||
|
||||
substrings = g_strsplit(ip6_net, "/", 2);
|
||||
if (!substrings || !substrings[0]) {
|
||||
error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "ipv6-net",
|
||||
"a valid IPv6 prefix");
|
||||
goto out;
|
||||
}
|
||||
|
||||
prefix_addr = substrings[0];
|
||||
|
||||
/* Handle user-specified prefix length. */
|
||||
if (substrings[1] &&
|
||||
qemu_strtoul(substrings[1], NULL, 10, &prefix_len))
|
||||
{
|
||||
error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
|
||||
"ipv6-prefixlen", "a number");
|
||||
goto out;
|
||||
}
|
||||
|
||||
qemu_opt_set(opts, "ipv6-prefix", prefix_addr, &error_abort);
|
||||
qemu_opt_set_number(opts, "ipv6-prefixlen", prefix_len,
|
||||
&error_abort);
|
||||
qemu_opt_unset(opts, "ipv6-net");
|
||||
substrings = g_strsplit(ip6_net, "/", 2);
|
||||
if (!substrings || !substrings[0]) {
|
||||
error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "ipv6-net",
|
||||
"a valid IPv6 prefix");
|
||||
goto out;
|
||||
}
|
||||
|
||||
prefix_addr = substrings[0];
|
||||
|
||||
/* Handle user-specified prefix length. */
|
||||
if (substrings[1] &&
|
||||
qemu_strtoul(substrings[1], NULL, 10, &prefix_len))
|
||||
{
|
||||
error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
|
||||
"ipv6-prefixlen", "a number");
|
||||
goto out;
|
||||
}
|
||||
|
||||
qemu_opt_set(opts, "ipv6-prefix", prefix_addr, &error_abort);
|
||||
qemu_opt_set_number(opts, "ipv6-prefixlen", prefix_len,
|
||||
&error_abort);
|
||||
qemu_opt_unset(opts, "ipv6-net");
|
||||
}
|
||||
|
||||
/* Create an ID for -net if the user did not specify one */
|
||||
@@ -1421,6 +1419,12 @@ static int net_init_client(void *dummy, QemuOpts *opts, Error **errp)
|
||||
|
||||
static int net_init_netdev(void *dummy, QemuOpts *opts, Error **errp)
|
||||
{
|
||||
const char *type = qemu_opt_get(opts, "type");
|
||||
|
||||
if (type && is_help_option(type)) {
|
||||
show_netdevs();
|
||||
exit(0);
|
||||
}
|
||||
return net_client_init(opts, true, errp);
|
||||
}
|
||||
|
||||
|
||||
@@ -817,6 +817,7 @@ int net_init_tap(const Netdev *netdev, const char *name,
|
||||
if (ret < 0) {
|
||||
error_setg_errno(errp, -ret, "%s: Can't use file descriptor %d",
|
||||
name, fd);
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -831,6 +832,7 @@ int net_init_tap(const Netdev *netdev, const char *name,
|
||||
vhostfdname, vnet_hdr, fd, &err);
|
||||
if (err) {
|
||||
error_propagate(errp, err);
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
} else if (tap->has_fds) {
|
||||
@@ -951,7 +953,8 @@ free_fail:
|
||||
script = default_script = get_relocated_path(DEFAULT_NETWORK_SCRIPT);
|
||||
}
|
||||
if (!downscript) {
|
||||
downscript = default_downscript = get_relocated_path(DEFAULT_NETWORK_SCRIPT);
|
||||
downscript = default_downscript =
|
||||
get_relocated_path(DEFAULT_NETWORK_DOWN_SCRIPT);
|
||||
}
|
||||
|
||||
if (tap->has_ifname) {
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -100,6 +100,9 @@ static void make_readipl(void)
|
||||
{
|
||||
Ccw0 *ccwIplRead = (Ccw0 *)0x00;
|
||||
|
||||
/* Clear out any existing data */
|
||||
memset(ccwIplRead, 0, sizeof(Ccw0));
|
||||
|
||||
/* Create Read IPL ccw at address 0 */
|
||||
ccwIplRead->cmd_code = CCW_CMD_READ_IPL;
|
||||
ccwIplRead->cda = 0x00; /* Read into address 0x00 in main memory */
|
||||
|
||||
@@ -78,7 +78,7 @@ void jump_to_low_kernel(void)
|
||||
* kernel start address (when jumping to the PSW-at-zero address instead,
|
||||
* the kernel startup code fails when we booted from a network device).
|
||||
*/
|
||||
if (!memcmp((char *)0x10008, "S390EP", 6)) {
|
||||
if (!memcmp((char *)S390EP, "S390EP", 6)) {
|
||||
jump_to_IPL_code(KERN_IMAGE_START);
|
||||
}
|
||||
|
||||
|
||||
@@ -178,6 +178,12 @@ static void boot_setup(void)
|
||||
memcpy(lpmsg + 10, loadparm_str, 8);
|
||||
sclp_print(lpmsg);
|
||||
|
||||
/*
|
||||
* Clear out any potential S390EP magic (see jump_to_low_kernel()),
|
||||
* so we don't taint our decision-making process during a reboot.
|
||||
*/
|
||||
memset((char *)S390EP, 0, 6);
|
||||
|
||||
have_iplb = store_iplb(&iplb);
|
||||
}
|
||||
|
||||
|
||||
@@ -95,6 +95,9 @@ typedef struct LowCore {
|
||||
|
||||
extern LowCore *lowcore;
|
||||
|
||||
/* Location of "S390EP" in a Linux binary (see arch/s390/boot/head.S) */
|
||||
#define S390EP 0x10008
|
||||
|
||||
static inline void set_prefix(uint32_t address)
|
||||
{
|
||||
asm volatile("spx %0" : : "m" (address) : "memory");
|
||||
|
||||
Binary file not shown.
@@ -303,7 +303,8 @@ class QEMUMachine:
|
||||
return args
|
||||
|
||||
def _pre_launch(self) -> None:
|
||||
self._temp_dir = tempfile.mkdtemp(dir=self._test_dir)
|
||||
self._temp_dir = tempfile.mkdtemp(prefix="qemu-machine-",
|
||||
dir=self._test_dir)
|
||||
self._qemu_log_path = os.path.join(self._temp_dir, self._name + ".log")
|
||||
self._qemu_log_file = open(self._qemu_log_path, 'wb')
|
||||
|
||||
|
||||
+20
-18
@@ -913,8 +913,8 @@ SRST
|
||||
``-fda file``
|
||||
\
|
||||
``-fdb file``
|
||||
Use file as floppy disk 0/1 image (see
|
||||
:ref:`disk_005fimages`).
|
||||
Use file as floppy disk 0/1 image (see the :ref:`disk images` chapter in
|
||||
the System Emulation Users Guide).
|
||||
ERST
|
||||
|
||||
DEF("hda", HAS_ARG, QEMU_OPTION_hda,
|
||||
@@ -931,8 +931,8 @@ SRST
|
||||
``-hdc file``
|
||||
\
|
||||
``-hdd file``
|
||||
Use file as hard disk 0, 1, 2 or 3 image (see
|
||||
:ref:`disk_005fimages`).
|
||||
Use file as hard disk 0, 1, 2 or 3 image (see the :ref:`disk images`
|
||||
chapter in the System Emulation Users Guide).
|
||||
ERST
|
||||
|
||||
DEF("cdrom", HAS_ARG, QEMU_OPTION_cdrom,
|
||||
@@ -1189,9 +1189,9 @@ SRST
|
||||
In addition, it knows the following options:
|
||||
|
||||
``file=file``
|
||||
This option defines which disk image (see
|
||||
:ref:`disk_005fimages`) to use with this drive. If
|
||||
the filename contains comma, you must double it (for instance,
|
||||
This option defines which disk image (see the :ref:`disk images`
|
||||
chapter in the System Emulation Users Guide) to use with this drive.
|
||||
If the filename contains comma, you must double it (for instance,
|
||||
"file=my,,file" to use file "my,file").
|
||||
|
||||
Special files such as iSCSI devices can be specified using
|
||||
@@ -1400,8 +1400,8 @@ SRST
|
||||
``-snapshot``
|
||||
Write to temporary files instead of disk image files. In this case,
|
||||
the raw disk image you use is not written back. You can however
|
||||
force the write back by pressing C-a s (see
|
||||
:ref:`disk_005fimages`).
|
||||
force the write back by pressing C-a s (see the :ref:`disk images`
|
||||
chapter in the System Emulation Users Guide).
|
||||
ERST
|
||||
|
||||
DEF("fsdev", HAS_ARG, QEMU_OPTION_fsdev,
|
||||
@@ -1687,8 +1687,8 @@ DEF("usbdevice", HAS_ARG, QEMU_OPTION_usbdevice,
|
||||
SRST
|
||||
``-usbdevice devname``
|
||||
Add the USB device devname. Note that this option is deprecated,
|
||||
please use ``-device usb-...`` instead. See
|
||||
:ref:`usb_005fdevices`.
|
||||
please use ``-device usb-...`` instead. See the chapter about
|
||||
:ref:`Connecting USB devices` in the System Emulation Users Guide.
|
||||
|
||||
``mouse``
|
||||
Virtual Mouse. This will override the PS/2 mouse emulation when
|
||||
@@ -2110,7 +2110,7 @@ SRST
|
||||
connections.
|
||||
|
||||
The password must be set separately using the ``set_password``
|
||||
command in the :ref:`pcsys_005fmonitor`. The
|
||||
command in the :ref:`QEMU monitor`. The
|
||||
syntax to change your password is:
|
||||
``set_password <protocol> <password>`` where <protocol> could be
|
||||
either "vnc" or "spice".
|
||||
@@ -2155,8 +2155,8 @@ SRST
|
||||
and 'x509' settings to enable use of SSL and server
|
||||
certificates. This ensures a data encryption preventing
|
||||
compromise of authentication credentials. See the
|
||||
:ref:`vnc_005fsecurity` section for details on
|
||||
using SASL authentication.
|
||||
:ref:`VNC security` section in the System Emulation Users Guide
|
||||
for details on using SASL authentication.
|
||||
|
||||
``sasl-authz=ID``
|
||||
Provides the ID of the QAuthZ authorization object against which
|
||||
@@ -3082,7 +3082,9 @@ The general form of a character device option is:
|
||||
-serial chardev:char1
|
||||
|
||||
When you're using a multiplexed character device, some escape
|
||||
sequences are interpreted in the input. See :ref:`mux_005fkeys`.
|
||||
sequences are interpreted in the input. See the chapter about
|
||||
:ref:`keys in the character backend multiplexer` in the
|
||||
System Emulation Users Guide for more details.
|
||||
|
||||
Note that some other command line options may implicitly create
|
||||
multiplexed character backends; for instance ``-serial mon:stdio``
|
||||
@@ -3755,8 +3757,8 @@ DEF("gdb", HAS_ARG, QEMU_OPTION_gdb, \
|
||||
QEMU_ARCH_ALL)
|
||||
SRST
|
||||
``-gdb dev``
|
||||
Accept a gdb connection on device dev (see
|
||||
:ref:`gdb_005fusage`). Note that this option does not pause QEMU
|
||||
Accept a gdb connection on device dev (see the :ref:`GDB usage` chapter
|
||||
in the System Emulation Users Guide). Note that this option does not pause QEMU
|
||||
execution -- if you want QEMU to not start the guest until you
|
||||
connect with gdb and issue a ``continue`` command, you will need to
|
||||
also pass the ``-S`` option to QEMU.
|
||||
@@ -3781,7 +3783,7 @@ DEF("s", 0, QEMU_OPTION_s, \
|
||||
SRST
|
||||
``-s``
|
||||
Shorthand for -gdb tcp::1234, i.e. open a gdbserver on TCP port 1234
|
||||
(see :ref:`gdb_005fusage`).
|
||||
(see the :ref:`GDB usage` chapter in the System Emulation Users Guide).
|
||||
ERST
|
||||
|
||||
DEF("d", HAS_ARG, QEMU_OPTION_d, \
|
||||
|
||||
+19
-17
@@ -61,23 +61,25 @@ if targetos == 'windows'
|
||||
if 'CONFIG_QGA_VSS' in config_host and 'QEMU_GA_MSI_WITH_VSS' in config_host
|
||||
deps += qga_vss
|
||||
endif
|
||||
qga_msi = custom_target('QGA MSI',
|
||||
input: files('installer/qemu-ga.wxs'),
|
||||
output: 'qemu-ga-@0@.msi'.format(config_host['ARCH']),
|
||||
depends: deps,
|
||||
command: [
|
||||
find_program('env'),
|
||||
'QEMU_GA_VERSION=' + config_host['QEMU_GA_VERSION'],
|
||||
'QEMU_GA_MANUFACTURER=' + config_host['QEMU_GA_MANUFACTURER'],
|
||||
'QEMU_GA_DISTRO=' + config_host['QEMU_GA_DISTRO'],
|
||||
'BUILD_DIR=' + meson.build_root(),
|
||||
wixl, '-o', '@OUTPUT0@', '@INPUT0@',
|
||||
config_host['QEMU_GA_MSI_ARCH'].split(),
|
||||
config_host['QEMU_GA_MSI_WITH_VSS'].split(),
|
||||
config_host['QEMU_GA_MSI_MINGW_DLL_PATH'].split(),
|
||||
])
|
||||
all_qga += [qga_msi]
|
||||
alias_target('msi', qga_msi)
|
||||
if 'CONFIG_QGA_MSI' in config_host
|
||||
qga_msi = custom_target('QGA MSI',
|
||||
input: files('installer/qemu-ga.wxs'),
|
||||
output: 'qemu-ga-@0@.msi'.format(config_host['ARCH']),
|
||||
depends: deps,
|
||||
command: [
|
||||
find_program('env'),
|
||||
'QEMU_GA_VERSION=' + config_host['QEMU_GA_VERSION'],
|
||||
'QEMU_GA_MANUFACTURER=' + config_host['QEMU_GA_MANUFACTURER'],
|
||||
'QEMU_GA_DISTRO=' + config_host['QEMU_GA_DISTRO'],
|
||||
'BUILD_DIR=' + meson.build_root(),
|
||||
wixl, '-o', '@OUTPUT0@', '@INPUT0@',
|
||||
config_host['QEMU_GA_MSI_ARCH'].split(),
|
||||
config_host['QEMU_GA_MSI_WITH_VSS'].split(),
|
||||
config_host['QEMU_GA_MSI_MINGW_DLL_PATH'].split(),
|
||||
])
|
||||
all_qga += [qga_msi]
|
||||
alias_target('msi', qga_msi)
|
||||
endif
|
||||
endif
|
||||
else
|
||||
install_subdir('run', install_dir: get_option('localstatedir'))
|
||||
|
||||
+6
-2
@@ -186,9 +186,13 @@ opensbi64-generic:
|
||||
cp opensbi/build/platform/generic/firmware/fw_dynamic.bin ../pc-bios/opensbi-riscv64-generic-fw_dynamic.bin
|
||||
cp opensbi/build/platform/generic/firmware/fw_dynamic.elf ../pc-bios/opensbi-riscv64-generic-fw_dynamic.elf
|
||||
|
||||
MESON = meson
|
||||
NINJA = ninja
|
||||
qboot:
|
||||
$(MAKE) -C qboot
|
||||
cp qboot/bios.bin ../pc-bios/qboot.rom
|
||||
mkdir -p qboot/build
|
||||
$(MESON) setup $(if $(wildcard qboot/build/meson-private),--wipe,) qboot qboot/build
|
||||
$(NINJA) -C qboot/build
|
||||
cp qboot/build/bios.bin ../pc-bios/qboot.rom
|
||||
|
||||
npcm7xx_bootrom:
|
||||
$(MAKE) -C vbootrom CROSS_COMPILE=$(arm_cross_prefix)
|
||||
|
||||
+1
-1
Submodule roms/qboot updated: cb1c49e0cf...a5300c4949.
@@ -31,7 +31,7 @@ class NoPipelineFound(Exception):
|
||||
"""Communication is successfull but pipeline is not found."""
|
||||
|
||||
|
||||
def get_local_branch_commit(branch='staging'):
|
||||
def get_local_branch_commit(branch):
|
||||
"""
|
||||
Returns the commit sha1 for the *local* branch named "staging"
|
||||
"""
|
||||
@@ -126,18 +126,16 @@ def create_parser():
|
||||
help=('The GitLab project ID. Defaults to the project '
|
||||
'for https://gitlab.com/qemu-project/qemu, that '
|
||||
'is, "%(default)s"'))
|
||||
try:
|
||||
default_commit = get_local_branch_commit()
|
||||
commit_required = False
|
||||
except ValueError:
|
||||
default_commit = ''
|
||||
commit_required = True
|
||||
parser.add_argument('-c', '--commit', required=commit_required,
|
||||
default=default_commit,
|
||||
parser.add_argument('-b', '--branch', type=str, default="staging",
|
||||
help=('Specify the branch to check. '
|
||||
'Use HEAD for your current branch. '
|
||||
'Otherwise looks at "%(default)s"'))
|
||||
parser.add_argument('-c', '--commit',
|
||||
default=None,
|
||||
help=('Look for a pipeline associated with the given '
|
||||
'commit. If one is not explicitly given, the '
|
||||
'commit associated with the local branch named '
|
||||
'"staging" is used. Default: %(default)s'))
|
||||
'commit associated with the default branch '
|
||||
'is used.'))
|
||||
parser.add_argument('--verbose', action='store_true', default=False,
|
||||
help=('A minimal verbosity level that prints the '
|
||||
'overall result of the check/wait'))
|
||||
@@ -149,6 +147,10 @@ def main():
|
||||
"""
|
||||
parser = create_parser()
|
||||
args = parser.parse_args()
|
||||
|
||||
if not args.commit:
|
||||
args.commit = get_local_branch_commit(args.branch)
|
||||
|
||||
success = False
|
||||
try:
|
||||
if args.wait:
|
||||
|
||||
+1
-1
@@ -65,7 +65,7 @@ def main():
|
||||
dlldir = "w64"
|
||||
makensis += ["-DW64"]
|
||||
if os.path.exists(os.path.join(args.srcdir, "dll")):
|
||||
makensis += "-DDLLDIR={0}/dll/{1}".format(args.srcdir, dlldir)
|
||||
makensis += ["-DDLLDIR={0}/dll/{1}".format(args.srcdir, dlldir)]
|
||||
|
||||
makensis += ["-DOUTFILE=" + args.outfile] + args.nsisargs
|
||||
subprocess.run(makensis)
|
||||
|
||||
+1
-1
Submodule slirp updated: ce94eba204...8f43a99191.
+9
-2
@@ -205,8 +205,15 @@ static bool memory_region_ioeventfd_before(MemoryRegionIoeventfd *a,
|
||||
static bool memory_region_ioeventfd_equal(MemoryRegionIoeventfd *a,
|
||||
MemoryRegionIoeventfd *b)
|
||||
{
|
||||
return !memory_region_ioeventfd_before(a, b)
|
||||
&& !memory_region_ioeventfd_before(b, a);
|
||||
if (int128_eq(a->addr.start, b->addr.start) &&
|
||||
(!int128_nz(a->addr.size) || !int128_nz(b->addr.size) ||
|
||||
(int128_eq(a->addr.size, b->addr.size) &&
|
||||
(a->match_data == b->match_data) &&
|
||||
((a->match_data && (a->data == b->data)) || !a->match_data) &&
|
||||
(a->e == b->e))))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Range of memory in the global map. Addresses are absolute. */
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#else
|
||||
#include "exec/gdbstub.h"
|
||||
#include "qemu/cutils.h"
|
||||
#include "hw/arm/boot.h"
|
||||
#endif
|
||||
|
||||
#define TARGET_SYS_OPEN 0x01
|
||||
@@ -1014,6 +1015,9 @@ target_ulong do_arm_semihosting(CPUARMState *env)
|
||||
int i;
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
TaskState *ts = cs->opaque;
|
||||
#else
|
||||
const struct arm_boot_info *info = env->boot_info;
|
||||
target_ulong rambase = info->loader_start;
|
||||
#endif
|
||||
|
||||
GET_ARG(0);
|
||||
@@ -1046,10 +1050,10 @@ target_ulong do_arm_semihosting(CPUARMState *env)
|
||||
#else
|
||||
limit = ram_size;
|
||||
/* TODO: Make this use the limit of the loaded application. */
|
||||
retvals[0] = limit / 2;
|
||||
retvals[1] = limit;
|
||||
retvals[2] = limit; /* Stack base */
|
||||
retvals[3] = 0; /* Stack limit. */
|
||||
retvals[0] = rambase + limit / 2;
|
||||
retvals[1] = rambase + limit;
|
||||
retvals[2] = rambase + limit; /* Stack base */
|
||||
retvals[3] = rambase; /* Stack limit. */
|
||||
#endif
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(retvals); i++) {
|
||||
|
||||
+2
-2
@@ -40,7 +40,7 @@
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
|
||||
static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
|
||||
static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
|
||||
MMUAccessType access_type, ARMMMUIdx mmu_idx,
|
||||
bool s1_is_el0,
|
||||
hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot,
|
||||
@@ -10988,7 +10988,7 @@ static ARMVAParameters aa32_va_parameters(CPUARMState *env, uint32_t va,
|
||||
* @fi: set to fault info if the translation fails
|
||||
* @cacheattrs: (if non-NULL) set to the cacheability/shareability attributes
|
||||
*/
|
||||
static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
|
||||
static bool get_phys_addr_lpae(CPUARMState *env, uint64_t address,
|
||||
MMUAccessType access_type, ARMMMUIdx mmu_idx,
|
||||
bool s1_is_el0,
|
||||
hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot,
|
||||
|
||||
@@ -214,16 +214,16 @@ static inline uint32_t x86_call_gate_offset(x86_call_gate *gate)
|
||||
return (uint32_t)((gate->offset1 << 16) | gate->offset0);
|
||||
}
|
||||
|
||||
#define LDT_SEL 0
|
||||
#define GDT_SEL 1
|
||||
#define GDT_SEL 0
|
||||
#define LDT_SEL 1
|
||||
|
||||
typedef struct x68_segment_selector {
|
||||
union {
|
||||
uint16_t sel;
|
||||
struct {
|
||||
uint16_t rpl:3;
|
||||
uint16_t rpl:2;
|
||||
uint16_t ti:1;
|
||||
uint16_t index:12;
|
||||
uint16_t index:13;
|
||||
};
|
||||
};
|
||||
} __attribute__ ((__packed__)) x68_segment_selector;
|
||||
|
||||
@@ -122,6 +122,10 @@ uint32_t hvf_get_supported_cpuid(uint32_t func, uint32_t idx,
|
||||
CPUID_PAT | CPUID_PSE36 | CPUID_EXT2_MMXEXT | CPUID_MMX |
|
||||
CPUID_FXSR | CPUID_EXT2_FXSR | CPUID_EXT2_PDPE1GB | CPUID_EXT2_3DNOWEXT |
|
||||
CPUID_EXT2_3DNOW | CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX;
|
||||
hv_vmx_read_capability(HV_VMX_CAP_PROCBASED2, &cap);
|
||||
if (!(cap & CPU_BASED2_RDTSCP)) {
|
||||
edx &= ~CPUID_EXT2_RDTSCP;
|
||||
}
|
||||
hv_vmx_read_capability(HV_VMX_CAP_PROCBASED, &cap);
|
||||
if (!(cap & CPU_BASED_TSC_OFFSET)) {
|
||||
edx &= ~CPUID_EXT2_RDTSCP;
|
||||
|
||||
@@ -139,6 +139,36 @@ static void gen_lxvw4x(DisasContext *ctx)
|
||||
tcg_temp_free_i64(xtl);
|
||||
}
|
||||
|
||||
static void gen_lxvwsx(DisasContext *ctx)
|
||||
{
|
||||
TCGv EA;
|
||||
TCGv_i32 data;
|
||||
|
||||
if (xT(ctx->opcode) < 32) {
|
||||
if (unlikely(!ctx->vsx_enabled)) {
|
||||
gen_exception(ctx, POWERPC_EXCP_VSXU);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (unlikely(!ctx->altivec_enabled)) {
|
||||
gen_exception(ctx, POWERPC_EXCP_VPU);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
gen_set_access_type(ctx, ACCESS_INT);
|
||||
EA = tcg_temp_new();
|
||||
|
||||
gen_addr_reg_index(ctx, EA);
|
||||
|
||||
data = tcg_temp_new_i32();
|
||||
tcg_gen_qemu_ld_i32(data, EA, ctx->mem_idx, MO_TEUL);
|
||||
tcg_gen_gvec_dup_i32(MO_UL, vsr_full_offset(xT(ctx->opcode)), 16, 16, data);
|
||||
|
||||
tcg_temp_free(EA);
|
||||
tcg_temp_free_i32(data);
|
||||
}
|
||||
|
||||
static void gen_bswap16x8(TCGv_i64 outh, TCGv_i64 outl,
|
||||
TCGv_i64 inh, TCGv_i64 inl)
|
||||
{
|
||||
|
||||
@@ -5,6 +5,7 @@ GEN_HANDLER_E(lxsibzx, 0x1F, 0x0D, 0x18, 0, PPC_NONE, PPC2_ISA300),
|
||||
GEN_HANDLER_E(lxsihzx, 0x1F, 0x0D, 0x19, 0, PPC_NONE, PPC2_ISA300),
|
||||
GEN_HANDLER_E(lxsspx, 0x1F, 0x0C, 0x10, 0, PPC_NONE, PPC2_VSX207),
|
||||
GEN_HANDLER_E(lxvd2x, 0x1F, 0x0C, 0x1A, 0, PPC_NONE, PPC2_VSX),
|
||||
GEN_HANDLER_E(lxvwsx, 0x1F, 0x0C, 0x0B, 0, PPC_NONE, PPC2_ISA300),
|
||||
GEN_HANDLER_E(lxvdsx, 0x1F, 0x0C, 0x0A, 0, PPC_NONE, PPC2_VSX),
|
||||
GEN_HANDLER_E(lxvw4x, 0x1F, 0x0C, 0x18, 0, PPC_NONE, PPC2_VSX),
|
||||
GEN_HANDLER_E(lxvh8x, 0x1F, 0x0C, 0x19, 0, PPC_NONE, PPC2_ISA300),
|
||||
|
||||
@@ -447,6 +447,13 @@ void s390_enable_css_support(S390CPU *cpu)
|
||||
kvm_s390_enable_css_support(cpu);
|
||||
}
|
||||
}
|
||||
|
||||
void s390_do_cpu_set_diag318(CPUState *cs, run_on_cpu_data arg)
|
||||
{
|
||||
if (kvm_enabled()) {
|
||||
kvm_s390_set_diag318(cs, arg.host_ulong);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static gchar *s390_gdb_arch_name(CPUState *cs)
|
||||
|
||||
@@ -769,6 +769,7 @@ int s390_set_memory_limit(uint64_t new_limit, uint64_t *hw_limit);
|
||||
void s390_set_max_pagesize(uint64_t pagesize, Error **errp);
|
||||
void s390_cmma_reset(void);
|
||||
void s390_enable_css_support(S390CPU *cpu);
|
||||
void s390_do_cpu_set_diag318(CPUState *cs, run_on_cpu_data arg);
|
||||
int s390_assign_subch_ioeventfd(EventNotifier *notifier, uint32_t sch_id,
|
||||
int vq, bool assign);
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
|
||||
@@ -120,3 +120,7 @@ void kvm_s390_stop_interrupt(S390CPU *cpu)
|
||||
void kvm_s390_restart_interrupt(S390CPU *cpu)
|
||||
{
|
||||
}
|
||||
|
||||
void kvm_s390_set_diag318(CPUState *cs, uint64_t diag318_info)
|
||||
{
|
||||
}
|
||||
+17
-5
@@ -1611,10 +1611,23 @@ static int handle_sw_breakpoint(S390CPU *cpu, struct kvm_run *run)
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
void kvm_s390_set_diag318(CPUState *cs, uint64_t diag318_info)
|
||||
{
|
||||
CPUS390XState *env = &S390_CPU(cs)->env;
|
||||
|
||||
/* Feat bit is set only if KVM supports sync for diag318 */
|
||||
if (s390_has_feat(S390_FEAT_DIAG_318)) {
|
||||
env->diag318_info = diag318_info;
|
||||
cs->kvm_run->s.regs.diag318 = diag318_info;
|
||||
cs->kvm_run->kvm_dirty_regs |= KVM_SYNC_DIAG318;
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_diag_318(S390CPU *cpu, struct kvm_run *run)
|
||||
{
|
||||
uint64_t reg = (run->s390_sieic.ipa & 0x00f0) >> 4;
|
||||
uint64_t diag318_info = run->s.regs.gprs[reg];
|
||||
CPUState *t;
|
||||
|
||||
/*
|
||||
* DIAG 318 can only be enabled with KVM support. As such, let's
|
||||
@@ -1622,13 +1635,12 @@ static void handle_diag_318(S390CPU *cpu, struct kvm_run *run)
|
||||
*/
|
||||
if (!s390_has_feat(S390_FEAT_DIAG_318)) {
|
||||
kvm_s390_program_interrupt(cpu, PGM_SPECIFICATION);
|
||||
return;
|
||||
}
|
||||
|
||||
cpu->env.diag318_info = diag318_info;
|
||||
|
||||
if (can_sync_regs(CPU(cpu), KVM_SYNC_DIAG318)) {
|
||||
run->s.regs.diag318 = diag318_info;
|
||||
run->kvm_dirty_regs |= KVM_SYNC_DIAG318;
|
||||
CPU_FOREACH(t) {
|
||||
run_on_cpu(t, s390_do_cpu_set_diag318,
|
||||
RUN_ON_CPU_HOST_ULONG(diag318_info));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -45,5 +45,6 @@ void kvm_s390_set_max_pagesize(uint64_t pagesize, Error **errp);
|
||||
void kvm_s390_crypto_reset(void);
|
||||
void kvm_s390_restart_interrupt(S390CPU *cpu);
|
||||
void kvm_s390_stop_interrupt(S390CPU *cpu);
|
||||
void kvm_s390_set_diag318(CPUState *cs, uint64_t diag318_info);
|
||||
|
||||
#endif /* KVM_S390X_H */
|
||||
@@ -171,7 +171,8 @@ class Test(avocado.Test):
|
||||
self.cancel("No QEMU binary defined or found in the build tree")
|
||||
|
||||
def _new_vm(self, *args):
|
||||
vm = QEMUMachine(self.qemu_bin, sock_dir=tempfile.mkdtemp())
|
||||
self._sd = tempfile.TemporaryDirectory(prefix="avo_qemu_sock_")
|
||||
vm = QEMUMachine(self.qemu_bin, sock_dir=self._sd.name)
|
||||
if args:
|
||||
vm.add_args(*args)
|
||||
return vm
|
||||
@@ -192,6 +193,7 @@ class Test(avocado.Test):
|
||||
def tearDown(self):
|
||||
for vm in self._vms.values():
|
||||
vm.shutdown()
|
||||
self._sd = None
|
||||
|
||||
def fetch_asset(self, name,
|
||||
asset_hash=None, algorithm=None,
|
||||
|
||||
@@ -30,7 +30,6 @@ RUN apt update && \
|
||||
pkg-config \
|
||||
psmisc \
|
||||
python3 \
|
||||
python3-setuptools \
|
||||
python3-sphinx \
|
||||
$(apt-get -s build-dep qemu | egrep ^Inst | fgrep '[all]' | cut -d\ -f2)
|
||||
|
||||
|
||||
Loaded 100 of 115 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user