diff --git a/include/libkdumpfile/addrxlat.h.in b/include/libkdumpfile/addrxlat.h.in index c5f562d6..67a31df0 100644 --- a/include/libkdumpfile/addrxlat.h.in +++ b/include/libkdumpfile/addrxlat.h.in @@ -829,6 +829,11 @@ typedef enum _addrxlat_optidx { */ ADDRXLAT_OPT_rootpgt, + /** User land root page table address. Used *only* in aarch64 case. + * Type: full address + */ + ADDRXLAT_OPT_user_rootpgt, + /** Xen p2m root machine frame number. * Type: address */ @@ -928,6 +933,14 @@ addrxlat_opt_rootpgt(addrxlat_opt_t *opt, const addrxlat_fulladdr_t *val) opt->val.fulladdr = *val; } +/** Helper to set @xref ADDRXLAT_OPT_user_rootpgt in a type-safe manner. */ +static inline void +addrxlat_opt_user_rootpgt(addrxlat_opt_t *opt, const addrxlat_fulladdr_t *val) +{ + opt->idx = ADDRXLAT_OPT_user_rootpgt; + opt->val.fulladdr = *val; +} + /** Helper to set @xref ADDRXLAT_OPT_xen_p2m_mfn in a type-safe manner. */ static inline void addrxlat_opt_xen_p2m_mfn(addrxlat_opt_t *opt, unsigned long val) diff --git a/python/addrxlat.c b/python/addrxlat.c index f52003d4..a810e9f1 100644 --- a/python/addrxlat.c +++ b/python/addrxlat.c @@ -4312,13 +4312,14 @@ sys_os_init(PyObject *_self, PyObject *args, PyObject *kwargs) "page_shift", "phys_base", "rootpgt", + "user_rootpgt", "xen_p2m_mfn", "xen_xlat", NULL }; PyObject *ctxobj; PyObject *arch, *type, *ver, *page_shift, *phys_base, - *rootpgt, *xen_p2m_mfn, *xen_xlat, *phys_bits, *virt_bits; + *rootpgt, *user_rootpgt, *xen_p2m_mfn, *xen_xlat, *phys_bits, *virt_bits; addrxlat_ctx_t *ctx; addrxlat_opt_t opts[ADDRXLAT_OPT_NUM], *p; addrxlat_status status; @@ -4326,9 +4327,9 @@ sys_os_init(PyObject *_self, PyObject *args, PyObject *kwargs) arch = type = ver = page_shift = phys_base = rootpgt = xen_p2m_mfn = xen_xlat = phys_bits = virt_bits = Py_None; if (!PyArg_ParseTupleAndKeywords( - args, kwargs, "O|OOOOOOOOOO:os_init", keywords, + args, kwargs, "O|OOOOOOOOOOO:os_init", keywords, &ctxobj, &arch, &type, &ver, &phys_bits, &virt_bits, - &page_shift, &phys_base, &rootpgt, &xen_p2m_mfn, + &page_shift, &phys_base, &rootpgt, &user_rootpgt, &xen_p2m_mfn, &xen_xlat)) return NULL; @@ -4394,6 +4395,13 @@ sys_os_init(PyObject *_self, PyObject *args, PyObject *kwargs) addrxlat_opt_rootpgt(p, faddr); ++p; } + if (user_rootpgt != Py_None) { + addrxlat_fulladdr_t *faddr = fulladdr_AsPointer(user_rootpgt); + if (!faddr) + return NULL; + addrxlat_opt_user_rootpgt(p, faddr); + ++p; + } if (xen_p2m_mfn != Py_None) { addrxlat_opt_xen_p2m_mfn( p, Number_AsUnsignedLongLong(xen_p2m_mfn)); diff --git a/src/addrxlat/aarch64.c b/src/addrxlat/aarch64.c index cf7499be..503c62aa 100644 --- a/src/addrxlat/aarch64.c +++ b/src/addrxlat/aarch64.c @@ -404,6 +404,10 @@ map_linux_aarch64(struct os_init_data *ctl) return status; } + meth = &ctl->sys->meth[ADDRXLAT_SYS_METH_UPGT]; + if (opt_isset(ctl->popt, user_rootpgt)) + meth->param.pgt.root = ctl->popt.user_rootpgt; + status = sys_set_physmaps(ctl, PHYSADDR_MASK); if (status != ADDRXLAT_OK) return status; diff --git a/src/addrxlat/addrxlat-priv.h b/src/addrxlat/addrxlat-priv.h index a27a3f5b..9d7cabac 100644 --- a/src/addrxlat/addrxlat-priv.h +++ b/src/addrxlat/addrxlat-priv.h @@ -414,6 +414,7 @@ struct parsed_opts { unsigned long page_shift; /**< Value of OPT_page_shift. */ addrxlat_addr_t phys_base; /**< Value of OPT_phys_base. */ addrxlat_fulladdr_t rootpgt; /**< Value of OPT_rootpgt. */ + addrxlat_fulladdr_t user_rootpgt; /**< Value of OPT_user_rootpgt. */ unsigned long xen_p2m_mfn; /**< Value of OPT_xen_p2m_mfn. */ bool xen_xlat; /**< Value of OPT_xen_xlat. */ }; diff --git a/src/addrxlat/sys.c b/src/addrxlat/sys.c index 4f6e068c..17ac3461 100644 --- a/src/addrxlat/sys.c +++ b/src/addrxlat/sys.c @@ -121,6 +121,10 @@ parse_opt(struct parsed_opts *popt, const addrxlat_opt_t *opt) popt->rootpgt = opt->val.fulladdr; break; + case ADDRXLAT_OPT_user_rootpgt: + popt->user_rootpgt = opt->val.fulladdr; + break; + case ADDRXLAT_OPT_xen_p2m_mfn: popt->xen_p2m_mfn = opt->val.num; break;