dump: use system context in Windows dump
We use CPU #0 to access guest virtual memory, but it can execute user thread at that moment. So, switch CR3 to PageDirectoryBase from header and restore original value at the end. Signed-off-by: Viktor Prutyanov <viktor.prutyanov@virtuozzo.com> Message-Id: <20180517162342.4330-3-viktor.prutyanov@virtuozzo.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
2da91b54fe
commit
92d1b3d508
26
win_dump.c
26
win_dump.c
@ -111,12 +111,6 @@ static void patch_header(WinDumpHeader64 *h)
|
|||||||
h->PhysicalMemoryBlock.unused = 0;
|
h->PhysicalMemoryBlock.unused = 0;
|
||||||
h->unused1 = 0;
|
h->unused1 = 0;
|
||||||
|
|
||||||
/*
|
|
||||||
* We assume h->DirectoryBase and current CR3 are the same when we access
|
|
||||||
* memory by virtual address. In other words, we suppose current context
|
|
||||||
* is system context. It is definetely true in case of BSOD.
|
|
||||||
*/
|
|
||||||
|
|
||||||
patch_mm_pfn_database(h, &local_err);
|
patch_mm_pfn_database(h, &local_err);
|
||||||
if (local_err) {
|
if (local_err) {
|
||||||
warn_report_err(local_err);
|
warn_report_err(local_err);
|
||||||
@ -171,6 +165,8 @@ void create_win_dump(DumpState *s, Error **errp)
|
|||||||
{
|
{
|
||||||
WinDumpHeader64 *h = (WinDumpHeader64 *)(s->guest_note +
|
WinDumpHeader64 *h = (WinDumpHeader64 *)(s->guest_note +
|
||||||
VMCOREINFO_ELF_NOTE_HDR_SIZE);
|
VMCOREINFO_ELF_NOTE_HDR_SIZE);
|
||||||
|
X86CPU *first_x86_cpu = X86_CPU(first_cpu);
|
||||||
|
uint64_t saved_cr3 = first_x86_cpu->env.cr[3];
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
|
|
||||||
if (s->guest_note_size != sizeof(WinDumpHeader64) +
|
if (s->guest_note_size != sizeof(WinDumpHeader64) +
|
||||||
@ -185,10 +181,17 @@ void create_win_dump(DumpState *s, Error **errp)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Further access to kernel structures by virtual addresses
|
||||||
|
* should be made from system context.
|
||||||
|
*/
|
||||||
|
|
||||||
|
first_x86_cpu->env.cr[3] = h->DirectoryTableBase;
|
||||||
|
|
||||||
check_kdbg(h, &local_err);
|
check_kdbg(h, &local_err);
|
||||||
if (local_err) {
|
if (local_err) {
|
||||||
error_propagate(errp, local_err);
|
error_propagate(errp, local_err);
|
||||||
return;
|
goto out_cr3;
|
||||||
}
|
}
|
||||||
|
|
||||||
patch_header(h);
|
patch_header(h);
|
||||||
@ -198,12 +201,17 @@ void create_win_dump(DumpState *s, Error **errp)
|
|||||||
s->written_size = qemu_write_full(s->fd, h, sizeof(*h));
|
s->written_size = qemu_write_full(s->fd, h, sizeof(*h));
|
||||||
if (s->written_size != sizeof(*h)) {
|
if (s->written_size != sizeof(*h)) {
|
||||||
error_setg(errp, QERR_IO_ERROR);
|
error_setg(errp, QERR_IO_ERROR);
|
||||||
return;
|
goto out_cr3;
|
||||||
}
|
}
|
||||||
|
|
||||||
write_runs(s, h, &local_err);
|
write_runs(s, h, &local_err);
|
||||||
if (local_err) {
|
if (local_err) {
|
||||||
error_propagate(errp, local_err);
|
error_propagate(errp, local_err);
|
||||||
return;
|
goto out_cr3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out_cr3:
|
||||||
|
first_x86_cpu->env.cr[3] = saved_cr3;
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user