ia64/xen-unstable

changeset 16030:22273a5336e5

x86: Clean up arch_set_info_guest() by having HVM VCPUs bail early.
Signed-off-by: Keir Fraser <keir@xensource.com>
author Keir Fraser <keir@xensource.com>
date Mon Oct 01 15:28:18 2007 +0100 (2007-10-01)
parents 772674585a1a
children 307a8688a9e3
files xen/arch/x86/domain.c
line diff
     1.1 --- a/xen/arch/x86/domain.c	Mon Oct 01 15:12:05 2007 +0100
     1.2 +++ b/xen/arch/x86/domain.c	Mon Oct 01 15:28:18 2007 +0100
     1.3 @@ -645,21 +645,21 @@ int arch_set_info_guest(
     1.4  
     1.5      v->arch.guest_context.user_regs.eflags |= 2;
     1.6  
     1.7 +    if ( is_hvm_vcpu(v) )
     1.8 +        goto out;
     1.9 +
    1.10      /* Only CR0.TS is modifiable by guest or admin. */
    1.11      v->arch.guest_context.ctrlreg[0] &= X86_CR0_TS;
    1.12      v->arch.guest_context.ctrlreg[0] |= read_cr0() & ~X86_CR0_TS;
    1.13  
    1.14      init_int80_direct_trap(v);
    1.15  
    1.16 -    if ( !is_hvm_vcpu(v) )
    1.17 -    {
    1.18 -        /* IOPL privileges are virtualised. */
    1.19 -        v->arch.iopl = (v->arch.guest_context.user_regs.eflags >> 12) & 3;
    1.20 -        v->arch.guest_context.user_regs.eflags &= ~EF_IOPL;
    1.21 +    /* IOPL privileges are virtualised. */
    1.22 +    v->arch.iopl = (v->arch.guest_context.user_regs.eflags >> 12) & 3;
    1.23 +    v->arch.guest_context.user_regs.eflags &= ~EF_IOPL;
    1.24  
    1.25 -        /* Ensure real hardware interrupts are enabled. */
    1.26 -        v->arch.guest_context.user_regs.eflags |= EF_IE;
    1.27 -    }
    1.28 +    /* Ensure real hardware interrupts are enabled. */
    1.29 +    v->arch.guest_context.user_regs.eflags |= EF_IE;
    1.30  
    1.31      if ( v->is_initialised )
    1.32          goto out;
    1.33 @@ -672,29 +672,44 @@ int arch_set_info_guest(
    1.34      if ( v->vcpu_id == 0 )
    1.35          d->vm_assist = c(vm_assist);
    1.36  
    1.37 -    if ( !is_hvm_vcpu(v) )
    1.38 -    {
    1.39 -        if ( !compat )
    1.40 -            rc = (int)set_gdt(v, c.nat->gdt_frames, c.nat->gdt_ents);
    1.41 +    if ( !compat )
    1.42 +        rc = (int)set_gdt(v, c.nat->gdt_frames, c.nat->gdt_ents);
    1.43  #ifdef CONFIG_COMPAT
    1.44 -        else
    1.45 -        {
    1.46 -            unsigned long gdt_frames[ARRAY_SIZE(c.cmp->gdt_frames)];
    1.47 -            unsigned int i, n = (c.cmp->gdt_ents + 511) / 512;
    1.48 +    else
    1.49 +    {
    1.50 +        unsigned long gdt_frames[ARRAY_SIZE(c.cmp->gdt_frames)];
    1.51 +        unsigned int i, n = (c.cmp->gdt_ents + 511) / 512;
    1.52 +
    1.53 +        if ( n > ARRAY_SIZE(c.cmp->gdt_frames) )
    1.54 +            return -EINVAL;
    1.55 +        for ( i = 0; i < n; ++i )
    1.56 +            gdt_frames[i] = c.cmp->gdt_frames[i];
    1.57 +        rc = (int)set_gdt(v, gdt_frames, c.cmp->gdt_ents);
    1.58 +    }
    1.59 +#endif
    1.60 +    if ( rc != 0 )
    1.61 +        return rc;
    1.62  
    1.63 -            if ( n > ARRAY_SIZE(c.cmp->gdt_frames) )
    1.64 -                return -EINVAL;
    1.65 -            for ( i = 0; i < n; ++i )
    1.66 -                gdt_frames[i] = c.cmp->gdt_frames[i];
    1.67 -            rc = (int)set_gdt(v, gdt_frames, c.cmp->gdt_ents);
    1.68 +    if ( !compat )
    1.69 +    {
    1.70 +        cr3_pfn = gmfn_to_mfn(d, xen_cr3_to_pfn(c.nat->ctrlreg[3]));
    1.71 +
    1.72 +        if ( !mfn_valid(cr3_pfn) ||
    1.73 +             (paging_mode_refcounts(d)
    1.74 +              ? !get_page(mfn_to_page(cr3_pfn), d)
    1.75 +              : !get_page_and_type(mfn_to_page(cr3_pfn), d,
    1.76 +                                   PGT_base_page_table)) )
    1.77 +        {
    1.78 +            destroy_gdt(v);
    1.79 +            return -EINVAL;
    1.80          }
    1.81 -#endif
    1.82 -        if ( rc != 0 )
    1.83 -            return rc;
    1.84 +
    1.85 +        v->arch.guest_table = pagetable_from_pfn(cr3_pfn);
    1.86  
    1.87 -        if ( !compat )
    1.88 +#ifdef __x86_64__
    1.89 +        if ( c.nat->ctrlreg[1] )
    1.90          {
    1.91 -            cr3_pfn = gmfn_to_mfn(d, xen_cr3_to_pfn(c.nat->ctrlreg[3]));
    1.92 +            cr3_pfn = gmfn_to_mfn(d, xen_cr3_to_pfn(c.nat->ctrlreg[1]));
    1.93  
    1.94              if ( !mfn_valid(cr3_pfn) ||
    1.95                   (paging_mode_refcounts(d)
    1.96 @@ -702,59 +717,42 @@ int arch_set_info_guest(
    1.97                    : !get_page_and_type(mfn_to_page(cr3_pfn), d,
    1.98                                         PGT_base_page_table)) )
    1.99              {
   1.100 +                cr3_pfn = pagetable_get_pfn(v->arch.guest_table);
   1.101 +                v->arch.guest_table = pagetable_null();
   1.102 +                if ( paging_mode_refcounts(d) )
   1.103 +                    put_page(mfn_to_page(cr3_pfn));
   1.104 +                else
   1.105 +                    put_page_and_type(mfn_to_page(cr3_pfn));
   1.106                  destroy_gdt(v);
   1.107                  return -EINVAL;
   1.108              }
   1.109  
   1.110 -            v->arch.guest_table = pagetable_from_pfn(cr3_pfn);
   1.111 -
   1.112 -#ifdef __x86_64__
   1.113 -            if ( c.nat->ctrlreg[1] )
   1.114 -            {
   1.115 -                cr3_pfn = gmfn_to_mfn(d, xen_cr3_to_pfn(c.nat->ctrlreg[1]));
   1.116 -
   1.117 -                if ( !mfn_valid(cr3_pfn) ||
   1.118 -                     (paging_mode_refcounts(d)
   1.119 -                      ? !get_page(mfn_to_page(cr3_pfn), d)
   1.120 -                      : !get_page_and_type(mfn_to_page(cr3_pfn), d,
   1.121 -                                           PGT_base_page_table)) )
   1.122 -                {
   1.123 -                    cr3_pfn = pagetable_get_pfn(v->arch.guest_table);
   1.124 -                    v->arch.guest_table = pagetable_null();
   1.125 -                    if ( paging_mode_refcounts(d) )
   1.126 -                        put_page(mfn_to_page(cr3_pfn));
   1.127 -                    else
   1.128 -                        put_page_and_type(mfn_to_page(cr3_pfn));
   1.129 -                    destroy_gdt(v);
   1.130 -                    return -EINVAL;
   1.131 -                }
   1.132 -
   1.133 -                v->arch.guest_table_user = pagetable_from_pfn(cr3_pfn);
   1.134 -            }
   1.135 -#endif
   1.136 -        }
   1.137 -#ifdef CONFIG_COMPAT
   1.138 -        else
   1.139 -        {
   1.140 -            l4_pgentry_t *l4tab;
   1.141 -
   1.142 -            cr3_pfn = gmfn_to_mfn(d, compat_cr3_to_pfn(c.cmp->ctrlreg[3]));
   1.143 -
   1.144 -            if ( !mfn_valid(cr3_pfn) ||
   1.145 -                 (paging_mode_refcounts(d)
   1.146 -                  ? !get_page(mfn_to_page(cr3_pfn), d)
   1.147 -                  : !get_page_and_type(mfn_to_page(cr3_pfn), d,
   1.148 -                                       PGT_l3_page_table)) )
   1.149 -            {
   1.150 -                destroy_gdt(v);
   1.151 -                return -EINVAL;
   1.152 -            }
   1.153 -
   1.154 -            l4tab = __va(pagetable_get_paddr(v->arch.guest_table));
   1.155 -            *l4tab = l4e_from_pfn(cr3_pfn, _PAGE_PRESENT|_PAGE_RW|_PAGE_USER|_PAGE_ACCESSED);
   1.156 +            v->arch.guest_table_user = pagetable_from_pfn(cr3_pfn);
   1.157          }
   1.158  #endif
   1.159 -    }    
   1.160 +    }
   1.161 +#ifdef CONFIG_COMPAT
   1.162 +    else
   1.163 +    {
   1.164 +        l4_pgentry_t *l4tab;
   1.165 +
   1.166 +        cr3_pfn = gmfn_to_mfn(d, compat_cr3_to_pfn(c.cmp->ctrlreg[3]));
   1.167 +
   1.168 +        if ( !mfn_valid(cr3_pfn) ||
   1.169 +             (paging_mode_refcounts(d)
   1.170 +              ? !get_page(mfn_to_page(cr3_pfn), d)
   1.171 +              : !get_page_and_type(mfn_to_page(cr3_pfn), d,
   1.172 +                                   PGT_l3_page_table)) )
   1.173 +        {
   1.174 +            destroy_gdt(v);
   1.175 +            return -EINVAL;
   1.176 +        }
   1.177 +
   1.178 +        l4tab = __va(pagetable_get_paddr(v->arch.guest_table));
   1.179 +        *l4tab = l4e_from_pfn(
   1.180 +            cr3_pfn, _PAGE_PRESENT|_PAGE_RW|_PAGE_USER|_PAGE_ACCESSED);
   1.181 +    }
   1.182 +#endif
   1.183  
   1.184      if ( v->vcpu_id == 0 )
   1.185          update_domain_wallclock_time(d);