ia64/xen-unstable

changeset 9973:7296d8fb07ff

[IA64] xen: grant table support

grant table support.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
author awilliam@xenbuild.aw
date Tue May 09 11:38:35 2006 -0600 (2006-05-09)
parents 8ac86f96879f
children 423bee635129
files xen/arch/ia64/xen/domain.c xen/include/asm-ia64/config.h xen/include/asm-ia64/grant_table.h xen/include/asm-ia64/linux-xen/asm/pgtable.h xen/include/asm-ia64/shadow.h
line diff
     1.1 --- a/xen/arch/ia64/xen/domain.c	Tue May 09 11:34:45 2006 -0600
     1.2 +++ b/xen/arch/ia64/xen/domain.c	Tue May 09 11:38:35 2006 -0600
     1.3 @@ -394,6 +394,10 @@ static void relinquish_memory(struct dom
     1.4  
     1.5          /* Follow the list chain and /then/ potentially free the page. */
     1.6          ent = ent->next;
     1.7 +#ifdef CONFIG_XEN_IA64_DOM0_VP
     1.8 +        if (page_get_owner(page) == d)
     1.9 +            set_gpfn_from_mfn(page_to_mfn(page), INVALID_M2P_ENTRY);
    1.10 +#endif
    1.11          put_page(page);
    1.12      }
    1.13  
    1.14 @@ -483,6 +487,7 @@ void new_thread(struct vcpu *v,
    1.15  	}
    1.16  }
    1.17  
    1.18 +//XXX !xxx_present() should be used instread of !xxx_none()?
    1.19  static pte_t*
    1.20  lookup_alloc_domain_pte(struct domain* d, unsigned long mpaddr)
    1.21  {
    1.22 @@ -1007,6 +1012,175 @@ out1:
    1.23  out0:
    1.24      return error;
    1.25  }
    1.26 +
    1.27 +// grant table host mapping
    1.28 +// mpaddr: host_addr: pseudo physical address
    1.29 +// mfn: frame: machine page frame
    1.30 +// flags: GNTMAP_readonly | GNTMAP_application_map | GNTMAP_contains_pte
    1.31 +int
    1.32 +create_grant_host_mapping(unsigned long gpaddr,
    1.33 +			  unsigned long mfn, unsigned int flags)
    1.34 +{
    1.35 +    struct domain* d = current->domain;
    1.36 +
    1.37 +    if (flags & (GNTMAP_application_map | GNTMAP_contains_pte)) {
    1.38 +        DPRINTK("%s: flags 0x%x\n", __func__, flags);
    1.39 +        return GNTST_general_error;
    1.40 +    }
    1.41 +    if (flags & GNTMAP_readonly) {
    1.42 +#if 0
    1.43 +        DPRINTK("%s: GNTMAP_readonly is not implemented yet. flags %x\n",
    1.44 +                __func__, flags);
    1.45 +#endif
    1.46 +        flags &= ~GNTMAP_readonly;
    1.47 +    }
    1.48 +
    1.49 +    assign_domain_page_replace(d, gpaddr, mfn, flags);
    1.50 +
    1.51 +    return GNTST_okay;
    1.52 +}
    1.53 +
    1.54 +// grant table host unmapping
    1.55 +int
    1.56 +destroy_grant_host_mapping(unsigned long gpaddr,
    1.57 +			   unsigned long mfn, unsigned int flags)
    1.58 +{
    1.59 +    struct domain* d = current->domain;
    1.60 +    pte_t* pte;
    1.61 +    pte_t old_pte;
    1.62 +    unsigned long old_mfn = INVALID_MFN;
    1.63 +
    1.64 +    if (flags & (GNTMAP_application_map | GNTMAP_contains_pte)) {
    1.65 +        DPRINTK("%s: flags 0x%x\n", __func__, flags);
    1.66 +        return GNTST_general_error;
    1.67 +    }
    1.68 +    if (flags & GNTMAP_readonly) {
    1.69 +#if 0
    1.70 +        DPRINTK("%s: GNTMAP_readonly is not implemented yet. flags %x\n",
    1.71 +                __func__, flags);
    1.72 +#endif
    1.73 +        flags &= ~GNTMAP_readonly;
    1.74 +    }
    1.75 +
    1.76 +    // get_page(mfn_to_page(mfn)) is not needed.
    1.77 +    // the caller, __gnttab_map_grant_ref() does it.
    1.78 +
    1.79 +    pte = lookup_noalloc_domain_pte(d, gpaddr);
    1.80 +    if (pte == NULL || !pte_present(*pte) || pte_pfn(*pte) != mfn)
    1.81 +        return GNTST_general_error;//XXX GNTST_bad_pseudo_phys_addr
    1.82 +
    1.83 +    // update pte
    1.84 +    old_pte = ptep_get_and_clear(d->arch.mm, gpaddr, pte);
    1.85 +    if (pte_present(old_pte)) {
    1.86 +        old_mfn = pte_pfn(old_pte);//XXX
    1.87 +    }
    1.88 +    domain_page_flush(d, gpaddr, old_mfn, INVALID_MFN);
    1.89 +
    1.90 +    return GNTST_okay;
    1.91 +}
    1.92 +
    1.93 +//XXX needs refcount patch
    1.94 +//XXX heavily depends on the struct page layout.
    1.95 +//XXX SMP
    1.96 +int
    1.97 +steal_page_for_grant_transfer(struct domain *d, struct page_info *page)
    1.98 +{
    1.99 +#if 0 /* if big endian */
   1.100 +# error "implement big endian version of steal_page_for_grant_transfer()"
   1.101 +#endif
   1.102 +    u32 _d, _nd;
   1.103 +    u64 x, nx, y;
   1.104 +    unsigned long mpaddr = get_gpfn_from_mfn(page_to_mfn(page)) << PAGE_SHIFT;
   1.105 +    struct page_info *new;
   1.106 +
   1.107 +    // zap_domain_page_one() does put_page(page)
   1.108 +    if (get_page(page, d) == 0) {
   1.109 +        DPRINTK("%s:%d page %p mfn %ld d 0x%p id %d\n",
   1.110 +                __func__, __LINE__, page, page_to_mfn(page), d, d->domain_id);
   1.111 +        return -1;
   1.112 +    }
   1.113 +    zap_domain_page_one(d, mpaddr);
   1.114 +
   1.115 +    spin_lock(&d->page_alloc_lock);
   1.116 +
   1.117 +    /*
   1.118 +     * The tricky bit: atomically release ownership while there is just one
   1.119 +     * benign reference to the page (PGC_allocated). If that reference
   1.120 +     * disappears then the deallocation routine will safely spin.
   1.121 +     */
   1.122 +    _d  = pickle_domptr(d);
   1.123 +    y = *((u64*)&page->count_info);
   1.124 +    do {
   1.125 +        x = y;
   1.126 +        nx = x & 0xffffffff;
   1.127 +        // page->count_info: untouched
   1.128 +        // page->u.inused._domain = 0;
   1.129 +        _nd = x >> 32;
   1.130 +
   1.131 +        if (unlikely((x & (PGC_count_mask | PGC_allocated)) !=
   1.132 +                     (1 | PGC_allocated)) ||
   1.133 +            unlikely(_nd != _d)) {
   1.134 +            struct domain* nd = unpickle_domptr(_nd);
   1.135 +            if (nd == NULL) {
   1.136 +                DPRINTK("gnttab_transfer: Bad page %p: ed=%p(%u) 0x%x, "
   1.137 +                        "sd=%p 0x%x,"
   1.138 +                        " caf=%016lx, taf=%" PRtype_info "\n",
   1.139 +                        (void *) page_to_mfn(page),
   1.140 +                        d, d->domain_id, _d,
   1.141 +                        nd, _nd,
   1.142 +                        x,
   1.143 +                        page->u.inuse.type_info);
   1.144 +            } else {
   1.145 +                DPRINTK("gnttab_transfer: Bad page %p: ed=%p(%u) 0x%x, "
   1.146 +                        "sd=%p(%u) 0x%x,"
   1.147 +                        " caf=%016lx, taf=%" PRtype_info "\n",
   1.148 +                        (void *) page_to_mfn(page),
   1.149 +                        d, d->domain_id, _d,
   1.150 +                        nd, nd->domain_id, _nd,
   1.151 +                        x,
   1.152 +                        page->u.inuse.type_info);
   1.153 +            }
   1.154 +            spin_unlock(&d->page_alloc_lock);
   1.155 +            return -1;
   1.156 +        }
   1.157 +
   1.158 +        y = cmpxchg((u64*)&page->count_info, x, nx);
   1.159 +    } while (unlikely(y != x));
   1.160 +
   1.161 +    /*
   1.162 +     * Unlink from 'd'. At least one reference remains (now anonymous), so
   1.163 +     * noone else is spinning to try to delete this page from 'd'.
   1.164 +     */
   1.165 +    d->tot_pages--;
   1.166 +    list_del(&page->list);
   1.167 +
   1.168 +    spin_unlock(&d->page_alloc_lock);
   1.169 +
   1.170 +#if 1
   1.171 +    //XXX Until net_rx_action() fix
   1.172 +    // assign new page for this mpaddr
   1.173 +    new = assign_new_domain_page(d, mpaddr);
   1.174 +    BUG_ON(new == NULL);//XXX
   1.175 +#endif
   1.176 +
   1.177 +    return 0;
   1.178 +}
   1.179 +
   1.180 +void
   1.181 +guest_physmap_add_page(struct domain *d, unsigned long gpfn,
   1.182 +                       unsigned long mfn)
   1.183 +{
   1.184 +    assign_domain_page_replace(d, gpfn << PAGE_SHIFT, mfn, 0/* XXX */);
   1.185 +    set_gpfn_from_mfn(mfn, gpfn);
   1.186 +}
   1.187 +
   1.188 +void
   1.189 +guest_physmap_remove_page(struct domain *d, unsigned long gpfn,
   1.190 +                          unsigned long mfn)
   1.191 +{
   1.192 +    BUG_ON(mfn == 0);//XXX
   1.193 +    zap_domain_page_one(d, gpfn << PAGE_SHIFT);
   1.194 +}
   1.195  #endif
   1.196  
   1.197  /* Flush cache of domain d.  */
     2.1 --- a/xen/include/asm-ia64/config.h	Tue May 09 11:34:45 2006 -0600
     2.2 +++ b/xen/include/asm-ia64/config.h	Tue May 09 11:38:35 2006 -0600
     2.3 @@ -239,6 +239,10 @@ void dummy_called(char *function);
     2.4  // these declarations got moved at some point, find a better place for them
     2.5  extern int ht_per_core;
     2.6  
     2.7 +#ifdef CONFIG_XEN_IA64_DOM0_VP
     2.8 +#define CONFIG_SHADOW	1
     2.9 +#endif
    2.10 +
    2.11  // xen/include/asm/config.h
    2.12  /******************************************************************************
    2.13   * config.h
     3.1 --- a/xen/include/asm-ia64/grant_table.h	Tue May 09 11:34:45 2006 -0600
     3.2 +++ b/xen/include/asm-ia64/grant_table.h	Tue May 09 11:38:35 2006 -0600
     3.3 @@ -7,10 +7,22 @@
     3.4  
     3.5  #define ORDER_GRANT_FRAMES 0
     3.6  
     3.7 +#ifndef CONFIG_XEN_IA64_DOM0_VP
     3.8 +// for grant map/unmap
     3.9  #define create_grant_host_mapping(a, f, fl)  0
    3.10  #define destroy_grant_host_mapping(a, f, fl) 0
    3.11  
    3.12 +// for grant transfer
    3.13  #define steal_page_for_grant_transfer(d, p)  0
    3.14 +#else
    3.15 +// for grant map/unmap
    3.16 +int create_grant_host_mapping(unsigned long gpaddr, unsigned long mfn, unsigned int flags);
    3.17 +int destroy_grant_host_mapping(unsigned long gpaddr, unsigned long mfn, unsigned int flags);
    3.18 +
    3.19 +// for grant transfer
    3.20 +int steal_page_for_grant_transfer(struct domain *d, struct page_info *page);
    3.21 +void guest_physmap_add_page(struct domain *d, unsigned long gpfn, unsigned long mfn);
    3.22 +#endif
    3.23  
    3.24  #define gnttab_create_shared_page(d, t, i) ((void)0)
    3.25  
    3.26 @@ -20,13 +32,21 @@
    3.27  #define gnttab_shared_maddr(d, t, i)                        \
    3.28      virt_to_maddr((char*)(t)->shared + ((i) << PAGE_SHIFT))
    3.29  
    3.30 -#define gnttab_shared_gmfn(d, t, i)                                          \
    3.31 +#ifndef CONFIG_XEN_IA64_DOM0_VP
    3.32 +# define gnttab_shared_gmfn(d, t, i)                                         \
    3.33      ({ ((d) == dom0) ?                                                       \
    3.34              (virt_to_maddr((t)->shared) >> PAGE_SHIFT) + (i):                \
    3.35              assign_domain_page((d),                                          \
    3.36                                 IA64_GRANT_TABLE_PADDR + ((i) << PAGE_SHIFT), \
    3.37                                 gnttab_shared_maddr(d, t, i)),                \
    3.38              (IA64_GRANT_TABLE_PADDR >> PAGE_SHIFT) + (i);})
    3.39 +#else
    3.40 +# define gnttab_shared_gmfn(d, t, i)                                    \
    3.41 +    ({ assign_domain_page((d),                                          \
    3.42 +                          IA64_GRANT_TABLE_PADDR + ((i) << PAGE_SHIFT), \
    3.43 +                          gnttab_shared_maddr((d), (t), (i)));          \
    3.44 +        (IA64_GRANT_TABLE_PADDR >> PAGE_SHIFT) + (i);})
    3.45 +#endif
    3.46  
    3.47  #define gnttab_log_dirty(d, f) ((void)0)
    3.48  
     4.1 --- a/xen/include/asm-ia64/linux-xen/asm/pgtable.h	Tue May 09 11:34:45 2006 -0600
     4.2 +++ b/xen/include/asm-ia64/linux-xen/asm/pgtable.h	Tue May 09 11:38:35 2006 -0600
     4.3 @@ -383,6 +383,7 @@ ptep_test_and_clear_dirty (struct vm_are
     4.4  	return 1;
     4.5  #endif
     4.6  }
     4.7 +#endif
     4.8  
     4.9  static inline pte_t
    4.10  ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
    4.11 @@ -396,6 +397,7 @@ ptep_get_and_clear(struct mm_struct *mm,
    4.12  #endif
    4.13  }
    4.14  
    4.15 +#ifndef XEN
    4.16  static inline void
    4.17  ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
    4.18  {
     5.1 --- a/xen/include/asm-ia64/shadow.h	Tue May 09 11:34:45 2006 -0600
     5.2 +++ b/xen/include/asm-ia64/shadow.h	Tue May 09 11:38:35 2006 -0600
     5.3 @@ -1,2 +1,57 @@
     5.4 -/* empty */
     5.5 +/******************************************************************************
     5.6 + * include/asm-ia64/shadow.h
     5.7 + *
     5.8 + * Copyright (c) 2006 Isaku Yamahata <yamahata at valinux co jp>
     5.9 + *                    VA Linux Systems Japan K.K.
    5.10 + *
    5.11 + * This program is free software; you can redistribute it and/or modify
    5.12 + * it under the terms of the GNU General Public License as published by
    5.13 + * the Free Software Foundation; either version 2 of the License, or
    5.14 + * (at your option) any later version.
    5.15 + *
    5.16 + * This program is distributed in the hope that it will be useful,
    5.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    5.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    5.19 + * GNU General Public License for more details.
    5.20 + *
    5.21 + * You should have received a copy of the GNU General Public License
    5.22 + * along with this program; if not, write to the Free Software
    5.23 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    5.24 + *
    5.25 + */
    5.26  
    5.27 +#ifndef _XEN_SHADOW_H
    5.28 +#define _XEN_SHADOW_H
    5.29 +
    5.30 +#include <xen/config.h>
    5.31 +
    5.32 +#ifdef CONFIG_XEN_IA64_DOM0_VP
    5.33 +#ifndef CONFIG_SHADOW
    5.34 +# error "CONFIG_SHADOW must be defined"
    5.35 +#endif
    5.36 +
    5.37 +#define shadow_drop_references(d, p)          ((void)0)
    5.38 +
    5.39 +// this is used only x86-specific code
    5.40 +//#define shadow_sync_and_drop_references(d, p) ((void)0)
    5.41 +
    5.42 +#define shadow_mode_translate(d)              (1)
    5.43 +
    5.44 +// for granttab transfer. XENMEM_populate_physmap
    5.45 +void guest_physmap_add_page(struct domain *d, unsigned long gpfn, unsigned long mfn);
    5.46 +// for balloon driver. XENMEM_decrease_reservation
    5.47 +void guest_physmap_remove_page(struct domain *d, unsigned long gpfn, unsigned long mfn);
    5.48 +#endif
    5.49 +
    5.50 +#endif // _XEN_SHADOW_H
    5.51 +
    5.52 +/*
    5.53 + * Local variables:
    5.54 + * mode: C
    5.55 + * c-set-style: "BSD"
    5.56 + * c-basic-offset: 4
    5.57 + * tab-width: 4
    5.58 + * indent-tabs-mode: nil
    5.59 + * End:
    5.60 + */
    5.61 +