]> xenbits.xensource.com Git - xen.git/commitdiff
x86/64 compat: Replace hypervisor BUG_ON() with a cleaner hypercall failure.
authorKeir Fraser <keir.fraser@citrix.com>
Fri, 11 Apr 2008 08:10:58 +0000 (09:10 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Fri, 11 Apr 2008 08:10:58 +0000 (09:10 +0100)
While trying to run a 32-bit PV domU on a 64-bit hypervisor, I
triggered an assert in the hypervisor.  The assert dealt with the
maximum number of grants that a domU can have.  I made the hypervisor
a bit more graceful by returning an error rather than asserting.

Signed-off-by: Michael Abd-El-Malek <mabdelmalek@cmu.edu>
xen/common/compat/grant_table.c

index 882d435a657ee712db8afccb801d2f387218f58f..8781a331cf4e3575806b34dc46a9f97052a104b5 100644 (file)
@@ -109,12 +109,24 @@ int compat_grant_table_op(unsigned int cmd,
                 rc = -EFAULT;
             else
             {
-                BUG_ON((COMPAT_ARG_XLAT_SIZE - sizeof(*nat.setup)) / sizeof(*nat.setup->frame_list.p) < max_nr_grant_frames);
+                unsigned int max_frame_list_size_in_page =
+                    (COMPAT_ARG_XLAT_SIZE - sizeof(*nat.setup)) /
+                    sizeof(*nat.setup->frame_list.p);
+                if ( max_frame_list_size_in_page < max_nr_grant_frames )
+                {
+                    gdprintk(XENLOG_WARNING,
+                             "max_nr_grant_frames is too large (%u,%u)\n",
+                             max_nr_grant_frames, max_frame_list_size_in_page);
+                    rc = -EINVAL;
+                }
+                else
+                {
 #define XLAT_gnttab_setup_table_HNDL_frame_list(_d_, _s_) \
-                set_xen_guest_handle((_d_)->frame_list, (unsigned long *)(nat.setup + 1))
-                XLAT_gnttab_setup_table(nat.setup, &cmp.setup);
+                    set_xen_guest_handle((_d_)->frame_list, (unsigned long *)(nat.setup + 1))
+                    XLAT_gnttab_setup_table(nat.setup, &cmp.setup);
 #undef XLAT_gnttab_setup_table_HNDL_frame_list
-                rc = gnttab_setup_table(guest_handle_cast(nat.uop, gnttab_setup_table_t), 1);
+                    rc = gnttab_setup_table(guest_handle_cast(nat.uop, gnttab_setup_table_t), 1);
+                }
             }
             if ( rc == 0 )
             {