Skip to content

Commit 78eedc6

Browse files
davidhildenbrandhuth
authored andcommitted
hw/s390x/s390-skeys: use memory mapping to detect which storage keys to dump
Handle it similar to migration. Assert that we're holding the BQL, to make sure we don't see concurrent modifications. Signed-off-by: David Hildenbrand <[email protected]> Reviewed-by: Thomas Huth <[email protected]> Message-Id: <[email protected]> Signed-off-by: Thomas Huth <[email protected]>
1 parent 67db130 commit 78eedc6

File tree

1 file changed

+30
-20
lines changed

1 file changed

+30
-20
lines changed

hw/s390x/s390-skeys.c

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -110,11 +110,10 @@ void qmp_dump_skeys(const char *filename, Error **errp)
110110
{
111111
S390SKeysState *ss = s390_get_skeys_device();
112112
S390SKeysClass *skeyclass = S390_SKEYS_GET_CLASS(ss);
113-
MachineState *ms = MACHINE(qdev_get_machine());
114-
const uint64_t total_count = ms->ram_size / TARGET_PAGE_SIZE;
115-
uint64_t handled_count = 0, cur_count;
113+
GuestPhysBlockList guest_phys_blocks;
114+
GuestPhysBlock *block;
115+
uint64_t pages, gfn;
116116
Error *lerr = NULL;
117-
vaddr cur_gfn = 0;
118117
uint8_t *buf;
119118
int ret;
120119
int fd;
@@ -145,28 +144,39 @@ void qmp_dump_skeys(const char *filename, Error **errp)
145144
goto out;
146145
}
147146

148-
/* we'll only dump initial memory for now */
149-
while (handled_count < total_count) {
150-
/* Calculate how many keys to ask for & handle overflow case */
151-
cur_count = MIN(total_count - handled_count, S390_SKEYS_BUFFER_SIZE);
147+
assert(qemu_mutex_iothread_locked());
148+
guest_phys_blocks_init(&guest_phys_blocks);
149+
guest_phys_blocks_append(&guest_phys_blocks);
152150

153-
ret = skeyclass->get_skeys(ss, cur_gfn, cur_count, buf);
154-
if (ret < 0) {
155-
error_setg(errp, "get_keys error %d", ret);
156-
goto out_free;
157-
}
151+
QTAILQ_FOREACH(block, &guest_phys_blocks.head, next) {
152+
assert(QEMU_IS_ALIGNED(block->target_start, TARGET_PAGE_SIZE));
153+
assert(QEMU_IS_ALIGNED(block->target_end, TARGET_PAGE_SIZE));
158154

159-
/* write keys to stream */
160-
write_keys(f, buf, cur_gfn, cur_count, &lerr);
161-
if (lerr) {
162-
goto out_free;
163-
}
155+
gfn = block->target_start / TARGET_PAGE_SIZE;
156+
pages = (block->target_end - block->target_start) / TARGET_PAGE_SIZE;
164157

165-
cur_gfn += cur_count;
166-
handled_count += cur_count;
158+
while (pages) {
159+
const uint64_t cur_pages = MIN(pages, S390_SKEYS_BUFFER_SIZE);
160+
161+
ret = skeyclass->get_skeys(ss, gfn, cur_pages, buf);
162+
if (ret < 0) {
163+
error_setg_errno(errp, -ret, "get_keys error");
164+
goto out_free;
165+
}
166+
167+
/* write keys to stream */
168+
write_keys(f, buf, gfn, cur_pages, &lerr);
169+
if (lerr) {
170+
goto out_free;
171+
}
172+
173+
gfn += cur_pages;
174+
pages -= cur_pages;
175+
}
167176
}
168177

169178
out_free:
179+
guest_phys_blocks_free(&guest_phys_blocks);
170180
error_propagate(errp, lerr);
171181
g_free(buf);
172182
out:

0 commit comments

Comments
 (0)