Make some basic cases of grant tables work in shadow translate mode.

This is enough to get block devices to work.

Note that this involves assigning PFNs to the machine frames used for
the grant table structures.  While I'm here, I also assigned a PFN to
the shared info frame.

Signed-off-by: Steven Smith, sos22@cam.ac.uk
This commit is contained in:
sos22@douglas.cl.cam.ac.uk committed 2006-01-25 18:57:44 +01:00
1 parent a365040987
commit cd9edced7b
6 files changed
+99 -11

No files matched your search

+16 -7
View File
@@ -3,6 +3,7 @@
*/
#include "xg_private.h"
#include "xc_private.h"
#include <xenctrl.h>
#if defined(__i386__)
@@ -32,6 +33,8 @@
#define L4_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
#endif
#define NR_GRANT_FRAMES 4
#ifdef __ia64__
#define get_tot_pages xc_get_max_pages
#else
@@ -504,6 +507,8 @@ static int setup_guest(int xc_handle,
goto error_out;
}
shadow_mode_enabled = !!strstr(dsi.xen_guest_string,
"SHADOW=translate");
/*
* Why do we need this? The number of page-table frames depends on the
* size of the bootstrap address space. But the size of the address space
@@ -587,7 +592,7 @@ static int setup_guest(int xc_handle,
goto error_out;
}
if ( (page_array = malloc((nr_pages + 1) * sizeof(unsigned long))) == NULL )
if ( (page_array = malloc((nr_pages + 1 + NR_GRANT_FRAMES) * sizeof(unsigned long))) == NULL )
{
PERROR("Could not allocate memory");
goto error_out;
@@ -622,19 +627,23 @@ static int setup_guest(int xc_handle,
if ( (mmu = xc_init_mmu_updates(xc_handle, dom)) == NULL )
goto error_out;
shadow_mode_enabled = !!strstr(dsi.xen_guest_string,
"SHADOW=translate");
/* Write the phys->machine and machine->phys table entries. */
physmap_pfn = (vphysmap_start - dsi.v_start) >> PAGE_SHIFT;
physmap = physmap_e = xc_map_foreign_range(
xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
page_array[physmap_pfn++]);
if (shadow_mode_enabled)
page_array[nr_pages] = shared_info_frame;
page_array[nr_pages] = shared_info_frame;
for ( count = 0; count < nr_pages + shadow_mode_enabled; count++ )
if ( xc_get_gnttab_frames(xc_handle,
dom,
page_array + 1 + nr_pages,
NR_GRANT_FRAMES) <= 0) {
fprintf(stderr, "cannot get grant table frames\n");
goto error_out;
}
for ( count = 0; count < nr_pages + 1 + NR_GRANT_FRAMES; count++ )
{
if ( xc_add_mmu_update(
xc_handle, mmu,
+29
View File
@@ -314,6 +314,35 @@ int xc_get_pfn_list(int xc_handle,
return (ret < 0) ? -1 : op.u.getmemlist.num_pfns;
}
int xc_get_gnttab_frames(int xc_handle,
uint32_t domid,
unsigned long *pfn_buf,
unsigned long max_pfns)
{
DECLARE_DOM0_OP;
int ret;
op.cmd = DOM0_GETGNTTABLIST;
op.u.getgnttablist.domain = (domid_t)domid;
op.u.getgnttablist.max_pfns = max_pfns;
op.u.getgnttablist.buffer = pfn_buf;
#ifdef VALGRIND
memset(pfn_buf, 0, max_pfns * sizeof(unsigned long));
#endif
if ( mlock(pfn_buf, max_pfns * sizeof(unsigned long)) != 0 )
{
PERROR("xc_get_pfn_list: pfn_buf mlock failed");
return -1;
}
ret = do_dom0_op(xc_handle, &op);
safe_munlock(pfn_buf, max_pfns * sizeof(unsigned long));
return (ret < 0) ? -1 : op.u.getgnttablist.num_pfns;
}
long xc_get_tot_pages(int xc_handle, uint32_t domid)
{
DECLARE_DOM0_OP;
+3
View File
@@ -111,6 +111,9 @@ static inline int do_dom0_op(int xc_handle, dom0_op_t *op)
return ret;
}
int xc_get_gnttab_frames(int xc_handle, uint32_t domid, unsigned long *pfn_buf,
unsigned long max_pfns);
/*
* ioctl-based mfn mapping interface
+32
View File
@@ -330,6 +330,38 @@ long arch_do_dom0_op(dom0_op_t *op, dom0_op_t *u_dom0_op)
}
break;
case DOM0_GETGNTTABLIST:
{
int i;
struct domain *d = find_domain_by_id(op->u.getgnttablist.domain);
unsigned long max_pfns = op->u.getgnttablist.max_pfns;
unsigned long pfn;
unsigned long *buffer = op->u.getgnttablist.buffer;
ret = -EINVAL;
if ( d != NULL )
{
ret = 0;
for ( i = 0; i < max_pfns && i < NR_GRANT_FRAMES; i++ )
{
pfn = gnttab_shared_mfn(d, d->grant_table, i);
if ( put_user(pfn, buffer) )
{
ret = -EFAULT;
break;
}
buffer++;
}
op->u.getgnttablist.num_pfns = i;
copy_to_user(u_dom0_op, op, sizeof(*op));
put_domain(d);
}
}
break;
case DOM0_GETMEMLIST:
{
int i;
+7 -3
View File
@@ -481,6 +481,7 @@ gnttab_setup_table(
gnttab_setup_table_t op;
struct domain *d;
int i;
unsigned long mfn;
if ( count != 1 )
return -EINVAL;
@@ -520,9 +521,12 @@ gnttab_setup_table(
{
ASSERT(d->grant_table != NULL);
(void)put_user(GNTST_okay, &uop->status);
for ( i = 0; i < op.nr_frames; i++ )
(void)put_user(gnttab_shared_mfn(d, d->grant_table, i),
&op.frame_list[i]);
for ( i = 0; i < op.nr_frames; i++ ) {
mfn = gnttab_shared_mfn(d, d->grant_table, i);
if (shadow_mode_translate(d))
mfn = __mfn_to_gpfn(d, mfn);
(void)put_user(mfn, &op.frame_list[i]);
}
}
put_domain(d);
+12 -1
View File
@@ -430,7 +430,17 @@ typedef struct {
domid_t domain; /* domain to be affected */
unsigned long mfn; /* machine frame to be initialised */
} dom0_hypercall_init_t;
#define DOM0_GETGNTTABLIST 49
typedef struct {
/* IN variables. */
domid_t domain;
unsigned long max_pfns;
void *buffer;
/* OUT variables. */
unsigned long num_pfns;
} dom0_getgnttablist_t;
typedef struct {
uint32_t cmd;
uint32_t interface_version; /* DOM0_INTERFACE_VERSION */
@@ -472,6 +482,7 @@ typedef struct {
dom0_irq_permission_t irq_permission;
dom0_iomem_permission_t iomem_permission;
dom0_hypercall_init_t hypercall_init;
dom0_getgnttablist_t getgnttablist;
uint8_t pad[128];
} u;
} dom0_op_t;
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.