ia64/xen-unstable

changeset 9759:7a9a00c51588

[IA64] introduce dom0vp hypercalls

implement dom0vp hypercall.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
author awilliam@ldap.hp.com
date Tue Apr 25 13:56:30 2006 -0600 (2006-04-25)
parents ae0d41bd3bba
children 8a2b2b45e237
files xen/arch/ia64/xen/dom0_ops.c xen/arch/ia64/xen/domain.c xen/arch/ia64/xen/hypercall.c xen/include/asm-ia64/domain.h xen/include/public/arch-ia64.h
line diff
     1.1 --- a/xen/arch/ia64/xen/dom0_ops.c	Tue Apr 25 13:48:02 2006 -0600
     1.2 +++ b/xen/arch/ia64/xen/dom0_ops.c	Tue Apr 25 13:56:30 2006 -0600
     1.3 @@ -236,6 +236,55 @@ long arch_do_dom0_op(dom0_op_t *op, GUES
     1.4      return ret;
     1.5  }
     1.6  
     1.7 +#ifdef CONFIG_XEN_IA64_DOM0_VP
     1.8 +unsigned long
     1.9 +do_dom0vp_op(unsigned long cmd,
    1.10 +             unsigned long arg0, unsigned long arg1, unsigned long arg2,
    1.11 +             unsigned long arg3)
    1.12 +{
    1.13 +    unsigned long ret = 0;
    1.14 +    struct domain *d = current->domain;
    1.15 +
    1.16 +    switch (cmd) {
    1.17 +    case IA64_DOM0VP_ioremap:
    1.18 +        ret = assign_domain_mmio_page(d, arg0, arg1);
    1.19 +        break;
    1.20 +    case IA64_DOM0VP_phystomach:
    1.21 +        ret = ____lookup_domain_mpa(d, arg0 << PAGE_SHIFT);
    1.22 +        if (ret == INVALID_MFN) {
    1.23 +            DPRINTK("%s:%d INVALID_MFN ret: 0x%lx\n", __func__, __LINE__, ret);
    1.24 +        } else {
    1.25 +            ret = (ret & _PFN_MASK) >> PAGE_SHIFT;//XXX pte_pfn()
    1.26 +        }
    1.27 +        break;
    1.28 +    case IA64_DOM0VP_machtophys:
    1.29 +        if (max_page <= arg0) {
    1.30 +            ret = INVALID_M2P_ENTRY;
    1.31 +            break;
    1.32 +        }
    1.33 +        ret = get_gpfn_from_mfn(arg0);
    1.34 +        break;
    1.35 +    case IA64_DOM0VP_populate_physmap:
    1.36 +        ret = dom0vp_populate_physmap(d, arg0,
    1.37 +                                      (unsigned int)arg1, (unsigned int)arg2);
    1.38 +        break;
    1.39 +    case IA64_DOM0VP_zap_physmap:
    1.40 +        ret = dom0vp_zap_physmap(d, arg0, (unsigned int)arg1);
    1.41 +        break;
    1.42 +    case IA64_DOM0VP_add_physmap:
    1.43 +        ret = dom0vp_add_physmap(d, arg0, arg1, (unsigned int)arg2,
    1.44 +                                 (domid_t)arg3);
    1.45 +        break;
    1.46 +    default:
    1.47 +        ret = -1;
    1.48 +		printf("unknown dom0_vp_op 0x%lx\n", cmd);
    1.49 +        break;
    1.50 +    }
    1.51 +
    1.52 +    return ret;
    1.53 +}
    1.54 +#endif
    1.55 +
    1.56  /*
    1.57   * Local variables:
    1.58   * mode: C
     2.1 --- a/xen/arch/ia64/xen/domain.c	Tue Apr 25 13:48:02 2006 -0600
     2.2 +++ b/xen/arch/ia64/xen/domain.c	Tue Apr 25 13:56:30 2006 -0600
     2.3 @@ -887,6 +887,151 @@ unsigned long lookup_domain_mpa(struct d
     2.4  	return 0;
     2.5  }
     2.6  
     2.7 +#ifdef CONFIG_XEN_IA64_DOM0_VP
     2.8 +//XXX SMP
     2.9 +unsigned long
    2.10 +dom0vp_populate_physmap(struct domain *d, unsigned long gpfn,
    2.11 +                        unsigned int extent_order, unsigned int address_bits)
    2.12 +{
    2.13 +    unsigned long ret = 0;
    2.14 +    int flags = 0;
    2.15 +    unsigned long mpaddr = gpfn << PAGE_SHIFT;
    2.16 +    unsigned long extent_size = 1UL << extent_order;
    2.17 +    unsigned long offset;
    2.18 +    struct page_info* page;
    2.19 +    unsigned long physaddr;
    2.20 +
    2.21 +    if (extent_order > 0 && !multipage_allocation_permitted(d)) {
    2.22 +        ret = -EINVAL;
    2.23 +        goto out;
    2.24 +    }
    2.25 +
    2.26 +    if (gpfn + (1 << extent_order) < gpfn) {
    2.27 +        ret = -EINVAL;
    2.28 +        goto out;
    2.29 +    }
    2.30 +    if (gpfn > d->max_pages || gpfn + (1 << extent_order) > d->max_pages) {
    2.31 +        ret = -EINVAL;
    2.32 +        goto out;
    2.33 +    }
    2.34 +    if ((extent_size << PAGE_SHIFT) < extent_size) {
    2.35 +        ret = -EINVAL;
    2.36 +        goto out;
    2.37 +    }
    2.38 +
    2.39 +    //XXX check address_bits and set flags = ALLOC_DOM_DMA if needed
    2.40 +
    2.41 +    // check the rage is not populated yet.
    2.42 +    //XXX loop optimization
    2.43 +    for (offset = 0; offset < extent_size << PAGE_SHIFT; offset += PAGE_SIZE) {
    2.44 +        if (____lookup_domain_mpa(d, mpaddr + offset) != INVALID_MFN) {
    2.45 +            ret = -EBUSY;
    2.46 +            goto out;
    2.47 +        }
    2.48 +    }
    2.49 +
    2.50 +    page = alloc_domheap_pages(d, extent_order, flags);
    2.51 +    if (page == NULL) {
    2.52 +        ret = -ENOMEM;
    2.53 +        DPRINTK("Could not allocate order=%d extent: id=%d flags=%x\n",
    2.54 +                extent_order, d->domain_id, flags);
    2.55 +        goto out;
    2.56 +    }
    2.57 +
    2.58 +    //XXX loop optimization
    2.59 +    physaddr = page_to_maddr(page);
    2.60 +    for (offset = 0; offset < extent_size << PAGE_SHIFT; offset += PAGE_SIZE) {
    2.61 +        assign_domain_page(d, mpaddr + offset, physaddr + offset);
    2.62 +    }
    2.63 +
    2.64 +out:
    2.65 +    return ret;
    2.66 +}
    2.67 +
    2.68 +//XXX SMP
    2.69 +unsigned long
    2.70 +dom0vp_zap_physmap(struct domain *d, unsigned long gpfn,
    2.71 +                   unsigned int extent_order)
    2.72 +{
    2.73 +    unsigned long ret = 0;
    2.74 +    if (extent_order != 0) {
    2.75 +        //XXX
    2.76 +        ret = -ENOSYS;
    2.77 +        goto out;
    2.78 +    }
    2.79 +
    2.80 +    zap_domain_page_one(d, gpfn << PAGE_SHIFT);
    2.81 +
    2.82 +out:
    2.83 +    return ret;
    2.84 +}
    2.85 +
    2.86 +static void
    2.87 +assign_domain_page_replace(struct domain *d, unsigned long mpaddr,
    2.88 +                           unsigned long mfn, unsigned int flags)
    2.89 +{
    2.90 +    struct mm_struct *mm = d->arch.mm;
    2.91 +    pte_t* pte;
    2.92 +    pte_t old_pte;
    2.93 +
    2.94 +    pte = lookup_alloc_domain_pte(d, mpaddr);
    2.95 +
    2.96 +    // update pte
    2.97 +    old_pte = ptep_get_and_clear(mm, mpaddr, pte);
    2.98 +    set_pte(pte, pfn_pte(mfn,
    2.99 +                         __pgprot(__DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RWX)));
   2.100 +    if (!pte_none(old_pte)) {
   2.101 +        unsigned long old_mfn;
   2.102 +        struct page_info* old_page;
   2.103 +
   2.104 +        // XXX should previous underlying page be removed?
   2.105 +        //  or should error be returned because it is a due to a domain?
   2.106 +        old_mfn = pte_pfn(old_pte);//XXX
   2.107 +        old_page = mfn_to_page(old_mfn);
   2.108 +
   2.109 +        if (page_get_owner(old_page) == d) {
   2.110 +            BUG_ON(get_gpfn_from_mfn(old_mfn) != (mpaddr >> PAGE_SHIFT));
   2.111 +            set_gpfn_from_mfn(old_mfn, INVALID_M2P_ENTRY);
   2.112 +        }
   2.113 +
   2.114 +        domain_page_flush(d, mpaddr, old_mfn, mfn);
   2.115 +
   2.116 +        put_page(old_page);
   2.117 +    } else {
   2.118 +        BUG_ON(page_get_owner(mfn_to_page(mfn)) == d &&
   2.119 +               get_gpfn_from_mfn(mfn) != INVALID_M2P_ENTRY);
   2.120 +    }
   2.121 +}
   2.122 +
   2.123 +unsigned long
   2.124 +dom0vp_add_physmap(struct domain* d, unsigned long gpfn, unsigned long mfn,
   2.125 +                   unsigned int flags, domid_t domid)
   2.126 +{
   2.127 +    int error = 0;
   2.128 +
   2.129 +    struct domain* rd;
   2.130 +    rd = find_domain_by_id(domid);
   2.131 +    if (unlikely(rd == NULL)) {
   2.132 +        error = -EINVAL;
   2.133 +        goto out0;
   2.134 +    }
   2.135 +    if (unlikely(rd == d)) {
   2.136 +        error = -EINVAL;
   2.137 +        goto out1;
   2.138 +    }
   2.139 +    if (unlikely(get_page(mfn_to_page(mfn), rd) == 0)) {
   2.140 +        error = -EINVAL;
   2.141 +        goto out1;
   2.142 +    }
   2.143 +
   2.144 +    assign_domain_page_replace(d, gpfn << PAGE_SHIFT, mfn, 0/* flags:XXX */);
   2.145 +out1:
   2.146 +    put_domain(rd);
   2.147 +out0:
   2.148 +    return error;
   2.149 +}
   2.150 +#endif
   2.151 +
   2.152  /* Flush cache of domain d.  */
   2.153  void domain_cache_flush (struct domain *d, int sync_only)
   2.154  {
     3.1 --- a/xen/arch/ia64/xen/hypercall.c	Tue Apr 25 13:48:02 2006 -0600
     3.2 +++ b/xen/arch/ia64/xen/hypercall.c	Tue Apr 25 13:56:30 2006 -0600
     3.3 @@ -124,6 +124,12 @@ xen_hypercall (struct pt_regs *regs)
     3.4  		                       guest_handle_from_ptr(regs->r15, void));
     3.5  		break;
     3.6  
     3.7 +#ifdef CONFIG_XEN_IA64_DOM0_VP
     3.8 +	    case __HYPERVISOR_ia64_dom0vp_op:
     3.9 +		regs->r8 = do_dom0vp_op(regs->r14, regs->r15, regs->r16,
    3.10 +		                        regs->r17, regs->r18);
    3.11 +		break;
    3.12 +#endif
    3.13  	    default:
    3.14  		printf("unknown xen hypercall %lx\n", regs->r2);
    3.15  		regs->r8 = do_ni_hypercall();
     4.1 --- a/xen/include/asm-ia64/domain.h	Tue Apr 25 13:48:02 2006 -0600
     4.2 +++ b/xen/include/asm-ia64/domain.h	Tue Apr 25 13:56:30 2006 -0600
     4.3 @@ -169,6 +169,10 @@ void assign_domain_io_page(struct domain
     4.4  #ifdef CONFIG_XEN_IA64_DOM0_VP
     4.5  unsigned long assign_domain_mmio_page(struct domain *d, unsigned long mpaddr, unsigned long size);
     4.6  unsigned long assign_domain_mach_page(struct domain *d, unsigned long mpaddr, unsigned long size);
     4.7 +unsigned long do_dom0vp_op(unsigned long cmd, unsigned long arg0, unsigned long arg1, unsigned long arg2, unsigned long arg3);
     4.8 +unsigned long dom0vp_populate_physmap(struct domain *d, unsigned long gpfn, unsigned int extent_order, unsigned int address_bits);
     4.9 +unsigned long dom0vp_zap_physmap(struct domain *d, unsigned long gpfn, unsigned int extent_order);
    4.10 +unsigned long dom0vp_add_physmap(struct domain* d, unsigned long gpfn, unsigned long mfn, unsigned int flags, domid_t domid);
    4.11  #endif
    4.12  
    4.13  #include <asm/uaccess.h> /* for KERNEL_DS */
     5.1 --- a/xen/include/public/arch-ia64.h	Tue Apr 25 13:48:02 2006 -0600
     5.2 +++ b/xen/include/public/arch-ia64.h	Tue Apr 25 13:56:30 2006 -0600
     5.3 @@ -326,6 +326,41 @@ typedef struct vcpu_guest_context {
     5.4  } vcpu_guest_context_t;
     5.5  DEFINE_GUEST_HANDLE(vcpu_guest_context_t);
     5.6  
     5.7 +// dom0 vp op
     5.8 +#define __HYPERVISOR_ia64_dom0vp_op     256 // XXX sufficient large
     5.9 +                                            // TODO
    5.10 +                                            // arch specific hypercall
    5.11 +                                            // number conversion
    5.12 +#define IA64_DOM0VP_ioremap             0       // map io space in machine
    5.13 +                                                // address to dom0 physical
    5.14 +                                                // address space.
    5.15 +                                                // currently physical
    5.16 +                                                // assignedg address equals to
    5.17 +                                                // machine address
    5.18 +#define IA64_DOM0VP_phystomach          1       // convert a pseudo physical
    5.19 +                                                // page frame number
    5.20 +                                                // to the corresponding
    5.21 +                                                // machine page frame number.
    5.22 +                                                // if no page is assigned,
    5.23 +                                                // INVALID_MFN or GPFN_INV_MASK
    5.24 +                                                // is returned depending on
    5.25 +                                                // domain's non-vti/vti mode.
    5.26 +#define IA64_DOM0VP_machtophys          3       // convert a machine page
    5.27 +                                                // frame number
    5.28 +                                                // to the corresponding
    5.29 +                                                // pseudo physical page frame
    5.30 +                                                // number of the caller domain
    5.31 +#define IA64_DOM0VP_populate_physmap    16      // allocate machine-contigusous
    5.32 +                                                // memory region and
    5.33 +                                                // map it to pseudo physical
    5.34 +                                                // address
    5.35 +#define IA64_DOM0VP_zap_physmap         17      // unmap and free pages
    5.36 +                                                // contained in the specified
    5.37 +                                                // pseudo physical region
    5.38 +#define IA64_DOM0VP_add_physmap         18      // assigne machine page frane
    5.39 +                                                // to dom0's pseudo physical
    5.40 +                                                // address space.
    5.41 +
    5.42  #endif /* !__ASSEMBLY__ */
    5.43  
    5.44  #endif /* __HYPERVISOR_IF_IA64_H__ */