mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
Add VGA acceleration support for cirrus logic device model
Signed-off-by: Xiaofeng Ling <xiaofeng.ling@intel.com> Signed-off-by: Yunhong Jiang <yunhong.jiang@intel.com> Signed-off-by: Asit Mallick <asit.k.mallick@intel.com>
This commit is contained in:
1 parent
2b3f9eda6b
commit
0c4708b64f
6 files changed
+284
-24
No files matched your search
@@ -231,6 +231,8 @@ typedef struct CirrusVGAState {
|
||||
int cirrus_linear_io_addr;
|
||||
int cirrus_linear_bitblt_io_addr;
|
||||
int cirrus_mmio_io_addr;
|
||||
unsigned long cirrus_lfb_addr;
|
||||
unsigned long cirrus_lfb_end;
|
||||
uint32_t cirrus_addr_mask;
|
||||
uint32_t linear_mmio_mask;
|
||||
uint8_t cirrus_shadow_gr0;
|
||||
@@ -2447,6 +2449,10 @@ static void cirrus_update_memory_access(CirrusVGAState *s)
|
||||
{
|
||||
unsigned mode;
|
||||
|
||||
extern void unset_vram_mapping(unsigned long addr, unsigned long end);
|
||||
extern void set_vram_mapping(unsigned long addr, unsigned long end);
|
||||
extern int vga_accelerate;
|
||||
|
||||
if ((s->sr[0x17] & 0x44) == 0x44) {
|
||||
goto generic_io;
|
||||
} else if (s->cirrus_srcptr != s->cirrus_srcptr_end) {
|
||||
@@ -2454,17 +2460,21 @@ static void cirrus_update_memory_access(CirrusVGAState *s)
|
||||
} else {
|
||||
if ((s->gr[0x0B] & 0x14) == 0x14) {
|
||||
goto generic_io;
|
||||
} else if (s->gr[0x0B] & 0x02) {
|
||||
goto generic_io;
|
||||
}
|
||||
|
||||
mode = s->gr[0x05] & 0x7;
|
||||
if (mode < 4 || mode > 5 || ((s->gr[0x0B] & 0x4) == 0)) {
|
||||
} else if (s->gr[0x0B] & 0x02) {
|
||||
goto generic_io;
|
||||
}
|
||||
|
||||
mode = s->gr[0x05] & 0x7;
|
||||
if (mode < 4 || mode > 5 || ((s->gr[0x0B] & 0x4) == 0)) {
|
||||
if (vga_accelerate && s->cirrus_lfb_addr && s->cirrus_lfb_end)
|
||||
set_vram_mapping(s->cirrus_lfb_addr, s->cirrus_lfb_end);
|
||||
s->cirrus_linear_write[0] = cirrus_linear_mem_writeb;
|
||||
s->cirrus_linear_write[1] = cirrus_linear_mem_writew;
|
||||
s->cirrus_linear_write[2] = cirrus_linear_mem_writel;
|
||||
} else {
|
||||
generic_io:
|
||||
if (vga_accelerate && s->cirrus_lfb_addr && s->cirrus_lfb_end)
|
||||
unset_vram_mapping(s->cirrus_lfb_addr, s->cirrus_lfb_end);
|
||||
s->cirrus_linear_write[0] = cirrus_linear_writeb;
|
||||
s->cirrus_linear_write[1] = cirrus_linear_writew;
|
||||
s->cirrus_linear_write[2] = cirrus_linear_writel;
|
||||
@@ -3058,6 +3068,8 @@ static void cirrus_pci_lfb_map(PCIDevice *d, int region_num,
|
||||
/* XXX: add byte swapping apertures */
|
||||
cpu_register_physical_memory(addr, s->vram_size,
|
||||
s->cirrus_linear_io_addr);
|
||||
s->cirrus_lfb_addr = addr;
|
||||
s->cirrus_lfb_end = addr + VGA_RAM_SIZE;
|
||||
cpu_register_physical_memory(addr + 0x1000000, 0x400000,
|
||||
s->cirrus_linear_bitblt_io_addr);
|
||||
}
|
||||
|
||||
+4
-3
@@ -385,6 +385,7 @@ void pc_init(int ram_size, int vga_ram_size, int boot_device,
|
||||
unsigned long bios_offset, vga_bios_offset;
|
||||
int bios_size, isa_bios_size;
|
||||
PCIBus *pci_bus;
|
||||
extern void * shared_vram;
|
||||
|
||||
linux_boot = (kernel_filename != NULL);
|
||||
|
||||
@@ -511,14 +512,14 @@ void pc_init(int ram_size, int vga_ram_size, int boot_device,
|
||||
if (cirrus_vga_enabled) {
|
||||
if (pci_enabled) {
|
||||
pci_cirrus_vga_init(pci_bus,
|
||||
ds, phys_ram_base + ram_size, ram_size,
|
||||
ds, shared_vram, ram_size,
|
||||
vga_ram_size);
|
||||
} else {
|
||||
isa_cirrus_vga_init(ds, phys_ram_base + ram_size, ram_size,
|
||||
isa_cirrus_vga_init(ds, shared_vram, ram_size,
|
||||
vga_ram_size);
|
||||
}
|
||||
} else {
|
||||
vga_initialize(pci_bus, ds, phys_ram_base + ram_size, ram_size,
|
||||
vga_initialize(pci_bus, ds, shared_vram, ram_size,
|
||||
vga_ram_size);
|
||||
}
|
||||
|
||||
|
||||
@@ -1568,6 +1568,8 @@ void vga_update_display(void)
|
||||
s->graphic_mode = graphic_mode;
|
||||
full_update = 1;
|
||||
}
|
||||
|
||||
full_update = 1;
|
||||
switch(graphic_mode) {
|
||||
case GMODE_TEXT:
|
||||
vga_draw_text(s, full_update);
|
||||
@@ -1848,6 +1850,7 @@ void vga_common_init(VGAState *s, DisplayState *ds, uint8_t *vga_ram_base,
|
||||
unsigned long vga_ram_offset, int vga_ram_size)
|
||||
{
|
||||
int i, j, v, b;
|
||||
extern void* shared_vram;
|
||||
|
||||
for(i = 0;i < 256; i++) {
|
||||
v = 0;
|
||||
@@ -1876,7 +1879,7 @@ void vga_common_init(VGAState *s, DisplayState *ds, uint8_t *vga_ram_base,
|
||||
|
||||
/* qemu's vga mem is not detached from phys_ram_base and can cause DM abort
|
||||
* when guest write vga mem, so allocate a new one */
|
||||
s->vram_ptr = qemu_mallocz(vga_ram_size);
|
||||
s->vram_ptr = shared_vram;
|
||||
|
||||
s->vram_offset = vga_ram_offset;
|
||||
s->vram_size = vga_ram_size;
|
||||
|
||||
@@ -54,6 +54,8 @@
|
||||
#include "exec-all.h"
|
||||
#include "vl.h"
|
||||
|
||||
void *shared_vram;
|
||||
|
||||
shared_iopage_t *shared_page = NULL;
|
||||
extern int reset_requested;
|
||||
|
||||
|
||||
+240
-7
@@ -134,6 +134,7 @@ int pci_enabled = 1;
|
||||
int prep_enabled = 0;
|
||||
int rtc_utc = 1;
|
||||
int cirrus_vga_enabled = 1;
|
||||
int vga_accelerate = 1;
|
||||
int graphic_width = 800;
|
||||
int graphic_height = 600;
|
||||
int graphic_depth = 15;
|
||||
@@ -141,6 +142,12 @@ int full_screen = 0;
|
||||
TextConsole *vga_console;
|
||||
CharDriverState *serial_hds[MAX_SERIAL_PORTS];
|
||||
int xc_handle;
|
||||
unsigned long *vgapage_array;
|
||||
unsigned long *freepage_array;
|
||||
unsigned long free_pages;
|
||||
void *vtop_table;
|
||||
unsigned long toptab;
|
||||
unsigned long vgaram_pages;
|
||||
|
||||
/***********************************************************/
|
||||
/* x86 ISA bus support */
|
||||
@@ -2162,6 +2169,7 @@ void help(void)
|
||||
"-isa simulate an ISA-only system (default is PCI system)\n"
|
||||
"-std-vga simulate a standard VGA card with VESA Bochs Extensions\n"
|
||||
" (default is CL-GD5446 PCI VGA)\n"
|
||||
"-vgaacc [0|1] 1 to accelerate CL-GD5446 speed, default is 1\n"
|
||||
#endif
|
||||
"-loadvm file start right away with a saved state (loadvm in monitor)\n"
|
||||
"\n"
|
||||
@@ -2251,6 +2259,7 @@ enum {
|
||||
QEMU_OPTION_serial,
|
||||
QEMU_OPTION_loadvm,
|
||||
QEMU_OPTION_full_screen,
|
||||
QEMU_OPTION_vgaacc,
|
||||
};
|
||||
|
||||
typedef struct QEMUOption {
|
||||
@@ -2327,6 +2336,7 @@ const QEMUOption qemu_options[] = {
|
||||
{ "pci", 0, QEMU_OPTION_pci },
|
||||
{ "nic-pcnet", 0, QEMU_OPTION_nic_pcnet },
|
||||
{ "cirrusvga", 0, QEMU_OPTION_cirrusvga },
|
||||
{ "vgaacc", HAS_ARG, QEMU_OPTION_vgaacc },
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
@@ -2343,6 +2353,177 @@ static uint8_t *signal_stack;
|
||||
#define NET_IF_USER 1
|
||||
#define NET_IF_DUMMY 2
|
||||
|
||||
#include <xg_private.h>
|
||||
|
||||
#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_USER)
|
||||
#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
|
||||
|
||||
#ifdef __i386__
|
||||
#define _LEVEL_3_ 0
|
||||
#else
|
||||
#define _LEVEL_3_ 1
|
||||
#endif
|
||||
|
||||
#if _LEVEL_3_
|
||||
#define L3_PROT (_PAGE_PRESENT)
|
||||
#define L1_PAGETABLE_ENTRIES 512
|
||||
#else
|
||||
#define L1_PAGETABLE_ENTRIES 1024
|
||||
#endif
|
||||
|
||||
inline int
|
||||
get_vl2_table(unsigned long count, unsigned long start)
|
||||
{
|
||||
#if _LEVEL_3_
|
||||
return ((start + (count << PAGE_SHIFT)) >> L3_PAGETABLE_SHIFT) & 0x3;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
setup_mapping(int xc_handle, u32 dom, unsigned long toptab, unsigned long *mem_page_array, unsigned long *page_table_array, unsigned long v_start, unsigned long v_end)
|
||||
{
|
||||
l1_pgentry_t *vl1tab=NULL, *vl1e=NULL;
|
||||
l2_pgentry_t *vl2tab[4], *vl2e=NULL, *vl2_table = NULL;
|
||||
unsigned long l1tab;
|
||||
unsigned long ppt_alloc = 0;
|
||||
unsigned long count;
|
||||
int i = 0;
|
||||
#if _LEVEL_3_
|
||||
l3_pgentry_t *vl3tab = NULL;
|
||||
unsigned long l2tab;
|
||||
if ( (vl3tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
|
||||
PROT_READ|PROT_WRITE,
|
||||
toptab >> PAGE_SHIFT)) == NULL )
|
||||
goto error_out;
|
||||
for (i = 0; i < 4 ; i++) {
|
||||
l2tab = vl3tab[i] & PAGE_MASK;
|
||||
vl2tab[i] = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
|
||||
PROT_READ|PROT_WRITE,
|
||||
l2tab >> PAGE_SHIFT);
|
||||
if(vl2tab[i] == NULL)
|
||||
goto error_out;
|
||||
}
|
||||
munmap(vl3tab, PAGE_SIZE);
|
||||
vl3tab = NULL;
|
||||
#else
|
||||
if ( (vl2tab[0] = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
|
||||
PROT_READ|PROT_WRITE,
|
||||
toptab >> PAGE_SHIFT)) == NULL )
|
||||
goto error_out;
|
||||
#endif
|
||||
|
||||
for ( count = 0; count < ((v_end-v_start)>>PAGE_SHIFT); count++ )
|
||||
{
|
||||
if ( ((unsigned long)vl1e & (PAGE_SIZE-1)) == 0 )
|
||||
{
|
||||
vl2_table = vl2tab[get_vl2_table(count, v_start)];
|
||||
vl2e = &vl2_table[l2_table_offset(
|
||||
v_start + (count << PAGE_SHIFT))];
|
||||
|
||||
l1tab = page_table_array[ppt_alloc++] << PAGE_SHIFT;
|
||||
if ( vl1tab != NULL )
|
||||
munmap(vl1tab, PAGE_SIZE);
|
||||
|
||||
if ( (vl1tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
|
||||
PROT_READ|PROT_WRITE,
|
||||
l1tab >> PAGE_SHIFT)) == NULL )
|
||||
{
|
||||
goto error_out;
|
||||
}
|
||||
memset(vl1tab, 0, PAGE_SIZE);
|
||||
vl1e = &vl1tab[l1_table_offset(v_start + (count<<PAGE_SHIFT))];
|
||||
*vl2e = l1tab | L2_PROT;
|
||||
}
|
||||
|
||||
*vl1e = (mem_page_array[count] << PAGE_SHIFT) | L1_PROT;
|
||||
vl1e++;
|
||||
}
|
||||
error_out:
|
||||
if(vl1tab) munmap(vl1tab, PAGE_SIZE);
|
||||
for(i = 0; i < 4; i++)
|
||||
if(vl2tab[i]) munmap(vl2tab[i], PAGE_SIZE);
|
||||
return ppt_alloc;
|
||||
}
|
||||
|
||||
void
|
||||
unsetup_mapping(int xc_handle, u32 dom, unsigned long toptab, unsigned long v_start, unsigned long v_end)
|
||||
{
|
||||
l1_pgentry_t *vl1tab=NULL, *vl1e=NULL;
|
||||
l2_pgentry_t *vl2tab[4], *vl2e=NULL, *vl2_table = NULL;
|
||||
unsigned long l1tab;
|
||||
unsigned long count;
|
||||
int i = 0;
|
||||
#if _LEVEL_3_
|
||||
l3_pgentry_t *vl3tab = NULL;
|
||||
unsigned long l2tab;
|
||||
if ( (vl3tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
|
||||
PROT_READ|PROT_WRITE,
|
||||
toptab >> PAGE_SHIFT)) == NULL )
|
||||
goto error_out;
|
||||
for (i = 0; i < 4 ; i ++){
|
||||
l2tab = vl3tab[i] & PAGE_MASK;
|
||||
vl2tab[i] = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
|
||||
PROT_READ|PROT_WRITE,
|
||||
l2tab >> PAGE_SHIFT);
|
||||
if(vl2tab[i] == NULL)
|
||||
goto error_out;
|
||||
}
|
||||
munmap(vl3tab, PAGE_SIZE);
|
||||
vl3tab = NULL;
|
||||
#else
|
||||
if ( (vl2tab[0] = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
|
||||
PROT_READ|PROT_WRITE,
|
||||
toptab >> PAGE_SHIFT)) == NULL )
|
||||
goto error_out;
|
||||
#endif
|
||||
|
||||
for ( count = 0; count < ((v_end-v_start)>>PAGE_SHIFT); count++ ){
|
||||
if ( ((unsigned long)vl1e & (PAGE_SIZE-1)) == 0 )
|
||||
{
|
||||
vl2_table = vl2tab[get_vl2_table(count, v_start)];
|
||||
vl2e = &vl2_table[l2_table_offset(v_start + (count << PAGE_SHIFT))];
|
||||
l1tab = *vl2e & PAGE_MASK;
|
||||
|
||||
if(l1tab == 0)
|
||||
continue;
|
||||
if ( vl1tab != NULL )
|
||||
munmap(vl1tab, PAGE_SIZE);
|
||||
|
||||
if ( (vl1tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
|
||||
PROT_READ|PROT_WRITE,
|
||||
l1tab >> PAGE_SHIFT)) == NULL )
|
||||
{
|
||||
goto error_out;
|
||||
}
|
||||
vl1e = &vl1tab[l1_table_offset(v_start + (count<<PAGE_SHIFT))];
|
||||
*vl2e = 0;
|
||||
}
|
||||
|
||||
*vl1e = 0;
|
||||
vl1e++;
|
||||
}
|
||||
error_out:
|
||||
if(vl1tab) munmap(vl1tab, PAGE_SIZE);
|
||||
for(i = 0; i < 4; i++)
|
||||
if(vl2tab[i]) munmap(vl2tab[i], PAGE_SIZE);
|
||||
}
|
||||
|
||||
void set_vram_mapping(unsigned long addr, unsigned long end)
|
||||
{
|
||||
end = addr + VGA_RAM_SIZE;
|
||||
setup_mapping(xc_handle, domid, toptab,
|
||||
vgapage_array, freepage_array, addr, end);
|
||||
}
|
||||
|
||||
void unset_vram_mapping(unsigned long addr, unsigned long end)
|
||||
{
|
||||
end = addr + VGA_RAM_SIZE;
|
||||
/* FIXME Flush the shadow page */
|
||||
unsetup_mapping(xc_handle, domid, toptab, addr, end);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
#ifdef CONFIG_GDBSTUB
|
||||
@@ -2366,8 +2547,9 @@ int main(int argc, char **argv)
|
||||
char serial_devices[MAX_SERIAL_PORTS][128];
|
||||
int serial_device_index;
|
||||
const char *loadvm = NULL;
|
||||
unsigned long nr_pages, *page_array;
|
||||
unsigned long nr_pages, extra_pages, ram_pages, *page_array;
|
||||
extern void *shared_page;
|
||||
extern void *shared_vram;
|
||||
/* change the qemu-dm to daemon, just like bochs dm */
|
||||
// daemon(0, 0);
|
||||
|
||||
@@ -2674,6 +2856,17 @@ int main(int argc, char **argv)
|
||||
case QEMU_OPTION_cirrusvga:
|
||||
cirrus_vga_enabled = 1;
|
||||
break;
|
||||
case QEMU_OPTION_vgaacc:
|
||||
{
|
||||
const char *p;
|
||||
p = optarg;
|
||||
vga_accelerate = strtol(p, (char **)&p, 0);
|
||||
if (*p != '\0') {
|
||||
fprintf(stderr, "qemu: invalid vgaacc option\n");
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case QEMU_OPTION_std_vga:
|
||||
cirrus_vga_enabled = 0;
|
||||
break;
|
||||
@@ -2803,12 +2996,25 @@ int main(int argc, char **argv)
|
||||
/* init the memory */
|
||||
phys_ram_size = ram_size + vga_ram_size + bios_size;
|
||||
|
||||
#define PAGE_SHIFT 12
|
||||
#define PAGE_SIZE (1 << PAGE_SHIFT)
|
||||
ram_pages = ram_size/PAGE_SIZE;
|
||||
vgaram_pages = (vga_ram_size -1)/PAGE_SIZE + 1;
|
||||
free_pages = vgaram_pages / L1_PAGETABLE_ENTRIES;
|
||||
extra_pages = vgaram_pages + free_pages;
|
||||
|
||||
nr_pages = ram_size/PAGE_SIZE;
|
||||
xc_handle = xc_interface_open();
|
||||
|
||||
|
||||
xc_dominfo_t info;
|
||||
xc_domain_getinfo(xc_handle, domid, 1, &info);
|
||||
|
||||
nr_pages = info.nr_pages + extra_pages;
|
||||
|
||||
if ( xc_domain_setmaxmem(xc_handle, domid,
|
||||
(nr_pages) * PAGE_SIZE/1024 ) != 0)
|
||||
{
|
||||
perror("set maxmem");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if ( (page_array = (unsigned long *)
|
||||
malloc(nr_pages * sizeof(unsigned long))) == NULL)
|
||||
{
|
||||
@@ -2816,6 +3022,12 @@ int main(int argc, char **argv)
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (xc_domain_memory_increase_reservation(xc_handle, domid,
|
||||
extra_pages , 0, 0, NULL) != 0) {
|
||||
perror("increase reservation");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if ( xc_get_pfn_list(xc_handle, domid, page_array, nr_pages) != nr_pages )
|
||||
{
|
||||
perror("xc_get_pfn_list");
|
||||
@@ -2825,15 +3037,36 @@ int main(int argc, char **argv)
|
||||
if ((phys_ram_base = xc_map_foreign_batch(xc_handle, domid,
|
||||
PROT_READ|PROT_WRITE,
|
||||
page_array,
|
||||
nr_pages - 1)) == 0) {
|
||||
ram_pages - 1)) == 0) {
|
||||
perror("xc_map_foreign_batch");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
shared_page = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
|
||||
PROT_READ|PROT_WRITE,
|
||||
page_array[nr_pages - 1]);
|
||||
page_array[ram_pages - 1]);
|
||||
|
||||
vgapage_array = &page_array[nr_pages - vgaram_pages];
|
||||
|
||||
if ((shared_vram = xc_map_foreign_batch(xc_handle, domid,
|
||||
PROT_READ|PROT_WRITE,
|
||||
vgapage_array,
|
||||
vgaram_pages)) == 0) {
|
||||
perror("xc_map_foreign_batch vgaram ");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
memset(shared_vram, 0, vgaram_pages * PAGE_SIZE);
|
||||
toptab = page_array[ram_pages] << PAGE_SHIFT;
|
||||
|
||||
vtop_table = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE,
|
||||
PROT_READ|PROT_WRITE,
|
||||
page_array[ram_pages]);
|
||||
|
||||
freepage_array = &page_array[nr_pages - extra_pages];
|
||||
|
||||
|
||||
fprintf(logfile, "shared page at pfn:%lx, mfn: %lx\n", (nr_pages-1),
|
||||
(page_array[nr_pages - 1]));
|
||||
|
||||
@@ -383,7 +383,6 @@ static int setup_guest(int xc_handle,
|
||||
l2tab = page_array[ppt_alloc++] << PAGE_SHIFT;
|
||||
ctxt->ctrlreg[3] = l2tab;
|
||||
|
||||
/* Initialise the page tables. */
|
||||
if ( (vl2tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
|
||||
PROT_READ|PROT_WRITE,
|
||||
l2tab >> PAGE_SHIFT)) == NULL )
|
||||
@@ -415,23 +414,35 @@ static int setup_guest(int xc_handle,
|
||||
munmap(vl1tab, PAGE_SIZE);
|
||||
munmap(vl2tab, PAGE_SIZE);
|
||||
#else
|
||||
/* here l3tab means pdpt, only 4 entry is used */
|
||||
l3tab = page_array[ppt_alloc++] << PAGE_SHIFT;
|
||||
ctxt->ctrlreg[3] = l3tab;
|
||||
|
||||
/* Initialise the page tables. */
|
||||
if ( (vl3tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
|
||||
PROT_READ|PROT_WRITE,
|
||||
l3tab >> PAGE_SHIFT)) == NULL )
|
||||
goto error_out;
|
||||
memset(vl3tab, 0, PAGE_SIZE);
|
||||
|
||||
/* Fill in every PDPT entry. */
|
||||
for ( i = 0; i < L3_PAGETABLE_ENTRIES_PAE; i++ )
|
||||
{
|
||||
l2tab = page_array[ppt_alloc++] << PAGE_SHIFT;
|
||||
if ( (vl2tab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE,
|
||||
PROT_READ|PROT_WRITE,
|
||||
l2tab >> PAGE_SHIFT)) == NULL )
|
||||
goto error_out;
|
||||
memset(vl2tab, 0, PAGE_SIZE);
|
||||
munmap(vl2tab, PAGE_SIZE);
|
||||
vl3tab[i] = l2tab | L3_PROT;
|
||||
}
|
||||
|
||||
vl3e = &vl3tab[l3_table_offset(dsi.v_start)];
|
||||
|
||||
for ( count = 0; count < ((v_end-dsi.v_start)>>PAGE_SHIFT); count++ )
|
||||
{
|
||||
if (!(count % (1 << (L3_PAGETABLE_SHIFT - L1_PAGETABLE_SHIFT)))){
|
||||
l2tab = page_array[ppt_alloc++] << PAGE_SHIFT;
|
||||
if (!(count & (1 << (L3_PAGETABLE_SHIFT - L1_PAGETABLE_SHIFT)))){
|
||||
l2tab = vl3tab[count >> (L3_PAGETABLE_SHIFT - L1_PAGETABLE_SHIFT)]
|
||||
& PAGE_MASK;
|
||||
|
||||
if (vl2tab != NULL)
|
||||
munmap(vl2tab, PAGE_SIZE);
|
||||
@@ -441,8 +452,6 @@ static int setup_guest(int xc_handle,
|
||||
l2tab >> PAGE_SHIFT)) == NULL )
|
||||
goto error_out;
|
||||
|
||||
memset(vl2tab, 0, PAGE_SIZE);
|
||||
*vl3e++ = l2tab | L3_PROT;
|
||||
vl2e = &vl2tab[l2_table_offset(dsi.v_start + (count << PAGE_SHIFT))];
|
||||
}
|
||||
if ( ((unsigned long)vl1e & (PAGE_SIZE-1)) == 0 )
|
||||
|
||||