[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v2 for-next v2 7/8] x86/mm: move check_descriptor to pv/mm.c
It's only needed there. Also make it static and delete the declaration from mm.h. No functional change. Signed-off-by: Wei Liu <wei.liu2@xxxxxxxxxx> --- xen/arch/x86/pv/mm.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++ xen/arch/x86/x86_64/mm.c | 87 ------------------------------------------------ xen/include/asm-x86/mm.h | 2 -- 3 files changed, 86 insertions(+), 89 deletions(-) diff --git a/xen/arch/x86/pv/mm.c b/xen/arch/x86/pv/mm.c index 48d3fe184b..96f2431756 100644 --- a/xen/arch/x86/pv/mm.c +++ b/xen/arch/x86/pv/mm.c @@ -220,6 +220,92 @@ static void invalidate_shadow_ldt(struct vcpu *v, int flush) spin_unlock(&v->arch.pv_vcpu.shadow_ldt_lock); } +/* Returns TRUE if given descriptor is valid for GDT or LDT. */ +static int check_descriptor(const struct domain *dom, struct desc_struct *d) +{ + u32 a = d->a, b = d->b; + u16 cs; + unsigned int dpl; + + /* A not-present descriptor will always fault, so is safe. */ + if ( !(b & _SEGMENT_P) ) + return 1; + + /* Check and fix up the DPL. */ + dpl = (b >> 13) & 3; + __fixup_guest_selector(dom, dpl); + b = (b & ~_SEGMENT_DPL) | (dpl << 13); + + /* All code and data segments are okay. No base/limit checking. */ + if ( (b & _SEGMENT_S) ) + { + if ( is_pv_32bit_domain(dom) ) + { + unsigned long base, limit; + + if ( b & _SEGMENT_L ) + goto bad; + + /* + * Older PAE Linux guests use segments which are limited to + * 0xf6800000. Extend these to allow access to the larger read-only + * M2P table available in 32on64 mode. + */ + base = (b & (0xff << 24)) | ((b & 0xff) << 16) | (a >> 16); + + limit = (b & 0xf0000) | (a & 0xffff); + limit++; /* We add one because limit is inclusive. */ + + if ( (b & _SEGMENT_G) ) + limit <<= 12; + + if ( (base == 0) && (limit > HYPERVISOR_COMPAT_VIRT_START(dom)) ) + { + a |= 0x0000ffff; + b |= 0x000f0000; + } + } + + goto good; + } + + /* Invalid type 0 is harmless. It is used for 2nd half of a call gate. */ + if ( (b & _SEGMENT_TYPE) == 0x000 ) + return 1; + + /* Everything but a call gate is discarded here. */ + if ( (b & _SEGMENT_TYPE) != 0xc00 ) + goto bad; + + /* Validate the target code selector. */ + cs = a >> 16; + if ( !guest_gate_selector_okay(dom, cs) ) + goto bad; + /* + * Force DPL to zero, causing a GP fault with its error code indicating + * the gate in use, allowing emulation. This is necessary because with + * native guests (kernel in ring 3) call gates cannot be used directly + * to transition from user to kernel mode (and whether a gate is used + * to enter the kernel can only be determined when the gate is being + * used), and with compat guests call gates cannot be used at all as + * there are only 64-bit ones. + * Store the original DPL in the selector's RPL field. + */ + b &= ~_SEGMENT_DPL; + cs = (cs & ~3) | dpl; + a = (a & 0xffffU) | (cs << 16); + + /* Reserved bits must be zero. */ + if ( b & (is_pv_32bit_domain(dom) ? 0xe0 : 0xff) ) + goto bad; + + good: + d->a = a; + d->b = b; + return 1; + bad: + return 0; +} static int alloc_segdesc_page(struct page_info *page) { diff --git a/xen/arch/x86/x86_64/mm.c b/xen/arch/x86/x86_64/mm.c index 19a14e8829..0bf85a59ed 100644 --- a/xen/arch/x86/x86_64/mm.c +++ b/xen/arch/x86/x86_64/mm.c @@ -1018,93 +1018,6 @@ long subarch_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg) return rc; } -/* Returns TRUE if given descriptor is valid for GDT or LDT. */ -int check_descriptor(const struct domain *dom, struct desc_struct *d) -{ - u32 a = d->a, b = d->b; - u16 cs; - unsigned int dpl; - - /* A not-present descriptor will always fault, so is safe. */ - if ( !(b & _SEGMENT_P) ) - return 1; - - /* Check and fix up the DPL. */ - dpl = (b >> 13) & 3; - __fixup_guest_selector(dom, dpl); - b = (b & ~_SEGMENT_DPL) | (dpl << 13); - - /* All code and data segments are okay. No base/limit checking. */ - if ( (b & _SEGMENT_S) ) - { - if ( is_pv_32bit_domain(dom) ) - { - unsigned long base, limit; - - if ( b & _SEGMENT_L ) - goto bad; - - /* - * Older PAE Linux guests use segments which are limited to - * 0xf6800000. Extend these to allow access to the larger read-only - * M2P table available in 32on64 mode. - */ - base = (b & (0xff << 24)) | ((b & 0xff) << 16) | (a >> 16); - - limit = (b & 0xf0000) | (a & 0xffff); - limit++; /* We add one because limit is inclusive. */ - - if ( (b & _SEGMENT_G) ) - limit <<= 12; - - if ( (base == 0) && (limit > HYPERVISOR_COMPAT_VIRT_START(dom)) ) - { - a |= 0x0000ffff; - b |= 0x000f0000; - } - } - - goto good; - } - - /* Invalid type 0 is harmless. It is used for 2nd half of a call gate. */ - if ( (b & _SEGMENT_TYPE) == 0x000 ) - return 1; - - /* Everything but a call gate is discarded here. */ - if ( (b & _SEGMENT_TYPE) != 0xc00 ) - goto bad; - - /* Validate the target code selector. */ - cs = a >> 16; - if ( !guest_gate_selector_okay(dom, cs) ) - goto bad; - /* - * Force DPL to zero, causing a GP fault with its error code indicating - * the gate in use, allowing emulation. This is necessary because with - * native guests (kernel in ring 3) call gates cannot be used directly - * to transition from user to kernel mode (and whether a gate is used - * to enter the kernel can only be determined when the gate is being - * used), and with compat guests call gates cannot be used at all as - * there are only 64-bit ones. - * Store the original DPL in the selector's RPL field. - */ - b &= ~_SEGMENT_DPL; - cs = (cs & ~3) | dpl; - a = (a & 0xffffU) | (cs << 16); - - /* Reserved bits must be zero. */ - if ( b & (is_pv_32bit_domain(dom) ? 0xe0 : 0xff) ) - goto bad; - - good: - d->a = a; - d->b = b; - return 1; - bad: - return 0; -} - int pagefault_by_memadd(unsigned long addr, struct cpu_user_regs *regs) { struct domain *d = current->domain; diff --git a/xen/include/asm-x86/mm.h b/xen/include/asm-x86/mm.h index 8e2bf91070..ca70f14500 100644 --- a/xen/include/asm-x86/mm.h +++ b/xen/include/asm-x86/mm.h @@ -411,8 +411,6 @@ static inline int get_page_and_type(struct page_info *page, ASSERT(((_p)->count_info & PGC_count_mask) != 0); \ ASSERT(page_get_owner(_p) == (_d)) -int check_descriptor(const struct domain *, struct desc_struct *d); - extern bool_t opt_allow_superpage; extern paddr_t mem_hotplug; -- 2.11.0 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |