[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen master] x86/gdbsx: Rename debug.c to gdbsx.c
commit 203156ef36df87a9a4161e15889b901df5ef58eb Author: Bobby Eshleman <bobby.eshleman@xxxxxxxxx> AuthorDate: Tue Sep 28 13:30:26 2021 -0700 Commit: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> CommitDate: Fri Apr 22 20:39:34 2022 +0100 x86/gdbsx: Rename debug.c to gdbsx.c debug.c contains only dbg_rw_mem(). Rename it to gdbsx.c. Move gdbsx_guest_mem_io(), and the prior setup of iop->remain, from domctl.c to gdbsx.c, merging it with dbg_rw_mem(). Signed-off-by: Bobby Eshleman <bobby.eshleman@xxxxxxxxx> Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx> --- xen/arch/x86/Makefile | 2 +- xen/arch/x86/debug.c | 177 ------------------------------------ xen/arch/x86/domctl.c | 14 +-- xen/arch/x86/gdbsx.c | 174 +++++++++++++++++++++++++++++++++++ xen/arch/x86/include/asm/debugger.h | 6 -- xen/arch/x86/include/asm/gdbsx.h | 13 +++ 6 files changed, 190 insertions(+), 196 deletions(-) diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile index 717bcbcac7..177a2ff742 100644 --- a/xen/arch/x86/Makefile +++ b/xen/arch/x86/Makefile @@ -22,7 +22,6 @@ obj-y += cpuid.o obj-$(CONFIG_PV) += compat.o obj-$(CONFIG_PV32) += x86_64/compat.o obj-$(CONFIG_KEXEC) += crash.o -obj-$(CONFIG_GDBSX) += debug.o obj-y += delay.o obj-y += desc.o obj-bin-y += dmi_scan.init.o @@ -34,6 +33,7 @@ obj-y += emul-i8254.o obj-y += extable.o obj-y += flushtlb.o obj-$(CONFIG_CRASH_DEBUG) += gdbstub.o +obj-$(CONFIG_GDBSX) += gdbsx.o obj-y += hypercall.o obj-y += i387.o obj-y += i8259.o diff --git a/xen/arch/x86/debug.c b/xen/arch/x86/debug.c deleted file mode 100644 index 91034a852e..0000000000 --- a/xen/arch/x86/debug.c +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (C) 2009, Mukesh Rathor, Oracle Corp. All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License v2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; If not, see <http://www.gnu.org/licenses/>. - */ - -#include <xen/sched.h> -#include <xen/mm.h> -#include <xen/domain_page.h> -#include <xen/guest_access.h> -#include <asm/debugger.h> -#include <asm/p2m.h> - -typedef unsigned long dbgva_t; -typedef unsigned char dbgbyte_t; - -/* Returns: mfn for the given (hvm guest) vaddr */ -static mfn_t -dbg_hvm_va2mfn(dbgva_t vaddr, struct domain *dp, int toaddr, gfn_t *gfn) -{ - mfn_t mfn; - uint32_t pfec = PFEC_page_present; - p2m_type_t gfntype; - - *gfn = _gfn(paging_gva_to_gfn(dp->vcpu[0], vaddr, &pfec)); - if ( gfn_eq(*gfn, INVALID_GFN) ) - return INVALID_MFN; - - mfn = get_gfn(dp, gfn_x(*gfn), &gfntype); - if ( p2m_is_readonly(gfntype) && toaddr ) - mfn = INVALID_MFN; - - if ( mfn_eq(mfn, INVALID_MFN) ) - { - put_gfn(dp, gfn_x(*gfn)); - *gfn = INVALID_GFN; - } - - return mfn; -} - -/* - * pgd3val: this is the value of init_mm.pgd[3] in a PV guest. It is optional. - * This to assist debug of modules in the guest. The kernel address - * space seems is always mapped, but modules are not necessarily - * mapped in any arbitraty guest cr3 that we pick if pgd3val is 0. - * Modules should always be addressible if we use cr3 from init_mm. - * Since pgd3val is already a pgd value, cr3->pgd[3], we just need to - * do 2 level lookups. - * - * NOTE: 4 level paging works for 32 PAE guests also because cpu runs in IA32-e - * mode. - * Returns: mfn for the given (pv guest) vaddr - */ -static mfn_t -dbg_pv_va2mfn(dbgva_t vaddr, struct domain *dp, uint64_t pgd3val) -{ - l4_pgentry_t l4e, *l4t; - l3_pgentry_t l3e, *l3t; - l2_pgentry_t l2e, *l2t; - l1_pgentry_t l1e, *l1t; - unsigned long cr3 = (pgd3val ? pgd3val : dp->vcpu[0]->arch.cr3); - mfn_t mfn = maddr_to_mfn(cr3_pa(cr3)); - - if ( pgd3val == 0 ) - { - l4t = map_domain_page(mfn); - l4e = l4t[l4_table_offset(vaddr)]; - unmap_domain_page(l4t); - mfn = l4e_get_mfn(l4e); - if ( !(l4e_get_flags(l4e) & _PAGE_PRESENT) ) - return INVALID_MFN; - - l3t = map_domain_page(mfn); - l3e = l3t[l3_table_offset(vaddr)]; - unmap_domain_page(l3t); - mfn = l3e_get_mfn(l3e); - if ( !(l3e_get_flags(l3e) & _PAGE_PRESENT) || - (l3e_get_flags(l3e) & _PAGE_PSE) ) - return INVALID_MFN; - } - - l2t = map_domain_page(mfn); - l2e = l2t[l2_table_offset(vaddr)]; - unmap_domain_page(l2t); - mfn = l2e_get_mfn(l2e); - if ( !(l2e_get_flags(l2e) & _PAGE_PRESENT) || - (l2e_get_flags(l2e) & _PAGE_PSE) ) - return INVALID_MFN; - - l1t = map_domain_page(mfn); - l1e = l1t[l1_table_offset(vaddr)]; - unmap_domain_page(l1t); - mfn = l1e_get_mfn(l1e); - - return mfn_valid(mfn) ? mfn : INVALID_MFN; -} - -/* Returns: number of bytes remaining to be copied */ -static unsigned int dbg_rw_guest_mem(struct domain *dp, unsigned long addr, - XEN_GUEST_HANDLE_PARAM(void) buf, - unsigned int len, bool toaddr, - uint64_t pgd3) -{ - while ( len > 0 ) - { - char *va; - mfn_t mfn; - gfn_t gfn = INVALID_GFN; - unsigned long pagecnt; - - pagecnt = min_t(long, PAGE_SIZE - (addr & ~PAGE_MASK), len); - - mfn = (is_hvm_domain(dp) - ? dbg_hvm_va2mfn(addr, dp, toaddr, &gfn) - : dbg_pv_va2mfn(addr, dp, pgd3)); - if ( mfn_eq(mfn, INVALID_MFN) ) - break; - - va = map_domain_page(mfn); - va = va + (addr & (PAGE_SIZE-1)); - - if ( toaddr ) - { - copy_from_guest(va, buf, pagecnt); - paging_mark_dirty(dp, mfn); - } - else - copy_to_guest(buf, va, pagecnt); - - unmap_domain_page(va); - if ( !gfn_eq(gfn, INVALID_GFN) ) - put_gfn(dp, gfn_x(gfn)); - - addr += pagecnt; - guest_handle_add_offset(buf, pagecnt); - len -= pagecnt; - } - - return len; -} - -/* - * addr is guest addr - * buf is debugger buffer. - * if toaddr, then addr = buf (write to addr), else buf = addr (rd from guest) - * pgd3: value of init_mm.pgd[3] in guest. see above. - * Returns: number of bytes remaining to be copied. - */ -unsigned int dbg_rw_mem(unsigned long gva, XEN_GUEST_HANDLE_PARAM(void) buf, - unsigned int len, struct domain *d, bool toaddr, - uint64_t pgd3) -{ - if ( d && !d->is_dying ) - len = dbg_rw_guest_mem(d, gva, buf, len, toaddr, pgd3); - - return len; -} - -/* - * Local variables: - * mode: C - * c-file-style: "BSD" - * c-basic-offset: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c index a6aae500a3..c20ab43527 100644 --- a/xen/arch/x86/domctl.c +++ b/xen/arch/x86/domctl.c @@ -20,6 +20,8 @@ #include <xen/console.h> #include <xen/iocap.h> #include <xen/paging.h> + +#include <asm/gdbsx.h> #include <asm/irq.h> #include <asm/hvm/emulate.h> #include <asm/hvm/hvm.h> @@ -33,20 +35,9 @@ #include <public/vm_event.h> #include <asm/mem_sharing.h> #include <asm/xstate.h> -#include <asm/debugger.h> #include <asm/psr.h> #include <asm/cpuid.h> -#ifdef CONFIG_GDBSX -static int gdbsx_guest_mem_io(struct domain *d, struct xen_domctl_gdbsx_memio *iop) -{ - iop->remain = dbg_rw_mem(iop->gva, guest_handle_from_ptr(iop->uva, void), - iop->len, d, iop->gwr, iop->pgd3val); - - return iop->remain ? -EFAULT : 0; -} -#endif - static int update_domain_cpu_policy(struct domain *d, xen_domctl_cpu_policy_t *xdpc) { @@ -827,7 +818,6 @@ long arch_do_domctl( #ifdef CONFIG_GDBSX case XEN_DOMCTL_gdbsx_guestmemio: - domctl->u.gdbsx_guest_memio.remain = domctl->u.gdbsx_guest_memio.len; ret = gdbsx_guest_mem_io(d, &domctl->u.gdbsx_guest_memio); if ( !ret ) copyback = true; diff --git a/xen/arch/x86/gdbsx.c b/xen/arch/x86/gdbsx.c new file mode 100644 index 0000000000..59eb31fc9a --- /dev/null +++ b/xen/arch/x86/gdbsx.c @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2009, Mukesh Rathor, Oracle Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License v2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; If not, see <http://www.gnu.org/licenses/>. + */ + +#include <xen/sched.h> +#include <xen/mm.h> +#include <xen/domain_page.h> +#include <xen/guest_access.h> +#include <asm/gdbsx.h> +#include <asm/p2m.h> + +typedef unsigned long dbgva_t; +typedef unsigned char dbgbyte_t; + +/* Returns: mfn for the given (hvm guest) vaddr */ +static mfn_t +dbg_hvm_va2mfn(dbgva_t vaddr, struct domain *dp, int toaddr, gfn_t *gfn) +{ + mfn_t mfn; + uint32_t pfec = PFEC_page_present; + p2m_type_t gfntype; + + *gfn = _gfn(paging_gva_to_gfn(dp->vcpu[0], vaddr, &pfec)); + if ( gfn_eq(*gfn, INVALID_GFN) ) + return INVALID_MFN; + + mfn = get_gfn(dp, gfn_x(*gfn), &gfntype); + if ( p2m_is_readonly(gfntype) && toaddr ) + mfn = INVALID_MFN; + + if ( mfn_eq(mfn, INVALID_MFN) ) + { + put_gfn(dp, gfn_x(*gfn)); + *gfn = INVALID_GFN; + } + + return mfn; +} + +/* + * pgd3val: this is the value of init_mm.pgd[3] in a PV guest. It is optional. + * This to assist debug of modules in the guest. The kernel address + * space seems is always mapped, but modules are not necessarily + * mapped in any arbitraty guest cr3 that we pick if pgd3val is 0. + * Modules should always be addressible if we use cr3 from init_mm. + * Since pgd3val is already a pgd value, cr3->pgd[3], we just need to + * do 2 level lookups. + * + * NOTE: 4 level paging works for 32 PAE guests also because cpu runs in IA32-e + * mode. + * Returns: mfn for the given (pv guest) vaddr + */ +static mfn_t +dbg_pv_va2mfn(dbgva_t vaddr, struct domain *dp, uint64_t pgd3val) +{ + l4_pgentry_t l4e, *l4t; + l3_pgentry_t l3e, *l3t; + l2_pgentry_t l2e, *l2t; + l1_pgentry_t l1e, *l1t; + unsigned long cr3 = (pgd3val ? pgd3val : dp->vcpu[0]->arch.cr3); + mfn_t mfn = maddr_to_mfn(cr3_pa(cr3)); + + if ( pgd3val == 0 ) + { + l4t = map_domain_page(mfn); + l4e = l4t[l4_table_offset(vaddr)]; + unmap_domain_page(l4t); + mfn = l4e_get_mfn(l4e); + if ( !(l4e_get_flags(l4e) & _PAGE_PRESENT) ) + return INVALID_MFN; + + l3t = map_domain_page(mfn); + l3e = l3t[l3_table_offset(vaddr)]; + unmap_domain_page(l3t); + mfn = l3e_get_mfn(l3e); + if ( !(l3e_get_flags(l3e) & _PAGE_PRESENT) || + (l3e_get_flags(l3e) & _PAGE_PSE) ) + return INVALID_MFN; + } + + l2t = map_domain_page(mfn); + l2e = l2t[l2_table_offset(vaddr)]; + unmap_domain_page(l2t); + mfn = l2e_get_mfn(l2e); + if ( !(l2e_get_flags(l2e) & _PAGE_PRESENT) || + (l2e_get_flags(l2e) & _PAGE_PSE) ) + return INVALID_MFN; + + l1t = map_domain_page(mfn); + l1e = l1t[l1_table_offset(vaddr)]; + unmap_domain_page(l1t); + mfn = l1e_get_mfn(l1e); + + return mfn_valid(mfn) ? mfn : INVALID_MFN; +} + +/* Returns: number of bytes remaining to be copied */ +static unsigned int dbg_rw_guest_mem(struct domain *dp, unsigned long addr, + XEN_GUEST_HANDLE_PARAM(void) buf, + unsigned int len, bool toaddr, + uint64_t pgd3) +{ + while ( len > 0 ) + { + char *va; + mfn_t mfn; + gfn_t gfn = INVALID_GFN; + unsigned long pagecnt; + + pagecnt = min_t(long, PAGE_SIZE - (addr & ~PAGE_MASK), len); + + mfn = (is_hvm_domain(dp) + ? dbg_hvm_va2mfn(addr, dp, toaddr, &gfn) + : dbg_pv_va2mfn(addr, dp, pgd3)); + if ( mfn_eq(mfn, INVALID_MFN) ) + break; + + va = map_domain_page(mfn); + va = va + (addr & (PAGE_SIZE-1)); + + if ( toaddr ) + { + copy_from_guest(va, buf, pagecnt); + paging_mark_dirty(dp, mfn); + } + else + copy_to_guest(buf, va, pagecnt); + + unmap_domain_page(va); + if ( !gfn_eq(gfn, INVALID_GFN) ) + put_gfn(dp, gfn_x(gfn)); + + addr += pagecnt; + guest_handle_add_offset(buf, pagecnt); + len -= pagecnt; + } + + return len; +} + +int gdbsx_guest_mem_io(struct domain *d, struct xen_domctl_gdbsx_memio *iop) +{ + if ( d && !d->is_dying ) + { + iop->remain = dbg_rw_guest_mem( + d, iop->gva, guest_handle_from_ptr(iop->uva, void), + iop->len, iop->gwr, iop->pgd3val); + } + else + iop->remain = iop->len; + + return iop->remain ? -EFAULT : 0; +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/arch/x86/include/asm/debugger.h b/xen/arch/x86/include/asm/debugger.h index e83b346a21..c5585752ca 100644 --- a/xen/arch/x86/include/asm/debugger.h +++ b/xen/arch/x86/include/asm/debugger.h @@ -54,10 +54,4 @@ static inline bool debugger_trap_fatal( #endif -#ifdef CONFIG_GDBSX -unsigned int dbg_rw_mem(unsigned long gva, XEN_GUEST_HANDLE_PARAM(void) buf, - unsigned int len, struct domain *d, bool toaddr, - uint64_t pgd3); -#endif - #endif /* __X86_DEBUGGER_H__ */ diff --git a/xen/arch/x86/include/asm/gdbsx.h b/xen/arch/x86/include/asm/gdbsx.h new file mode 100644 index 0000000000..eee746fc01 --- /dev/null +++ b/xen/arch/x86/include/asm/gdbsx.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __X86_GDBX_H__ +#define __X86_GDBX_H__ + +#ifdef CONFIG_GDBSX + +struct domain; +struct xen_domctl_gdbsx_memio; + +int gdbsx_guest_mem_io(struct domain *d, struct xen_domctl_gdbsx_memio *iop); + +#endif /* CONFIG_GDBSX */ +#endif /* __X86_GDBX_H__ */ -- generated by git-patchbot for /home/xen/git/xen.git#master
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |