Skip to content
This repository was archived by the owner on Jan 28, 2023. It is now read-only.

Do not allow guest direct access to CR8 #145

Merged
merged 2 commits into from
Dec 14, 2018
Merged

Do not allow guest direct access to CR8 #145

merged 2 commits into from
Dec 14, 2018

Conversation

raphaelning
Copy link
Contributor

@raphaelning raphaelning commented Dec 13, 2018

Currently, HAXM allows the guest to freely read/write CR8 via the
MOV from/to CR8 instructions, and does not save/restore host CR8
state. But some host OSes are sensitive to unexpected CR8 changes:
for instance, Windows x86_64 stores the current IRQL in CR8, and
if the guest (e.g. NetBSD) overwrites CR8 with a smaller value, the
host will crash (BSOD) shortly after the next VM exit.

Fix this problem by making HAXM intercept every guest access to
CR8: write requests are ignored (hardware/host CR8 untouched),
whereas read requests are serviced using a dummy handler that
always returns 0. This is a hacky approach, but since most guest
OSes do not rely on CR8 (e.g. NetBSD writes 0 to CR8 during boot,
but does not seem to care about the outcome), it is an acceptable
expedient. Proper CR8 virtualization would probably require
collaboration with user space, because CR8 is merely an alias for
APIC.TPR[7:4] (cf. Intel SDM Vol. 3A 10.8.6.1), and APIC emulation
is provided by user space (QEMU).

Fixes #136.

Signed-off-by: Yu Ning yu.ning@intel.com

@krytarowski
Copy link
Contributor

It looks like CR8 is set to 0 during boot.

https://nxr.netbsd.org/xref/src/sys/arch/x86/x86/lapic.c#198 lapic_write_tpri()
https://nxr.netbsd.org/xref/src/sys/arch/amd64/amd64/autoconf.c#116 cpu_configure()

CR8 is never read by the NetBSD kernel.

@krytarowski
Copy link
Contributor

This should be beneficial also for OpenBSD. They set CR8 to 0 on boot and never read it.

http://src.illumos.org/source/xref/openbsd-src/sys/arch/amd64/amd64/cpu.c#811
http://src.illumos.org/source/xref/openbsd-src/sys/arch/amd64/amd64/autoconf.c#133

@raphaelning
Copy link
Contributor Author

Thanks, but I ran qemu-system-x86_64.exe -accel hax -cdrom NetBSD-8.0-amd64.iso -m 1G -display gtk and saw the following in HAXM driver log:

haxm_warning:Ignored unsupported CR8 read, returning 0
haxm_warning:Ignored guest CR8 write, val=0x0
haxm_warning:Ignored unsupported CR8 read, returning 0
haxm_warning:Ignored guest CR8 write, val=0x0
haxm_error:
...........hax_teardown_vm

The "unsupported CR8 read" warning is from this PR:

hax_warning("Ignored unsupported CR%d read, returning 0\n", n);

@krytarowski
Copy link
Contributor

This patch looks good to me. (not sure if I can accept)

@raphaelning
Copy link
Contributor Author

@krytarowski Thanks, we'll run some tests and merge it (probably tomorrow).

@raphaelning
Copy link
Contributor Author

@krytarowski You were right, NetBSD never reads CR8. I've fixed the bogus HAXM warning.

Currently, HAXM allows the guest to freely read/write CR8 via the
MOV from/to CR8 instructions, and does not save/restore host CR8
state. But some host OSes are sensitive to unexpected CR8 changes:
for instance, Windows x86_64 stores the current IRQL in CR8, and
if the guest (e.g. NetBSD) overwrites CR8 with a smaller value, the
host will crash (BSOD) shortly after the next VM exit.

Fix this problem by making HAXM intercept every guest access to
CR8: write requests are ignored (hardware/host CR8 untouched),
whereas read requests are serviced using a dummy handler that
always returns 0. This is a hacky approach, but since most guest
OSes do not rely on CR8 (e.g. NetBSD writes 0 to CR8 during boot,
but does not seem to care about the outcome), it is an acceptable
expedient. Proper CR8 virtualization would probably require
collaboration with user space, because CR8 is merely an alias for
APIC.TPR[7:4] (cf. Intel SDM Vol. 3A 10.8.6.1), and APIC emulation
is provided by user space (QEMU).

Fixes #136.

Signed-off-by: Yu Ning <yu.ning@intel.com>
Refactor the VM exit handler for CR access to drop unnecessary
vcpu_read_cr() calls. This can avoid a bogus "unsupported CR8 read"
error message when the guest only writes to CR8.

Signed-off-by: Yu Ning <yu.ning@intel.com>
@wcwang wcwang merged commit 192cd52 into master Dec 14, 2018
@raphaelning raphaelning deleted the cr8-trap branch January 15, 2019 09:48
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants