git: 51fda658baa3 - main - vmm: Properly handle writes spanning across two pages in vm_handle_db
Date: Wed, 02 Oct 2024 16:45:04 UTC
The branch main has been updated by bnovkov: URL: https://cgit.FreeBSD.org/src/commit/?id=51fda658baa3f80c9778f3a9873fbf67df87119b commit 51fda658baa3f80c9778f3a9873fbf67df87119b Author: Bojan Novković <bnovkov@FreeBSD.org> AuthorDate: 2024-09-29 11:10:10 +0000 Commit: Bojan Novković <bnovkov@FreeBSD.org> CommitDate: 2024-10-02 16:43:36 +0000 vmm: Properly handle writes spanning across two pages in vm_handle_db The vm_handle_db function is responsible for writing correct status register values into memory when a guest VM is being single-stepped using the RFLAGS.TF mechanism. However, it currently does not properly handle an edge case where the resulting write spans across two pages. This commit fixes this by making vm_handle_db use two vm_copy_info structs. Security: HYP-09 Reviewed by: markj --- sys/amd64/vmm/vmm.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sys/amd64/vmm/vmm.c b/sys/amd64/vmm/vmm.c index a2c2b342bee4..5484d71cefd2 100644 --- a/sys/amd64/vmm/vmm.c +++ b/sys/amd64/vmm/vmm.c @@ -1795,7 +1795,7 @@ vm_handle_db(struct vcpu *vcpu, struct vm_exit *vme, bool *retu) int error, fault; uint64_t rsp; uint64_t rflags; - struct vm_copyinfo copyinfo; + struct vm_copyinfo copyinfo[2]; *retu = true; if (!vme->u.dbg.pushf_intercept || vme->u.dbg.tf_shadow_val != 0) { @@ -1804,21 +1804,21 @@ vm_handle_db(struct vcpu *vcpu, struct vm_exit *vme, bool *retu) vm_get_register(vcpu, VM_REG_GUEST_RSP, &rsp); error = vm_copy_setup(vcpu, &vme->u.dbg.paging, rsp, sizeof(uint64_t), - VM_PROT_RW, ©info, 1, &fault); + VM_PROT_RW, copyinfo, nitems(copyinfo), &fault); if (error != 0 || fault != 0) { *retu = false; return (EINVAL); } /* Read pushed rflags value from top of stack. */ - vm_copyin(©info, &rflags, sizeof(uint64_t)); + vm_copyin(copyinfo, &rflags, sizeof(uint64_t)); /* Clear TF bit. */ rflags &= ~(PSL_T); /* Write updated value back to memory. */ - vm_copyout(&rflags, ©info, sizeof(uint64_t)); - vm_copy_teardown(©info, 1); + vm_copyout(&rflags, copyinfo, sizeof(uint64_t)); + vm_copy_teardown(copyinfo, nitems(copyinfo)); return (0); }