ia64/xen-unstable

changeset 13303:e1971b229e89

Enable compatibility mode operation for HYPERVISOR_grant_table_op.

Signed-off-by: Jan Beulich <jbeulich@novell.com>
author Emmanuel Ackaouy <ack@xensource.com>
date Fri Jan 05 17:34:35 2007 +0000 (2007-01-05)
parents 883c0080dd05
children e82eda09ef41
files xen/arch/x86/x86_64/compat/entry.S xen/common/Makefile xen/common/compat/grant_table.c xen/common/grant_table.c xen/include/xlat.lst
line diff
     1.1 --- a/xen/arch/x86/x86_64/compat/entry.S	Fri Jan 05 17:34:35 2007 +0000
     1.2 +++ b/xen/arch/x86/x86_64/compat/entry.S	Fri Jan 05 17:34:35 2007 +0000
     1.3 @@ -279,7 +279,6 @@ CFIX14:
     1.4  .section .rodata, "a", @progbits
     1.5  
     1.6  #define compat_platform_op domain_crash_synchronous
     1.7 -#define compat_grant_table_op domain_crash_synchronous
     1.8  #define compat_acm_op domain_crash_synchronous
     1.9  #define compat_xenoprof_op domain_crash_synchronous
    1.10  #define compat_sysctl domain_crash_synchronous
     2.1 --- a/xen/common/Makefile	Fri Jan 05 17:34:35 2007 +0000
     2.2 +++ b/xen/common/Makefile	Fri Jan 05 17:34:35 2007 +0000
     2.3 @@ -42,5 +42,6 @@ version.o: $(BASEDIR)/include/xen/compil
     2.4  
     2.5  ifeq ($(CONFIG_COMPAT),y)
     2.6  # extra dependencies
     2.7 +grant_table.o: compat/grant_table.c
     2.8  schedule.o: compat/schedule.c
     2.9  endif
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/xen/common/compat/grant_table.c	Fri Jan 05 17:34:35 2007 +0000
     3.3 @@ -0,0 +1,218 @@
     3.4 +/******************************************************************************
     3.5 + * common/compat/grant_table.c
     3.6 + *
     3.7 + */
     3.8 +
     3.9 +#include <compat/grant_table.h>
    3.10 +
    3.11 +#define xen_grant_entry grant_entry
    3.12 +CHECK_grant_entry;
    3.13 +#undef xen_grant_entry
    3.14 +
    3.15 +#define xen_gnttab_map_grant_ref gnttab_map_grant_ref
    3.16 +CHECK_gnttab_map_grant_ref;
    3.17 +#undef xen_gnttab_map_grant_ref
    3.18 +
    3.19 +#define xen_gnttab_unmap_grant_ref gnttab_unmap_grant_ref
    3.20 +CHECK_gnttab_unmap_grant_ref;
    3.21 +#undef xen_gnttab_unmap_grant_ref
    3.22 +
    3.23 +DEFINE_XEN_GUEST_HANDLE(gnttab_setup_table_compat_t);
    3.24 +DEFINE_XEN_GUEST_HANDLE(gnttab_transfer_compat_t);
    3.25 +DEFINE_XEN_GUEST_HANDLE(gnttab_copy_compat_t);
    3.26 +
    3.27 +#define xen_gnttab_dump_table gnttab_dump_table
    3.28 +CHECK_gnttab_dump_table;
    3.29 +#undef xen_gnttab_dump_table
    3.30 +
    3.31 +int compat_grant_table_op(unsigned int cmd,
    3.32 +                          XEN_GUEST_HANDLE(void) cmp_uop,
    3.33 +                          unsigned int count)
    3.34 +{
    3.35 +    int rc = 0;
    3.36 +    unsigned int i;
    3.37 +
    3.38 +    switch ( cmd )
    3.39 +    {
    3.40 +#define CASE(name) \
    3.41 +    case GNTTABOP_##name: \
    3.42 +        if ( unlikely(!guest_handle_okay(guest_handle_cast(cmp_uop, \
    3.43 +                                                           gnttab_##name##_compat_t), \
    3.44 +                                         count)) ) \
    3.45 +            rc = -EFAULT; \
    3.46 +        break
    3.47 +
    3.48 +#ifndef CHECK_gnttab_map_grant_ref
    3.49 +    CASE(map_grant_ref);
    3.50 +#endif
    3.51 +
    3.52 +#ifndef CHECK_gnttab_unmap_grant_ref
    3.53 +    CASE(unmap_grant_ref);
    3.54 +#endif
    3.55 +
    3.56 +#ifndef CHECK_gnttab_setup_table
    3.57 +    CASE(setup_table);
    3.58 +#endif
    3.59 +
    3.60 +#ifndef CHECK_gnttab_transfer
    3.61 +    CASE(transfer);
    3.62 +#endif
    3.63 +
    3.64 +#ifndef CHECK_gnttab_copy
    3.65 +    CASE(copy);
    3.66 +#endif
    3.67 +
    3.68 +#ifndef CHECK_gnttab_dump_table
    3.69 +    CASE(dump_table);
    3.70 +#endif
    3.71 +
    3.72 +#undef CASE
    3.73 +    default:
    3.74 +        return do_grant_table_op(cmd, cmp_uop, count);
    3.75 +    }
    3.76 +
    3.77 +    if ( count > 512 )
    3.78 +        rc = -EINVAL;
    3.79 +
    3.80 +    for ( i = 0; i < count && rc == 0; )
    3.81 +    {
    3.82 +        unsigned int n;
    3.83 +        union {
    3.84 +            XEN_GUEST_HANDLE(void) uop;
    3.85 +            struct gnttab_setup_table *setup;
    3.86 +            struct gnttab_transfer *xfer;
    3.87 +            struct gnttab_copy *copy;
    3.88 +        } nat;
    3.89 +        union {
    3.90 +            struct compat_gnttab_setup_table setup;
    3.91 +            struct compat_gnttab_transfer xfer;
    3.92 +            struct compat_gnttab_copy copy;
    3.93 +        } cmp;
    3.94 +
    3.95 +        set_xen_guest_handle(nat.uop, (void *)COMPAT_ARG_XLAT_VIRT_START(current->vcpu_id));
    3.96 +        switch ( cmd )
    3.97 +        {
    3.98 +        case GNTTABOP_setup_table:
    3.99 +            if ( unlikely(count > 1) )
   3.100 +                rc = -EINVAL;
   3.101 +            else if ( unlikely(__copy_from_guest(&cmp.setup, cmp_uop, 1)) )
   3.102 +                rc = -EFAULT;
   3.103 +            else if ( unlikely(!compat_handle_okay(cmp.setup.frame_list, cmp.setup.nr_frames)) )
   3.104 +                rc = -EFAULT;
   3.105 +            else
   3.106 +            {
   3.107 +                BUILD_BUG_ON((COMPAT_ARG_XLAT_SIZE - sizeof(*nat.setup)) / sizeof(*nat.setup->frame_list.p) < NR_GRANT_FRAMES);
   3.108 +#define XLAT_gnttab_setup_table_HNDL_frame_list(_d_, _s_) \
   3.109 +                set_xen_guest_handle((_d_)->frame_list, (unsigned long *)(nat.setup + 1))
   3.110 +                XLAT_gnttab_setup_table(nat.setup, &cmp.setup);
   3.111 +#undef XLAT_gnttab_setup_table_HNDL_frame_list
   3.112 +                rc = gnttab_setup_table(guest_handle_cast(nat.uop, gnttab_setup_table_t), 1);
   3.113 +            }
   3.114 +            if ( rc == 0 )
   3.115 +            {
   3.116 +                BUG_ON(nat.setup->nr_frames > NR_GRANT_FRAMES);
   3.117 +#define XLAT_gnttab_setup_table_HNDL_frame_list(_d_, _s_) \
   3.118 +                do \
   3.119 +                { \
   3.120 +                    if ( (_s_)->status == GNTST_okay ) \
   3.121 +                    { \
   3.122 +                        for ( i = 0; i < (_s_)->nr_frames; ++i ) \
   3.123 +                        { \
   3.124 +                            unsigned int frame = (_s_)->frame_list.p[i]; \
   3.125 +                            BUG_ON(frame != (_s_)->frame_list.p[i]); \
   3.126 +                            (void)__copy_to_compat_offset((_d_)->frame_list, i, &frame, 1); \
   3.127 +                        } \
   3.128 +                    } \
   3.129 +                } while (0)
   3.130 +                XLAT_gnttab_setup_table(&cmp.setup, nat.setup);
   3.131 +#undef XLAT_gnttab_setup_table_HNDL_frame_list
   3.132 +                if ( unlikely(__copy_to_guest(cmp_uop, &cmp.setup, 1)) )
   3.133 +                    rc = -EFAULT;
   3.134 +                else
   3.135 +                    i = 1;
   3.136 +            }
   3.137 +            break;
   3.138 +
   3.139 +        case GNTTABOP_transfer:
   3.140 +            for ( n = 0; i < COMPAT_ARG_XLAT_SIZE / sizeof(*nat.xfer) && i < count && rc == 0; ++i, ++n )
   3.141 +            {
   3.142 +                if ( unlikely(__copy_from_guest_offset(&cmp.xfer, cmp_uop, i, 1)) )
   3.143 +                    rc = -EFAULT;
   3.144 +                else
   3.145 +                {
   3.146 +                    XLAT_gnttab_transfer(nat.xfer + n, &cmp.xfer);
   3.147 +                }
   3.148 +            }
   3.149 +            if ( rc == 0 )
   3.150 +                rc = gnttab_transfer(guest_handle_cast(nat.uop, gnttab_transfer_t), n);
   3.151 +            if ( rc == 0 )
   3.152 +            {
   3.153 +                XEN_GUEST_HANDLE(gnttab_transfer_compat_t) xfer;
   3.154 +
   3.155 +                xfer = guest_handle_cast(cmp_uop, gnttab_transfer_compat_t);
   3.156 +                guest_handle_add_offset(xfer, i);
   3.157 +                while ( n-- )
   3.158 +                {
   3.159 +                    guest_handle_add_offset(xfer, -1);
   3.160 +                    if ( __copy_field_to_guest(xfer, nat.xfer, status) )
   3.161 +                        rc = -EFAULT;
   3.162 +                }
   3.163 +            }
   3.164 +            break;
   3.165 +
   3.166 +        case GNTTABOP_copy:
   3.167 +            for ( n = 0; i < COMPAT_ARG_XLAT_SIZE / sizeof(*nat.copy) && i < count && rc == 0; ++i, ++n )
   3.168 +            {
   3.169 +                if ( unlikely(__copy_from_guest_offset(&cmp.copy, cmp_uop, i, 1)) )
   3.170 +                    rc = -EFAULT;
   3.171 +                else
   3.172 +                {
   3.173 +                    enum XLAT_gnttab_copy_source_u source_u;
   3.174 +                    enum XLAT_gnttab_copy_dest_u dest_u;
   3.175 +
   3.176 +                    if ( cmp.copy.flags & GNTCOPY_source_gref )
   3.177 +                        source_u = XLAT_gnttab_copy_source_u_ref;
   3.178 +                    else
   3.179 +                        source_u = XLAT_gnttab_copy_source_u_gmfn;
   3.180 +                    if ( cmp.copy.flags & GNTCOPY_dest_gref )
   3.181 +                        dest_u = XLAT_gnttab_copy_dest_u_ref;
   3.182 +                    else
   3.183 +                        dest_u = XLAT_gnttab_copy_dest_u_gmfn;
   3.184 +                    XLAT_gnttab_copy(nat.copy + n, &cmp.copy);
   3.185 +                }
   3.186 +            }
   3.187 +            if ( rc == 0 )
   3.188 +                rc = gnttab_copy(guest_handle_cast(nat.uop, gnttab_copy_t), n);
   3.189 +            if ( rc == 0 )
   3.190 +            {
   3.191 +                XEN_GUEST_HANDLE(gnttab_copy_compat_t) copy;
   3.192 +
   3.193 +                copy = guest_handle_cast(cmp_uop, gnttab_copy_compat_t);
   3.194 +                guest_handle_add_offset(copy, i);
   3.195 +                while ( n-- )
   3.196 +                {
   3.197 +                    guest_handle_add_offset(copy, -1);
   3.198 +                    if ( __copy_field_to_guest(copy, nat.copy, status) )
   3.199 +                        rc = -EFAULT;
   3.200 +                }
   3.201 +            }
   3.202 +            break;
   3.203 +
   3.204 +        default:
   3.205 +            domain_crash(current->domain);
   3.206 +            break;
   3.207 +        }
   3.208 +    }
   3.209 +
   3.210 +    return rc;
   3.211 +}
   3.212 +
   3.213 +/*
   3.214 + * Local variables:
   3.215 + * mode: C
   3.216 + * c-set-style: "BSD"
   3.217 + * c-basic-offset: 4
   3.218 + * tab-width: 4
   3.219 + * indent-tabs-mode: nil
   3.220 + * End:
   3.221 + */
     4.1 --- a/xen/common/grant_table.c	Fri Jan 05 17:34:35 2007 +0000
     4.2 +++ b/xen/common/grant_table.c	Fri Jan 05 17:34:35 2007 +0000
     4.3 @@ -1048,6 +1048,10 @@ do_grant_table_op(
     4.4      return rc;
     4.5  }
     4.6  
     4.7 +#ifdef CONFIG_COMPAT
     4.8 +#include "compat/grant_table.c"
     4.9 +#endif
    4.10 +
    4.11  int 
    4.12  grant_table_create(
    4.13      struct domain *d)
     5.1 --- a/xen/include/xlat.lst	Fri Jan 05 17:34:35 2007 +0000
     5.2 +++ b/xen/include/xlat.lst	Fri Jan 05 17:34:35 2007 +0000
     5.3 @@ -20,6 +20,13 @@
     5.4  ?	evtchn_send			event_channel.h
     5.5  ?	evtchn_status			event_channel.h
     5.6  ?	evtchn_unmask			event_channel.h
     5.7 +!	gnttab_copy			grant_table.h
     5.8 +?	gnttab_dump_table		grant_table.h
     5.9 +?	gnttab_map_grant_ref		grant_table.h
    5.10 +!	gnttab_setup_table		grant_table.h
    5.11 +!	gnttab_transfer			grant_table.h
    5.12 +?	gnttab_unmap_grant_ref		grant_table.h
    5.13 +?	grant_entry			grant_table.h
    5.14  !	add_to_physmap			memory.h
    5.15  !	foreign_memory_map		memory.h
    5.16  !	memory_exchange			memory.h