From 100b6d49bf4796465155024bac6798076fd38f6a Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Mon, 1 Oct 2007 15:28:18 +0100 Subject: [PATCH] x86: Clean up arch_set_info_guest() by having HVM VCPUs bail early. Signed-off-by: Keir Fraser --- xen/arch/x86/domain.c | 136 +++++++++++++++++++++--------------------- 1 file changed, 67 insertions(+), 69 deletions(-) diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index dafee075f9..540ef8f11e 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -645,21 +645,21 @@ int arch_set_info_guest( v->arch.guest_context.user_regs.eflags |= 2; + if ( is_hvm_vcpu(v) ) + goto out; + /* Only CR0.TS is modifiable by guest or admin. */ v->arch.guest_context.ctrlreg[0] &= X86_CR0_TS; v->arch.guest_context.ctrlreg[0] |= read_cr0() & ~X86_CR0_TS; init_int80_direct_trap(v); - if ( !is_hvm_vcpu(v) ) - { - /* IOPL privileges are virtualised. */ - v->arch.iopl = (v->arch.guest_context.user_regs.eflags >> 12) & 3; - v->arch.guest_context.user_regs.eflags &= ~EF_IOPL; + /* IOPL privileges are virtualised. */ + v->arch.iopl = (v->arch.guest_context.user_regs.eflags >> 12) & 3; + v->arch.guest_context.user_regs.eflags &= ~EF_IOPL; - /* Ensure real hardware interrupts are enabled. */ - v->arch.guest_context.user_regs.eflags |= EF_IE; - } + /* Ensure real hardware interrupts are enabled. */ + v->arch.guest_context.user_regs.eflags |= EF_IE; if ( v->is_initialised ) goto out; @@ -672,29 +672,44 @@ int arch_set_info_guest( if ( v->vcpu_id == 0 ) d->vm_assist = c(vm_assist); - if ( !is_hvm_vcpu(v) ) - { - if ( !compat ) - rc = (int)set_gdt(v, c.nat->gdt_frames, c.nat->gdt_ents); + if ( !compat ) + rc = (int)set_gdt(v, c.nat->gdt_frames, c.nat->gdt_ents); #ifdef CONFIG_COMPAT - else - { - unsigned long gdt_frames[ARRAY_SIZE(c.cmp->gdt_frames)]; - unsigned int i, n = (c.cmp->gdt_ents + 511) / 512; + else + { + unsigned long gdt_frames[ARRAY_SIZE(c.cmp->gdt_frames)]; + unsigned int i, n = (c.cmp->gdt_ents + 511) / 512; + + if ( n > ARRAY_SIZE(c.cmp->gdt_frames) ) + return -EINVAL; + for ( i = 0; i < n; ++i ) + gdt_frames[i] = c.cmp->gdt_frames[i]; + rc = (int)set_gdt(v, gdt_frames, c.cmp->gdt_ents); + } +#endif + if ( rc != 0 ) + return rc; - if ( n > ARRAY_SIZE(c.cmp->gdt_frames) ) - return -EINVAL; - for ( i = 0; i < n; ++i ) - gdt_frames[i] = c.cmp->gdt_frames[i]; - rc = (int)set_gdt(v, gdt_frames, c.cmp->gdt_ents); + if ( !compat ) + { + cr3_pfn = gmfn_to_mfn(d, xen_cr3_to_pfn(c.nat->ctrlreg[3])); + + if ( !mfn_valid(cr3_pfn) || + (paging_mode_refcounts(d) + ? !get_page(mfn_to_page(cr3_pfn), d) + : !get_page_and_type(mfn_to_page(cr3_pfn), d, + PGT_base_page_table)) ) + { + destroy_gdt(v); + return -EINVAL; } -#endif - if ( rc != 0 ) - return rc; - if ( !compat ) + v->arch.guest_table = pagetable_from_pfn(cr3_pfn); + +#ifdef __x86_64__ + if ( c.nat->ctrlreg[1] ) { - cr3_pfn = gmfn_to_mfn(d, xen_cr3_to_pfn(c.nat->ctrlreg[3])); + cr3_pfn = gmfn_to_mfn(d, xen_cr3_to_pfn(c.nat->ctrlreg[1])); if ( !mfn_valid(cr3_pfn) || (paging_mode_refcounts(d) @@ -702,59 +717,42 @@ int arch_set_info_guest( : !get_page_and_type(mfn_to_page(cr3_pfn), d, PGT_base_page_table)) ) { + cr3_pfn = pagetable_get_pfn(v->arch.guest_table); + v->arch.guest_table = pagetable_null(); + if ( paging_mode_refcounts(d) ) + put_page(mfn_to_page(cr3_pfn)); + else + put_page_and_type(mfn_to_page(cr3_pfn)); destroy_gdt(v); return -EINVAL; } - v->arch.guest_table = pagetable_from_pfn(cr3_pfn); - -#ifdef __x86_64__ - if ( c.nat->ctrlreg[1] ) - { - cr3_pfn = gmfn_to_mfn(d, xen_cr3_to_pfn(c.nat->ctrlreg[1])); - - if ( !mfn_valid(cr3_pfn) || - (paging_mode_refcounts(d) - ? !get_page(mfn_to_page(cr3_pfn), d) - : !get_page_and_type(mfn_to_page(cr3_pfn), d, - PGT_base_page_table)) ) - { - cr3_pfn = pagetable_get_pfn(v->arch.guest_table); - v->arch.guest_table = pagetable_null(); - if ( paging_mode_refcounts(d) ) - put_page(mfn_to_page(cr3_pfn)); - else - put_page_and_type(mfn_to_page(cr3_pfn)); - destroy_gdt(v); - return -EINVAL; - } - - v->arch.guest_table_user = pagetable_from_pfn(cr3_pfn); - } -#endif + v->arch.guest_table_user = pagetable_from_pfn(cr3_pfn); } +#endif + } #ifdef CONFIG_COMPAT - else - { - l4_pgentry_t *l4tab; - - cr3_pfn = gmfn_to_mfn(d, compat_cr3_to_pfn(c.cmp->ctrlreg[3])); + else + { + l4_pgentry_t *l4tab; - if ( !mfn_valid(cr3_pfn) || - (paging_mode_refcounts(d) - ? !get_page(mfn_to_page(cr3_pfn), d) - : !get_page_and_type(mfn_to_page(cr3_pfn), d, - PGT_l3_page_table)) ) - { - destroy_gdt(v); - return -EINVAL; - } + cr3_pfn = gmfn_to_mfn(d, compat_cr3_to_pfn(c.cmp->ctrlreg[3])); - l4tab = __va(pagetable_get_paddr(v->arch.guest_table)); - *l4tab = l4e_from_pfn(cr3_pfn, _PAGE_PRESENT|_PAGE_RW|_PAGE_USER|_PAGE_ACCESSED); + if ( !mfn_valid(cr3_pfn) || + (paging_mode_refcounts(d) + ? !get_page(mfn_to_page(cr3_pfn), d) + : !get_page_and_type(mfn_to_page(cr3_pfn), d, + PGT_l3_page_table)) ) + { + destroy_gdt(v); + return -EINVAL; } + + l4tab = __va(pagetable_get_paddr(v->arch.guest_table)); + *l4tab = l4e_from_pfn( + cr3_pfn, _PAGE_PRESENT|_PAGE_RW|_PAGE_USER|_PAGE_ACCESSED); + } #endif - } if ( v->vcpu_id == 0 ) update_domain_wallclock_time(d); -- 2.39.5