mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
bitkeeper revision 1.1159.1.124 (413c80f8x6TVGW53WE2vlecpb4z_KA)
Avoid warning message when validating a linear pagedirectory mapping.
This commit is contained in:
commit
ea5753a77c
47 files changed
+1372
-636
No files matched your search
@@ -126,6 +126,8 @@
|
||||
409ba2e7akOFqQUg6Qyg2s28xcXiMg linux-2.4.27-xen-sparse/mm/page_alloc.c
|
||||
3e5a4e683HKVU-sxtagrDasRB8eBVw linux-2.4.27-xen-sparse/mm/swapfile.c
|
||||
41180721bNns9Na7w1nJ0ZVt8bhUNA linux-2.4.27-xen-sparse/mm/vmalloc.c
|
||||
413aa1d0oNP8HXLvfPuMe6cSroUfSA linux-2.6.8.1-patches/agpgart.patch
|
||||
413aa1d0ewvSv-ohnNnQQNGsbPTTNA linux-2.6.8.1-patches/drm.patch
|
||||
40f562372u3A7_kfbYYixPHJJxYUxA linux-2.6.8.1-xen-sparse/arch/xen/Kconfig
|
||||
40f56237utH41NPukqHksuNf29IC9A linux-2.6.8.1-xen-sparse/arch/xen/Kconfig.drivers
|
||||
40f56237penAAlWVBVDpeQZNFIg8CA linux-2.6.8.1-xen-sparse/arch/xen/Makefile
|
||||
@@ -161,6 +163,7 @@
|
||||
40f562383SKvDStdtrvzr5fyCbW4rw linux-2.6.8.1-xen-sparse/arch/xen/i386/mm/hypervisor.c
|
||||
40f56239xcNylAxuGsQHwi1AyMLV8w linux-2.6.8.1-xen-sparse/arch/xen/i386/mm/init.c
|
||||
41062ab7CjxC1UBaFhOMWWdhHkIUyg linux-2.6.8.1-xen-sparse/arch/xen/i386/mm/ioremap.c
|
||||
413b5ab8LIowAnQrEmaOJSdmqm96jQ linux-2.6.8.1-xen-sparse/arch/xen/i386/mm/pageattr.c
|
||||
40f5623906UYHv1rsVUeRc0tFT0dWw linux-2.6.8.1-xen-sparse/arch/xen/i386/mm/pgtable.c
|
||||
4107adf12ndy94MidCaivDibJ3pPAg linux-2.6.8.1-xen-sparse/arch/xen/i386/pci/Makefile
|
||||
4107adf1WcCgkhsdLTRGX52cOG1vJg linux-2.6.8.1-xen-sparse/arch/xen/i386/pci/direct.c
|
||||
|
||||
@@ -19,6 +19,7 @@ iap10@striker.cl.cam.ac.uk
|
||||
iap10@tetris.cl.cam.ac.uk
|
||||
jws22@gauntlet.cl.cam.ac.uk
|
||||
jws@cairnwell.research
|
||||
kaf24@camelot.eng.3leafnetworks.com
|
||||
kaf24@freefall.cl.cam.ac.uk
|
||||
kaf24@labyrinth.cl.cam.ac.uk
|
||||
kaf24@penguin.local
|
||||
|
||||
@@ -604,12 +604,15 @@ static struct irqaction dbg_time = {
|
||||
void __init time_init(void)
|
||||
{
|
||||
unsigned long long alarm;
|
||||
u64 __cpu_khz, cpu_freq, scale, scale2;
|
||||
u64 __cpu_khz, __cpu_ghz, cpu_freq, scale, scale2;
|
||||
unsigned int cpu_ghz;
|
||||
|
||||
__cpu_khz = HYPERVISOR_shared_info->cpu_freq;
|
||||
do_div(__cpu_khz, 1000);
|
||||
__cpu_khz = __cpu_ghz = cpu_freq = HYPERVISOR_shared_info->cpu_freq;
|
||||
do_div(__cpu_khz, 1000UL);
|
||||
cpu_khz = (u32)__cpu_khz;
|
||||
do_div(__cpu_ghz, 1000000000UL);
|
||||
cpu_ghz = (unsigned int)__cpu_ghz;
|
||||
|
||||
printk("Xen reported: %lu.%03lu MHz processor.\n",
|
||||
cpu_khz / 1000, cpu_khz % 1000);
|
||||
|
||||
@@ -617,9 +620,6 @@ void __init time_init(void)
|
||||
xtime.tv_usec = HYPERVISOR_shared_info->wc_usec;
|
||||
processed_system_time = shadow_system_time;
|
||||
|
||||
cpu_freq = HYPERVISOR_shared_info->cpu_freq;
|
||||
|
||||
cpu_ghz = do_div(cpu_freq, 1000000000UL);
|
||||
for ( rdtsc_bitshift = 0; cpu_ghz != 0; rdtsc_bitshift++, cpu_ghz >>= 1 )
|
||||
continue;
|
||||
|
||||
|
||||
@@ -0,0 +1,346 @@
|
||||
--- linux-2.6.8.1/drivers/char/agp/ali-agp.c 2004-08-14 11:55:35.000000000 +0100
|
||||
+++ linux-2.6.8.1-xen0/drivers/char/agp/ali-agp.c 2004-09-05 05:55:58.876495340 +0100
|
||||
@@ -150,7 +150,7 @@
|
||||
pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp);
|
||||
pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL,
|
||||
(((temp & ALI_CACHE_FLUSH_ADDR_MASK) |
|
||||
- virt_to_phys(addr)) | ALI_CACHE_FLUSH_EN ));
|
||||
+ virt_to_bus(addr)) | ALI_CACHE_FLUSH_EN ));
|
||||
return addr;
|
||||
}
|
||||
|
||||
@@ -174,7 +174,7 @@
|
||||
pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp);
|
||||
pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL,
|
||||
(((temp & ALI_CACHE_FLUSH_ADDR_MASK) |
|
||||
- virt_to_phys(addr)) | ALI_CACHE_FLUSH_EN));
|
||||
+ virt_to_bus(addr)) | ALI_CACHE_FLUSH_EN));
|
||||
agp_generic_destroy_page(addr);
|
||||
}
|
||||
|
||||
--- linux-2.6.8.1/drivers/char/agp/amd-k7-agp.c 2004-08-14 11:56:24.000000000 +0100
|
||||
+++ linux-2.6.8.1-xen0/drivers/char/agp/amd-k7-agp.c 2004-09-05 05:55:58.877495108 +0100
|
||||
@@ -43,7 +43,7 @@
|
||||
|
||||
SetPageReserved(virt_to_page(page_map->real));
|
||||
global_cache_flush();
|
||||
- page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real),
|
||||
+ page_map->remapped = ioremap_nocache(virt_to_bus(page_map->real),
|
||||
PAGE_SIZE);
|
||||
if (page_map->remapped == NULL) {
|
||||
ClearPageReserved(virt_to_page(page_map->real));
|
||||
@@ -152,7 +152,7 @@
|
||||
|
||||
agp_bridge->gatt_table_real = (u32 *)page_dir.real;
|
||||
agp_bridge->gatt_table = (u32 *)page_dir.remapped;
|
||||
- agp_bridge->gatt_bus_addr = virt_to_phys(page_dir.real);
|
||||
+ agp_bridge->gatt_bus_addr = virt_to_bus(page_dir.real);
|
||||
|
||||
/* Get the address for the gart region.
|
||||
* This is a bus address even on the alpha, b/c its
|
||||
@@ -166,7 +166,7 @@
|
||||
/* Calculate the agp offset */
|
||||
for (i = 0; i < value->num_entries / 1024; i++, addr += 0x00400000) {
|
||||
page_dir.remapped[GET_PAGE_DIR_OFF(addr)] =
|
||||
- virt_to_phys(amd_irongate_private.gatt_pages[i]->real);
|
||||
+ virt_to_bus(amd_irongate_private.gatt_pages[i]->real);
|
||||
page_dir.remapped[GET_PAGE_DIR_OFF(addr)] |= 0x00000001;
|
||||
}
|
||||
|
||||
--- linux-2.6.8.1/drivers/char/agp/amd64-agp.c 2004-08-14 11:55:47.000000000 +0100
|
||||
+++ linux-2.6.8.1-xen0/drivers/char/agp/amd64-agp.c 2004-09-05 05:55:58.877495108 +0100
|
||||
@@ -212,7 +212,7 @@
|
||||
|
||||
static int amd_8151_configure(void)
|
||||
{
|
||||
- unsigned long gatt_bus = virt_to_phys(agp_bridge->gatt_table_real);
|
||||
+ unsigned long gatt_bus = virt_to_bus(agp_bridge->gatt_table_real);
|
||||
|
||||
/* Configure AGP regs in each x86-64 host bridge. */
|
||||
for_each_nb() {
|
||||
@@ -521,7 +521,7 @@
|
||||
{
|
||||
struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
|
||||
|
||||
- release_mem_region(virt_to_phys(bridge->gatt_table_real),
|
||||
+ release_mem_region(virt_to_bus(bridge->gatt_table_real),
|
||||
amd64_aperture_sizes[bridge->aperture_size_idx].size);
|
||||
agp_remove_bridge(bridge);
|
||||
agp_put_bridge(bridge);
|
||||
--- linux-2.6.8.1/drivers/char/agp/ati-agp.c 2004-08-14 11:55:48.000000000 +0100
|
||||
+++ linux-2.6.8.1-xen0/drivers/char/agp/ati-agp.c 2004-09-05 05:55:58.877495108 +0100
|
||||
@@ -64,7 +64,7 @@
|
||||
|
||||
/* CACHE_FLUSH(); */
|
||||
global_cache_flush();
|
||||
- page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real),
|
||||
+ page_map->remapped = ioremap_nocache(virt_to_bus(page_map->real),
|
||||
PAGE_SIZE);
|
||||
if (page_map->remapped == NULL || err) {
|
||||
ClearPageReserved(virt_to_page(page_map->real));
|
||||
--- linux-2.6.8.1/drivers/char/agp/backend.c 2004-08-14 11:55:47.000000000 +0100
|
||||
+++ linux-2.6.8.1-xen0/drivers/char/agp/backend.c 2004-09-05 05:55:58.878494876 +0100
|
||||
@@ -142,7 +142,7 @@
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
- bridge->scratch_page_real = virt_to_phys(addr);
|
||||
+ bridge->scratch_page_real = virt_to_bus(addr);
|
||||
bridge->scratch_page =
|
||||
bridge->driver->mask_memory(bridge->scratch_page_real, 0);
|
||||
}
|
||||
@@ -186,7 +186,7 @@
|
||||
err_out:
|
||||
if (bridge->driver->needs_scratch_page)
|
||||
bridge->driver->agp_destroy_page(
|
||||
- phys_to_virt(bridge->scratch_page_real));
|
||||
+ bus_to_virt(bridge->scratch_page_real));
|
||||
if (got_gatt)
|
||||
bridge->driver->free_gatt_table();
|
||||
if (got_keylist) {
|
||||
@@ -211,7 +211,7 @@
|
||||
if (bridge->driver->agp_destroy_page &&
|
||||
bridge->driver->needs_scratch_page)
|
||||
bridge->driver->agp_destroy_page(
|
||||
- phys_to_virt(bridge->scratch_page_real));
|
||||
+ bus_to_virt(bridge->scratch_page_real));
|
||||
}
|
||||
|
||||
static const drm_agp_t drm_agp = {
|
||||
--- linux-2.6.8.1/drivers/char/agp/generic.c 2004-08-14 11:55:10.000000000 +0100
|
||||
+++ linux-2.6.8.1-xen0/drivers/char/agp/generic.c 2004-09-05 05:55:58.879494644 +0100
|
||||
@@ -127,7 +127,7 @@
|
||||
}
|
||||
if (curr->page_count != 0) {
|
||||
for (i = 0; i < curr->page_count; i++) {
|
||||
- agp_bridge->driver->agp_destroy_page(phys_to_virt(curr->memory[i]));
|
||||
+ agp_bridge->driver->agp_destroy_page(bus_to_virt(curr->memory[i]));
|
||||
}
|
||||
}
|
||||
agp_free_key(curr->key);
|
||||
@@ -181,7 +181,7 @@
|
||||
return NULL;
|
||||
}
|
||||
new->memory[i] =
|
||||
- agp_bridge->driver->mask_memory(virt_to_phys(addr), type);
|
||||
+ agp_bridge->driver->mask_memory(virt_to_bus(addr), type);
|
||||
new->page_count++;
|
||||
}
|
||||
|
||||
@@ -636,6 +636,7 @@
|
||||
int i;
|
||||
void *temp;
|
||||
struct page *page;
|
||||
+ dma_addr_t dma;
|
||||
|
||||
/* The generic routines can't handle 2 level gatt's */
|
||||
if (agp_bridge->driver->size_type == LVL2_APER_SIZE)
|
||||
@@ -674,8 +675,10 @@
|
||||
break;
|
||||
}
|
||||
|
||||
- table = (char *) __get_free_pages(GFP_KERNEL,
|
||||
- page_order);
|
||||
+ table = dma_alloc_coherent(
|
||||
+ &agp_bridge->dev->dev,
|
||||
+ PAGE_SIZE << page_order, &dma,
|
||||
+ GFP_KERNEL);
|
||||
|
||||
if (table == NULL) {
|
||||
i++;
|
||||
@@ -706,7 +709,9 @@
|
||||
size = ((struct aper_size_info_fixed *) temp)->size;
|
||||
page_order = ((struct aper_size_info_fixed *) temp)->page_order;
|
||||
num_entries = ((struct aper_size_info_fixed *) temp)->num_entries;
|
||||
- table = (char *) __get_free_pages(GFP_KERNEL, page_order);
|
||||
+ table = dma_alloc_coherent(
|
||||
+ &agp_bridge->dev->dev,
|
||||
+ PAGE_SIZE << page_order, &dma, GFP_KERNEL);
|
||||
}
|
||||
|
||||
if (table == NULL)
|
||||
@@ -721,7 +726,7 @@
|
||||
agp_gatt_table = (void *)table;
|
||||
|
||||
agp_bridge->driver->cache_flush();
|
||||
- agp_bridge->gatt_table = ioremap_nocache(virt_to_phys(table),
|
||||
+ agp_bridge->gatt_table = ioremap_nocache(virt_to_bus(table),
|
||||
(PAGE_SIZE * (1 << page_order)));
|
||||
agp_bridge->driver->cache_flush();
|
||||
|
||||
@@ -729,11 +734,12 @@
|
||||
for (page = virt_to_page(table); page <= virt_to_page(table_end); page++)
|
||||
ClearPageReserved(page);
|
||||
|
||||
- free_pages((unsigned long) table, page_order);
|
||||
+ dma_free_coherent(&agp_bridge->dev->dev, PAGE_SIZE<<page_order,
|
||||
+ table, dma);
|
||||
|
||||
return -ENOMEM;
|
||||
}
|
||||
- agp_bridge->gatt_bus_addr = virt_to_phys(agp_bridge->gatt_table_real);
|
||||
+ agp_bridge->gatt_bus_addr = virt_to_bus(table);
|
||||
|
||||
/* AK: bogus, should encode addresses > 4GB */
|
||||
for (i = 0; i < num_entries; i++)
|
||||
@@ -785,7 +791,8 @@
|
||||
for (page = virt_to_page(table); page <= virt_to_page(table_end); page++)
|
||||
ClearPageReserved(page);
|
||||
|
||||
- free_pages((unsigned long) agp_bridge->gatt_table_real, page_order);
|
||||
+ dma_free_coherent(&agp_bridge->dev->dev, PAGE_SIZE<<page_order,
|
||||
+ agp_bridge->gatt_table_real, agp_bridge->gatt_bus_addr);
|
||||
|
||||
agp_gatt_table = NULL;
|
||||
agp_bridge->gatt_table = NULL;
|
||||
--- linux-2.6.8.1/drivers/char/agp/hp-agp.c 2004-08-14 11:55:59.000000000 +0100
|
||||
+++ linux-2.6.8.1-xen0/drivers/char/agp/hp-agp.c 2004-09-05 05:55:58.879494644 +0100
|
||||
@@ -110,7 +110,7 @@
|
||||
hp->gart_size = HP_ZX1_GART_SIZE;
|
||||
hp->gatt_entries = hp->gart_size / hp->io_page_size;
|
||||
|
||||
- hp->io_pdir = phys_to_virt(INREG64(hp->ioc_regs, HP_ZX1_PDIR_BASE));
|
||||
+ hp->io_pdir = bus_to_virt(INREG64(hp->ioc_regs, HP_ZX1_PDIR_BASE));
|
||||
hp->gatt = &hp->io_pdir[HP_ZX1_IOVA_TO_PDIR(hp->gart_base)];
|
||||
|
||||
if (hp->gatt[0] != HP_ZX1_SBA_IOMMU_COOKIE) {
|
||||
@@ -248,7 +248,7 @@
|
||||
agp_bridge->mode = INREG32(hp->lba_regs, hp->lba_cap_offset + PCI_AGP_STATUS);
|
||||
|
||||
if (hp->io_pdir_owner) {
|
||||
- OUTREG64(hp->ioc_regs, HP_ZX1_PDIR_BASE, virt_to_phys(hp->io_pdir));
|
||||
+ OUTREG64(hp->ioc_regs, HP_ZX1_PDIR_BASE, virt_to_bus(hp->io_pdir));
|
||||
OUTREG64(hp->ioc_regs, HP_ZX1_TCNFG, hp->io_tlb_ps);
|
||||
OUTREG64(hp->ioc_regs, HP_ZX1_IMASK, ~(HP_ZX1_IOVA_SIZE - 1));
|
||||
OUTREG64(hp->ioc_regs, HP_ZX1_IBASE, hp->iova_base | 0x1);
|
||||
--- linux-2.6.8.1/drivers/char/agp/i460-agp.c 2004-08-14 11:55:34.000000000 +0100
|
||||
+++ linux-2.6.8.1-xen0/drivers/char/agp/i460-agp.c 2004-09-05 05:55:58.879494644 +0100
|
||||
@@ -371,7 +371,7 @@
|
||||
}
|
||||
memset(lp->alloced_map, 0, map_size);
|
||||
|
||||
- lp->paddr = virt_to_phys(lpage);
|
||||
+ lp->paddr = virt_to_bus(lpage);
|
||||
lp->refcount = 0;
|
||||
atomic_add(I460_KPAGES_PER_IOPAGE, &agp_bridge->current_memory_agp);
|
||||
return 0;
|
||||
@@ -382,7 +382,7 @@
|
||||
kfree(lp->alloced_map);
|
||||
lp->alloced_map = NULL;
|
||||
|
||||
- free_pages((unsigned long) phys_to_virt(lp->paddr), I460_IO_PAGE_SHIFT - PAGE_SHIFT);
|
||||
+ free_pages((unsigned long) bus_to_virt(lp->paddr), I460_IO_PAGE_SHIFT - PAGE_SHIFT);
|
||||
atomic_sub(I460_KPAGES_PER_IOPAGE, &agp_bridge->current_memory_agp);
|
||||
}
|
||||
|
||||
--- linux-2.6.8.1/drivers/char/agp/intel-agp.c 2004-08-14 11:55:32.000000000 +0100
|
||||
+++ linux-2.6.8.1-xen0/drivers/char/agp/intel-agp.c 2004-09-05 05:55:58.880494412 +0100
|
||||
@@ -285,7 +285,7 @@
|
||||
if (new == NULL)
|
||||
return NULL;
|
||||
|
||||
- new->memory[0] = virt_to_phys(addr);
|
||||
+ new->memory[0] = virt_to_bus(addr);
|
||||
if (pg_count == 4) {
|
||||
/* kludge to get 4 physical pages for ARGB cursor */
|
||||
new->memory[1] = new->memory[0] + PAGE_SIZE;
|
||||
@@ -328,10 +328,10 @@
|
||||
agp_free_key(curr->key);
|
||||
if(curr->type == AGP_PHYS_MEMORY) {
|
||||
if (curr->page_count == 4)
|
||||
- i8xx_destroy_pages(phys_to_virt(curr->memory[0]));
|
||||
+ i8xx_destroy_pages(bus_to_virt(curr->memory[0]));
|
||||
else
|
||||
agp_bridge->driver->agp_destroy_page(
|
||||
- phys_to_virt(curr->memory[0]));
|
||||
+ bus_to_virt(curr->memory[0]));
|
||||
vfree(curr->memory);
|
||||
}
|
||||
kfree(curr);
|
||||
--- linux-2.6.8.1/drivers/char/agp/intel-mch-agp.c 2004-08-14 11:54:49.000000000 +0100
|
||||
+++ linux-2.6.8.1-xen0/drivers/char/agp/intel-mch-agp.c 2004-09-05 05:55:58.880494412 +0100
|
||||
@@ -51,7 +51,7 @@
|
||||
if (new == NULL)
|
||||
return NULL;
|
||||
|
||||
- new->memory[0] = agp_bridge->driver->mask_memory(virt_to_phys(addr), type);
|
||||
+ new->memory[0] = agp_bridge->driver->mask_memory(virt_to_bus(addr), type);
|
||||
new->page_count = 1;
|
||||
new->num_scratch_pages = 1;
|
||||
new->type = AGP_PHYS_MEMORY;
|
||||
@@ -63,7 +63,7 @@
|
||||
{
|
||||
agp_free_key(curr->key);
|
||||
if(curr->type == AGP_PHYS_MEMORY) {
|
||||
- agp_bridge->driver->agp_destroy_page(phys_to_virt(curr->memory[0]));
|
||||
+ agp_bridge->driver->agp_destroy_page(bus_to_virt(curr->memory[0]));
|
||||
vfree(curr->memory);
|
||||
}
|
||||
kfree(curr);
|
||||
--- linux-2.6.8.1/drivers/char/agp/sworks-agp.c 2004-08-14 11:55:10.000000000 +0100
|
||||
+++ linux-2.6.8.1-xen0/drivers/char/agp/sworks-agp.c 2004-09-05 05:55:58.881494180 +0100
|
||||
@@ -51,7 +51,7 @@
|
||||
}
|
||||
SetPageReserved(virt_to_page(page_map->real));
|
||||
global_cache_flush();
|
||||
- page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real),
|
||||
+ page_map->remapped = ioremap_nocache(virt_to_bus(page_map->real),
|
||||
PAGE_SIZE);
|
||||
if (page_map->remapped == NULL) {
|
||||
ClearPageReserved(virt_to_page(page_map->real));
|
||||
@@ -164,7 +164,7 @@
|
||||
for(i = 0; i < 1024; i++) {
|
||||
serverworks_private.scratch_dir.remapped[i] = (unsigned long) agp_bridge->scratch_page;
|
||||
page_dir.remapped[i] =
|
||||
- virt_to_phys(serverworks_private.scratch_dir.real);
|
||||
+ virt_to_bus(serverworks_private.scratch_dir.real);
|
||||
page_dir.remapped[i] |= 0x00000001;
|
||||
}
|
||||
|
||||
@@ -177,7 +177,7 @@
|
||||
|
||||
agp_bridge->gatt_table_real = (u32 *)page_dir.real;
|
||||
agp_bridge->gatt_table = (u32 *)page_dir.remapped;
|
||||
- agp_bridge->gatt_bus_addr = virt_to_phys(page_dir.real);
|
||||
+ agp_bridge->gatt_bus_addr = virt_to_bus(page_dir.real);
|
||||
|
||||
/* Get the address for the gart region.
|
||||
* This is a bus address even on the alpha, b/c its
|
||||
@@ -191,7 +191,7 @@
|
||||
|
||||
for(i = 0; i < value->num_entries / 1024; i++) {
|
||||
page_dir.remapped[i] =
|
||||
- virt_to_phys(serverworks_private.gatt_pages[i]->real);
|
||||
+ virt_to_bus(serverworks_private.gatt_pages[i]->real);
|
||||
page_dir.remapped[i] |= 0x00000001;
|
||||
}
|
||||
|
||||
--- linux-2.6.8.1/drivers/char/agp/uninorth-agp.c 2004-08-14 11:55:32.000000000 +0100
|
||||
+++ linux-2.6.8.1-xen0/drivers/char/agp/uninorth-agp.c 2004-09-05 05:55:58.881494180 +0100
|
||||
@@ -200,7 +200,7 @@
|
||||
|
||||
agp_bridge->gatt_table_real = (u32 *) table;
|
||||
agp_bridge->gatt_table = (u32 *)table;
|
||||
- agp_bridge->gatt_bus_addr = virt_to_phys(table);
|
||||
+ agp_bridge->gatt_bus_addr = virt_to_bus(table);
|
||||
|
||||
for (i = 0; i < num_entries; i++) {
|
||||
agp_bridge->gatt_table[i] =
|
||||
--- linux-2.6.8.1/include/asm-i386/agp.h 2004-08-14 11:54:47.000000000 +0100
|
||||
+++ linux-2.6.8.1-xen0/include/asm-i386/agp.h 2004-09-05 05:57:26.040268956 +0100
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/cacheflush.h>
|
||||
+#include <asm/system.h>
|
||||
|
||||
/*
|
||||
* Functions to keep the agpgart mappings coherent with the MMU.
|
||||
@@ -19,6 +20,6 @@
|
||||
/* Could use CLFLUSH here if the cpu supports it. But then it would
|
||||
need to be called for each cacheline of the whole page so it may not be
|
||||
worth it. Would need a page for it. */
|
||||
-#define flush_agp_cache() asm volatile("wbinvd":::"memory")
|
||||
+#define flush_agp_cache() wbinvd()
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
--- linux-2.6.8.1/drivers/char/drm/ati_pcigart.h 2004-08-14 11:56:14.000000000 +0100
|
||||
+++ linux-2.6.8.1-xen0/drivers/char/drm/ati_pcigart.h 2004-09-05 06:14:51.751782846 +0100
|
||||
@@ -158,7 +158,7 @@
|
||||
ret = 1;
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
- asm volatile ( "wbinvd" ::: "memory" );
|
||||
+ wbinvd();
|
||||
#else
|
||||
mb();
|
||||
#endif
|
||||
@@ -26,13 +26,12 @@ menu "XEN"
|
||||
config XEN_PRIVILEGED_GUEST
|
||||
bool "Privileged Guest (domain 0)"
|
||||
default n
|
||||
select XEN_PHYSDEV_ACCESS
|
||||
help
|
||||
Support for privileged operation (domain 0)
|
||||
|
||||
config XEN_PHYSDEV_ACCESS
|
||||
bool "Device-driver domain (physical device access)"
|
||||
default y if XEN_PRIVILEGED_GUEST
|
||||
default n
|
||||
help
|
||||
Device-driver domain (physical device access)
|
||||
|
||||
|
||||
@@ -4,84 +4,52 @@ menu "Device Drivers"
|
||||
|
||||
source "drivers/base/Kconfig"
|
||||
|
||||
source "drivers/scsi/Kconfig"
|
||||
source "drivers/block/Kconfig"
|
||||
source "drivers/md/Kconfig"
|
||||
if XEN_PHYSDEV_ACCESS
|
||||
source "drivers/mtd/Kconfig"
|
||||
source "drivers/parport/Kconfig"
|
||||
source "drivers/pnp/Kconfig"
|
||||
endif
|
||||
|
||||
# Always include scsi and block to enable iscsi, loop0 etc.
|
||||
source "drivers/block/Kconfig"
|
||||
|
||||
if XEN_PHYSDEV_ACCESS
|
||||
source "drivers/ide/Kconfig"
|
||||
endif
|
||||
|
||||
source "drivers/scsi/Kconfig"
|
||||
|
||||
if XEN_PHYSDEV_ACCESS
|
||||
source "drivers/cdrom/Kconfig"
|
||||
endif
|
||||
|
||||
source "drivers/md/Kconfig"
|
||||
|
||||
if XEN_PHYSDEV_ACCESS
|
||||
source "drivers/message/fusion/Kconfig"
|
||||
source "drivers/ieee1394/Kconfig"
|
||||
source "drivers/message/i2o/Kconfig"
|
||||
endif
|
||||
|
||||
source "net/Kconfig"
|
||||
|
||||
if XEN_PRIVILEGED_GUEST
|
||||
source "drivers/input/Kconfig"
|
||||
endif
|
||||
|
||||
config INPUT
|
||||
tristate "Input devices (needed for keyboard, mouse, ...)" if EMBEDDED
|
||||
default y
|
||||
---help---
|
||||
Say Y here if you have any input device (mouse, keyboard, tablet,
|
||||
joystick, steering wheel ...) connected to your system and want
|
||||
it to be available to applications. This includes standard PS/2
|
||||
keyboard and mouse.
|
||||
|
||||
Say N here if you have a headless (no monitor, no keyboard) system.
|
||||
|
||||
More information is available: <file:Documentation/input/input.txt>
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called input.
|
||||
|
||||
if XEN_PRIVILEGED_GUEST
|
||||
source "drivers/char/Kconfig"
|
||||
endif
|
||||
|
||||
config UNIX98_PTYS
|
||||
bool "Unix98 PTY support" if EMBEDDED
|
||||
default y
|
||||
---help---
|
||||
A pseudo terminal (PTY) is a software device consisting of two
|
||||
halves: a master and a slave. The slave device behaves identical to
|
||||
a physical terminal; the master device is used by a process to
|
||||
read data from and write data to the slave, thereby emulating a
|
||||
terminal. Typical programs for the master side are telnet servers
|
||||
and xterms.
|
||||
|
||||
Linux has traditionally used the BSD-like names /dev/ptyxx for
|
||||
masters and /dev/ttyxx for slaves of pseudo terminals. This scheme
|
||||
has a number of problems. The GNU C library glibc 2.1 and later,
|
||||
however, supports the Unix98 naming standard: in order to acquire a
|
||||
pseudo terminal, a process opens /dev/ptmx; the number of the pseudo
|
||||
terminal is then made available to the process and the pseudo
|
||||
terminal slave can be accessed as /dev/pts/<number>. What was
|
||||
traditionally /dev/ttyp2 will then be /dev/pts/2, for example.
|
||||
|
||||
All modern Linux systems use the Unix98 ptys. Say Y unless
|
||||
you're on an embedded system and want to conserve memory.
|
||||
|
||||
|
||||
if XEN_PHYSDEV_ACCESS
|
||||
source "drivers/isdn/Kconfig"
|
||||
source "drivers/telephony/Kconfig"
|
||||
source "drivers/input/Kconfig"
|
||||
source "drivers/char/Kconfig"
|
||||
source "drivers/i2c/Kconfig"
|
||||
source "drivers/w1/Kconfig"
|
||||
source "drivers/misc/Kconfig"
|
||||
source "drivers/media/Kconfig"
|
||||
source "drivers/video/Kconfig"
|
||||
source "sound/Kconfig"
|
||||
source "drivers/usb/Kconfig"
|
||||
endif
|
||||
|
||||
#config XEN_EVTCHN
|
||||
# bool "Xen Event Channel"
|
||||
# depends on XEN
|
||||
# default Y
|
||||
#
|
||||
#config XEN_CONSOLE
|
||||
# bool "Xen Console"
|
||||
# depends on XEN && XEN_EVTCHN
|
||||
# default Y
|
||||
# help
|
||||
# Say Y to build a console driver for Xen.
|
||||
if !XEN_PHYSDEV_ACCESS
|
||||
config UNIX98_PTYS
|
||||
bool
|
||||
default y
|
||||
endif
|
||||
|
||||
endmenu
|
||||
@@ -175,6 +175,105 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
|
||||
# CONFIG_FW_LOADER is not set
|
||||
# CONFIG_DEBUG_DRIVER is not set
|
||||
|
||||
#
|
||||
# Memory Technology Devices (MTD)
|
||||
#
|
||||
# CONFIG_MTD is not set
|
||||
|
||||
#
|
||||
# Parallel port support
|
||||
#
|
||||
# CONFIG_PARPORT is not set
|
||||
|
||||
#
|
||||
# Plug and Play support
|
||||
#
|
||||
# CONFIG_PNP is not set
|
||||
|
||||
#
|
||||
# Block devices
|
||||
#
|
||||
# CONFIG_BLK_DEV_FD is not set
|
||||
# CONFIG_BLK_DEV_XD is not set
|
||||
# CONFIG_BLK_CPQ_DA is not set
|
||||
# CONFIG_BLK_CPQ_CISS_DA is not set
|
||||
# CONFIG_BLK_DEV_DAC960 is not set
|
||||
# CONFIG_BLK_DEV_UMEM is not set
|
||||
CONFIG_BLK_DEV_LOOP=y
|
||||
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
|
||||
CONFIG_BLK_DEV_NBD=y
|
||||
# CONFIG_BLK_DEV_SX8 is not set
|
||||
CONFIG_BLK_DEV_RAM=y
|
||||
CONFIG_BLK_DEV_RAM_SIZE=4096
|
||||
CONFIG_BLK_DEV_INITRD=y
|
||||
# CONFIG_LBD is not set
|
||||
|
||||
#
|
||||
# ATA/ATAPI/MFM/RLL support
|
||||
#
|
||||
CONFIG_IDE=y
|
||||
CONFIG_BLK_DEV_IDE=y
|
||||
|
||||
#
|
||||
# Please see Documentation/ide.txt for help/info on IDE drives
|
||||
#
|
||||
# CONFIG_BLK_DEV_IDE_SATA is not set
|
||||
# CONFIG_BLK_DEV_HD_IDE is not set
|
||||
CONFIG_BLK_DEV_IDEDISK=y
|
||||
# CONFIG_IDEDISK_MULTI_MODE is not set
|
||||
# CONFIG_BLK_DEV_IDECS is not set
|
||||
CONFIG_BLK_DEV_IDECD=y
|
||||
# CONFIG_BLK_DEV_IDETAPE is not set
|
||||
# CONFIG_BLK_DEV_IDEFLOPPY is not set
|
||||
# CONFIG_BLK_DEV_IDESCSI is not set
|
||||
# CONFIG_IDE_TASK_IOCTL is not set
|
||||
# CONFIG_IDE_TASKFILE_IO is not set
|
||||
|
||||
#
|
||||
# IDE chipset support/bugfixes
|
||||
#
|
||||
CONFIG_IDE_GENERIC=y
|
||||
# CONFIG_BLK_DEV_CMD640 is not set
|
||||
CONFIG_BLK_DEV_IDEPCI=y
|
||||
# CONFIG_IDEPCI_SHARE_IRQ is not set
|
||||
# CONFIG_BLK_DEV_OFFBOARD is not set
|
||||
CONFIG_BLK_DEV_GENERIC=y
|
||||
# CONFIG_BLK_DEV_OPTI621 is not set
|
||||
# CONFIG_BLK_DEV_RZ1000 is not set
|
||||
CONFIG_BLK_DEV_IDEDMA_PCI=y
|
||||
# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
|
||||
CONFIG_IDEDMA_PCI_AUTO=y
|
||||
# CONFIG_IDEDMA_ONLYDISK is not set
|
||||
CONFIG_BLK_DEV_ADMA=y
|
||||
# CONFIG_BLK_DEV_AEC62XX is not set
|
||||
# CONFIG_BLK_DEV_ALI15X3 is not set
|
||||
# CONFIG_BLK_DEV_AMD74XX is not set
|
||||
# CONFIG_BLK_DEV_ATIIXP is not set
|
||||
# CONFIG_BLK_DEV_CMD64X is not set
|
||||
# CONFIG_BLK_DEV_TRIFLEX is not set
|
||||
# CONFIG_BLK_DEV_CY82C693 is not set
|
||||
# CONFIG_BLK_DEV_CS5520 is not set
|
||||
# CONFIG_BLK_DEV_CS5530 is not set
|
||||
# CONFIG_BLK_DEV_HPT34X is not set
|
||||
# CONFIG_BLK_DEV_HPT366 is not set
|
||||
# CONFIG_BLK_DEV_SC1200 is not set
|
||||
CONFIG_BLK_DEV_PIIX=y
|
||||
# CONFIG_BLK_DEV_NS87415 is not set
|
||||
# CONFIG_BLK_DEV_PDC202XX_OLD is not set
|
||||
# CONFIG_BLK_DEV_PDC202XX_NEW is not set
|
||||
CONFIG_BLK_DEV_SVWKS=y
|
||||
# CONFIG_BLK_DEV_SIIMAGE is not set
|
||||
# CONFIG_BLK_DEV_SIS5513 is not set
|
||||
# CONFIG_BLK_DEV_SLC90E66 is not set
|
||||
# CONFIG_BLK_DEV_TRM290 is not set
|
||||
# CONFIG_BLK_DEV_VIA82CXXX is not set
|
||||
# CONFIG_IDE_ARM is not set
|
||||
# CONFIG_IDE_CHIPSETS is not set
|
||||
CONFIG_BLK_DEV_IDEDMA=y
|
||||
# CONFIG_IDEDMA_IVB is not set
|
||||
CONFIG_IDEDMA_AUTO=y
|
||||
# CONFIG_BLK_DEV_HD is not set
|
||||
|
||||
#
|
||||
# SCSI device support
|
||||
#
|
||||
@@ -295,22 +394,9 @@ CONFIG_SCSI_QLA2XXX=y
|
||||
# CONFIG_PCMCIA_SYM53C500 is not set
|
||||
|
||||
#
|
||||
# Block devices
|
||||
# Old CD-ROM drivers (not SCSI, not IDE)
|
||||
#
|
||||
# CONFIG_BLK_DEV_FD is not set
|
||||
# CONFIG_BLK_DEV_XD is not set
|
||||
# CONFIG_BLK_CPQ_DA is not set
|
||||
# CONFIG_BLK_CPQ_CISS_DA is not set
|
||||
# CONFIG_BLK_DEV_DAC960 is not set
|
||||
# CONFIG_BLK_DEV_UMEM is not set
|
||||
CONFIG_BLK_DEV_LOOP=y
|
||||
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
|
||||
CONFIG_BLK_DEV_NBD=y
|
||||
# CONFIG_BLK_DEV_SX8 is not set
|
||||
CONFIG_BLK_DEV_RAM=y
|
||||
CONFIG_BLK_DEV_RAM_SIZE=4096
|
||||
CONFIG_BLK_DEV_INITRD=y
|
||||
# CONFIG_LBD is not set
|
||||
# CONFIG_CD_NO_IDESCSI is not set
|
||||
|
||||
#
|
||||
# Multi-device support (RAID and LVM)
|
||||
@@ -330,75 +416,19 @@ CONFIG_DM_MIRROR=y
|
||||
# CONFIG_DM_ZERO is not set
|
||||
|
||||
#
|
||||
# ATA/ATAPI/MFM/RLL support
|
||||
# Fusion MPT device support
|
||||
#
|
||||
CONFIG_IDE=y
|
||||
CONFIG_BLK_DEV_IDE=y
|
||||
# CONFIG_FUSION is not set
|
||||
|
||||
#
|
||||
# Please see Documentation/ide.txt for help/info on IDE drives
|
||||
# IEEE 1394 (FireWire) support
|
||||
#
|
||||
# CONFIG_BLK_DEV_IDE_SATA is not set
|
||||
# CONFIG_BLK_DEV_HD_IDE is not set
|
||||
CONFIG_BLK_DEV_IDEDISK=y
|
||||
# CONFIG_IDEDISK_MULTI_MODE is not set
|
||||
# CONFIG_BLK_DEV_IDECS is not set
|
||||
CONFIG_BLK_DEV_IDECD=y
|
||||
# CONFIG_BLK_DEV_IDETAPE is not set
|
||||
# CONFIG_BLK_DEV_IDEFLOPPY is not set
|
||||
# CONFIG_BLK_DEV_IDESCSI is not set
|
||||
# CONFIG_IDE_TASK_IOCTL is not set
|
||||
# CONFIG_IDE_TASKFILE_IO is not set
|
||||
# CONFIG_IEEE1394 is not set
|
||||
|
||||
#
|
||||
# IDE chipset support/bugfixes
|
||||
# I2O device support
|
||||
#
|
||||
CONFIG_IDE_GENERIC=y
|
||||
# CONFIG_BLK_DEV_CMD640 is not set
|
||||
CONFIG_BLK_DEV_IDEPCI=y
|
||||
# CONFIG_IDEPCI_SHARE_IRQ is not set
|
||||
# CONFIG_BLK_DEV_OFFBOARD is not set
|
||||
CONFIG_BLK_DEV_GENERIC=y
|
||||
# CONFIG_BLK_DEV_OPTI621 is not set
|
||||
# CONFIG_BLK_DEV_RZ1000 is not set
|
||||
CONFIG_BLK_DEV_IDEDMA_PCI=y
|
||||
# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
|
||||
CONFIG_IDEDMA_PCI_AUTO=y
|
||||
# CONFIG_IDEDMA_ONLYDISK is not set
|
||||
CONFIG_BLK_DEV_ADMA=y
|
||||
# CONFIG_BLK_DEV_AEC62XX is not set
|
||||
# CONFIG_BLK_DEV_ALI15X3 is not set
|
||||
# CONFIG_BLK_DEV_AMD74XX is not set
|
||||
# CONFIG_BLK_DEV_ATIIXP is not set
|
||||
# CONFIG_BLK_DEV_CMD64X is not set
|
||||
# CONFIG_BLK_DEV_TRIFLEX is not set
|
||||
# CONFIG_BLK_DEV_CY82C693 is not set
|
||||
# CONFIG_BLK_DEV_CS5520 is not set
|
||||
# CONFIG_BLK_DEV_CS5530 is not set
|
||||
# CONFIG_BLK_DEV_HPT34X is not set
|
||||
# CONFIG_BLK_DEV_HPT366 is not set
|
||||
# CONFIG_BLK_DEV_SC1200 is not set
|
||||
CONFIG_BLK_DEV_PIIX=y
|
||||
# CONFIG_BLK_DEV_NS87415 is not set
|
||||
# CONFIG_BLK_DEV_PDC202XX_OLD is not set
|
||||
# CONFIG_BLK_DEV_PDC202XX_NEW is not set
|
||||
CONFIG_BLK_DEV_SVWKS=y
|
||||
# CONFIG_BLK_DEV_SIIMAGE is not set
|
||||
# CONFIG_BLK_DEV_SIS5513 is not set
|
||||
# CONFIG_BLK_DEV_SLC90E66 is not set
|
||||
# CONFIG_BLK_DEV_TRM290 is not set
|
||||
# CONFIG_BLK_DEV_VIA82CXXX is not set
|
||||
# CONFIG_IDE_ARM is not set
|
||||
# CONFIG_IDE_CHIPSETS is not set
|
||||
CONFIG_BLK_DEV_IDEDMA=y
|
||||
# CONFIG_IDEDMA_IVB is not set
|
||||
CONFIG_IDEDMA_AUTO=y
|
||||
# CONFIG_BLK_DEV_HD is not set
|
||||
|
||||
#
|
||||
# Old CD-ROM drivers (not SCSI, not IDE)
|
||||
#
|
||||
# CONFIG_CD_NO_IDESCSI is not set
|
||||
# CONFIG_I2O is not set
|
||||
|
||||
#
|
||||
# Networking support
|
||||
@@ -645,6 +675,16 @@ CONFIG_TIGON3=y
|
||||
# CONFIG_SHAPER is not set
|
||||
# CONFIG_NETCONSOLE is not set
|
||||
|
||||
#
|
||||
# ISDN subsystem
|
||||
#
|
||||
# CONFIG_ISDN is not set
|
||||
|
||||
#
|
||||
# Telephony Support
|
||||
#
|
||||
# CONFIG_PHONE is not set
|
||||
|
||||
#
|
||||
# Input device support
|
||||
#
|
||||
@@ -752,6 +792,26 @@ CONFIG_LEGACY_PTY_COUNT=256
|
||||
#
|
||||
# CONFIG_I2C is not set
|
||||
|
||||
#
|
||||
# Dallas's 1-wire bus
|
||||
#
|
||||
# CONFIG_W1 is not set
|
||||
|
||||
#
|
||||
# Misc devices
|
||||
#
|
||||
# CONFIG_IBM_ASM is not set
|
||||
|
||||
#
|
||||
# Multimedia devices
|
||||
#
|
||||
# CONFIG_VIDEO_DEV is not set
|
||||
|
||||
#
|
||||
# Digital Video Broadcasting Devices
|
||||
#
|
||||
# CONFIG_DVB is not set
|
||||
|
||||
#
|
||||
# Graphics support
|
||||
#
|
||||
@@ -765,6 +825,21 @@ CONFIG_VGA_CONSOLE=y
|
||||
# CONFIG_MDA_CONSOLE is not set
|
||||
CONFIG_DUMMY_CONSOLE=y
|
||||
|
||||
#
|
||||
# Sound
|
||||
#
|
||||
# CONFIG_SOUND is not set
|
||||
|
||||
#
|
||||
# USB support
|
||||
#
|
||||
# CONFIG_USB is not set
|
||||
|
||||
#
|
||||
# USB Gadget Support
|
||||
#
|
||||
# CONFIG_USB_GADGET is not set
|
||||
|
||||
#
|
||||
# File systems
|
||||
#
|
||||
|
||||
@@ -131,6 +131,18 @@ CONFIG_STANDALONE=y
|
||||
CONFIG_PREVENT_FIRMWARE_BUILD=y
|
||||
# CONFIG_FW_LOADER is not set
|
||||
|
||||
#
|
||||
# Block devices
|
||||
#
|
||||
# CONFIG_BLK_DEV_FD is not set
|
||||
CONFIG_BLK_DEV_LOOP=m
|
||||
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
|
||||
CONFIG_BLK_DEV_NBD=m
|
||||
CONFIG_BLK_DEV_RAM=y
|
||||
CONFIG_BLK_DEV_RAM_SIZE=4096
|
||||
CONFIG_BLK_DEV_INITRD=y
|
||||
# CONFIG_LBD is not set
|
||||
|
||||
#
|
||||
# SCSI device support
|
||||
#
|
||||
@@ -167,18 +179,6 @@ CONFIG_BLK_DEV_SD=m
|
||||
# CONFIG_SCSI_EATA_PIO is not set
|
||||
# CONFIG_SCSI_DEBUG is not set
|
||||
|
||||
#
|
||||
# Block devices
|
||||
#
|
||||
# CONFIG_BLK_DEV_FD is not set
|
||||
CONFIG_BLK_DEV_LOOP=m
|
||||
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
|
||||
CONFIG_BLK_DEV_NBD=m
|
||||
CONFIG_BLK_DEV_RAM=y
|
||||
CONFIG_BLK_DEV_RAM_SIZE=4096
|
||||
CONFIG_BLK_DEV_INITRD=y
|
||||
# CONFIG_LBD is not set
|
||||
|
||||
#
|
||||
# Multi-device support (RAID and LVM)
|
||||
#
|
||||
@@ -283,7 +283,6 @@ CONFIG_NETDEVICES=y
|
||||
# CONFIG_SLIP is not set
|
||||
# CONFIG_SHAPER is not set
|
||||
# CONFIG_NETCONSOLE is not set
|
||||
CONFIG_INPUT=y
|
||||
CONFIG_UNIX98_PTYS=y
|
||||
|
||||
#
|
||||
|
||||
@@ -20,6 +20,8 @@ struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {};
|
||||
|
||||
extern void mcheck_init(struct cpuinfo_x86 *c);
|
||||
|
||||
extern void machine_specific_modify_cpu_capabilities(struct cpuinfo_x86 *c);
|
||||
|
||||
extern int disable_pse;
|
||||
|
||||
static void default_init(struct cpuinfo_x86 * c)
|
||||
@@ -392,6 +394,8 @@ void __init identify_cpu(struct cpuinfo_x86 *c)
|
||||
c->x86_vendor, c->x86_model);
|
||||
}
|
||||
|
||||
machine_specific_modify_cpu_capabilities(c);
|
||||
|
||||
/* Now the feature flags better reflect actual CPU features! */
|
||||
|
||||
printk(KERN_DEBUG "CPU: After all inits, caps: %08lx %08lx %08lx %08lx\n",
|
||||
@@ -504,7 +508,7 @@ void __init cpu_gdt_init(struct Xgt_desc_struct *gdt_descr)
|
||||
va < gdt_descr->address + gdt_descr->size;
|
||||
va += PAGE_SIZE, f++) {
|
||||
frames[f] = virt_to_machine(va) >> PAGE_SHIFT;
|
||||
wrprotect_bootpt(swapper_pg_dir, (void *)va, 1);
|
||||
protect_page(swapper_pg_dir, (void *)va, PROT_ON);
|
||||
}
|
||||
flush_page_update_queue();
|
||||
if (HYPERVISOR_set_gdt(frames, gdt_descr->size / 8))
|
||||
|
||||
@@ -6,8 +6,8 @@ XENARCH := $(subst ",,$(CONFIG_XENARCH))
|
||||
|
||||
CFLAGS += -Iarch/$(XENARCH)/mm
|
||||
|
||||
obj-y := init.o fault.o ioremap.o pgtable.o hypervisor.o
|
||||
c-obj-y := extable.o pageattr.o
|
||||
obj-y := init.o fault.o ioremap.o pgtable.o hypervisor.o pageattr.o
|
||||
c-obj-y := extable.o
|
||||
|
||||
c-obj-$(CONFIG_DISCONTIGMEM) += discontig.o
|
||||
c-obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
|
||||
|
||||
@@ -76,11 +76,9 @@ static pte_t * __init one_page_table_init(pmd_t *pmd)
|
||||
if (pmd_none(*pmd)) {
|
||||
pte_t *page_table = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
|
||||
set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE));
|
||||
flush_page_update_queue();
|
||||
if (page_table != pte_offset_kernel(pmd, 0))
|
||||
BUG();
|
||||
|
||||
wrprotect_bootpt((pgd_t *)start_info.pt_base, page_table, 1);
|
||||
return page_table;
|
||||
}
|
||||
|
||||
@@ -125,8 +123,7 @@ static void __init page_table_range_init (unsigned long start, unsigned long end
|
||||
}
|
||||
}
|
||||
|
||||
/* NOTE: caller must call flush_page_update_queue() */
|
||||
void __init wrprotect_bootpt(pgd_t *pgd, void *page, int set)
|
||||
void __init protect_page(pgd_t *pgd, void *page, int mode)
|
||||
{
|
||||
pmd_t *pmd;
|
||||
pte_t *pte;
|
||||
@@ -138,31 +135,25 @@ void __init wrprotect_bootpt(pgd_t *pgd, void *page, int set)
|
||||
pte = pte_offset_kernel(pmd, addr);
|
||||
if (!pte_present(*pte))
|
||||
return;
|
||||
queue_l1_entry_update(pte, set ? pte_val_ma(*pte) & ~_PAGE_RW :
|
||||
pte_val_ma(*pte) | _PAGE_RW);
|
||||
queue_l1_entry_update(pte, mode ? pte_val_ma(*pte) & ~_PAGE_RW :
|
||||
pte_val_ma(*pte) | _PAGE_RW);
|
||||
}
|
||||
|
||||
/* NOTE: caller must call flush_page_update_queue() */
|
||||
static void __init protect_bootpt_entries(pgd_t *spgd, pgd_t *dpgd, int set,
|
||||
int pmdupdate, int pmdset)
|
||||
void __init protect_pagetable(pgd_t *dpgd, pgd_t *spgd, int mode)
|
||||
{
|
||||
pmd_t *pmd;
|
||||
pte_t *pte;
|
||||
int pgd_idx, pmd_idx;
|
||||
|
||||
protect_page(dpgd, spgd, mode);
|
||||
|
||||
for (pgd_idx = 0; pgd_idx < PTRS_PER_PGD_NO_HV; spgd++, pgd_idx++) {
|
||||
pmd = pmd_offset(spgd, 0);
|
||||
if (pmd_none(*pmd))
|
||||
continue;
|
||||
if (pmdupdate)
|
||||
wrprotect_bootpt(dpgd, pmd, pmdset);
|
||||
for (pmd_idx = 0; pmd_idx < PTRS_PER_PMD; pmd++, pmd_idx++) {
|
||||
if (cpu_has_pse) {
|
||||
/* XXX */
|
||||
} else {
|
||||
pte = pte_offset_kernel(pmd, 0);
|
||||
wrprotect_bootpt(dpgd, pte, set);
|
||||
}
|
||||
pte = pte_offset_kernel(pmd, 0);
|
||||
protect_page(dpgd, pte, mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -536,18 +527,6 @@ out:
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* - write protect new L1 pages in old pgd
|
||||
* - write protect new pgd page in old pgd
|
||||
* - write protect new pgd page in new pgd
|
||||
* - write protect new L1 pages in new pgd
|
||||
* - write protect old L1 pages in new pgd and write protect old pgd in
|
||||
* new pgd
|
||||
* - pin new pgd
|
||||
* - switch to new pgd
|
||||
* - unpin old pgd
|
||||
* - make old L1 pages and old pgd page writeable in new pgd
|
||||
*/
|
||||
/*
|
||||
* paging_init() sets up the page tables - note that the first 8MB are
|
||||
* already mapped by head.S.
|
||||
@@ -557,6 +536,8 @@ out:
|
||||
*/
|
||||
void __init paging_init(void)
|
||||
{
|
||||
pgd_t *old_pgd = (pgd_t *)start_info.pt_base;
|
||||
pgd_t *new_pgd = swapper_pg_dir;
|
||||
#ifdef CONFIG_XEN_PHYSDEV_ACCESS
|
||||
int i;
|
||||
#endif
|
||||
@@ -569,21 +550,25 @@ void __init paging_init(void)
|
||||
|
||||
pagetable_init();
|
||||
|
||||
wrprotect_bootpt((pgd_t *)start_info.pt_base, swapper_pg_dir, 1);
|
||||
wrprotect_bootpt(swapper_pg_dir, swapper_pg_dir, 1);
|
||||
flush_page_update_queue();
|
||||
protect_bootpt_entries(swapper_pg_dir, swapper_pg_dir, 1, 0, 0);
|
||||
protect_bootpt_entries((pgd_t *)start_info.pt_base, swapper_pg_dir,
|
||||
1, 1, 1);
|
||||
queue_pgd_pin(__pa(swapper_pg_dir));
|
||||
load_cr3(swapper_pg_dir);
|
||||
/*
|
||||
* Write-protect both page tables within both page tables.
|
||||
* That's three ops, as the old p.t. is already protected
|
||||
* within the old p.t. Then pin the new table, switch tables,
|
||||
* and unprotect the old table.
|
||||
*/
|
||||
protect_pagetable(new_pgd, old_pgd, PROT_ON);
|
||||
protect_pagetable(new_pgd, new_pgd, PROT_ON);
|
||||
protect_pagetable(old_pgd, new_pgd, PROT_ON);
|
||||
queue_pgd_pin(__pa(new_pgd));
|
||||
load_cr3(new_pgd);
|
||||
queue_pgd_unpin(__pa(old_pgd));
|
||||
__flush_tlb_all(); /* implicit flush */
|
||||
queue_pgd_unpin(__pa(start_info.pt_base));
|
||||
protect_bootpt_entries((pgd_t *)start_info.pt_base, swapper_pg_dir,
|
||||
0, 1, 0);
|
||||
wrprotect_bootpt((pgd_t *)start_info.pt_base, swapper_pg_dir, 0);
|
||||
protect_pagetable(new_pgd, old_pgd, PROT_OFF);
|
||||
flush_page_update_queue();
|
||||
|
||||
/* Completely detached from old tables, so free them. */
|
||||
free_bootmem(__pa(old_pgd), start_info.nr_pt_frames << PAGE_SHIFT);
|
||||
|
||||
#ifdef CONFIG_X86_PAE
|
||||
/*
|
||||
* We will bail out later - printk doesn't work right now so
|
||||
@@ -741,9 +726,18 @@ void __init mem_init(void)
|
||||
|
||||
kmem_cache_t *pgd_cache;
|
||||
kmem_cache_t *pmd_cache;
|
||||
kmem_cache_t *pte_cache;
|
||||
|
||||
void __init pgtable_cache_init(void)
|
||||
{
|
||||
pte_cache = kmem_cache_create("pte",
|
||||
PTRS_PER_PTE*sizeof(pte_t),
|
||||
PTRS_PER_PTE*sizeof(pte_t),
|
||||
0,
|
||||
pte_ctor,
|
||||
pte_dtor);
|
||||
if (!pte_cache)
|
||||
panic("pgtable_cache_init(): Cannot create pte cache");
|
||||
if (PTRS_PER_PMD > 1) {
|
||||
pmd_cache = kmem_cache_create("pmd",
|
||||
PTRS_PER_PMD*sizeof(pmd_t),
|
||||
|
||||
@@ -17,6 +17,25 @@
|
||||
#include <asm/tlbflush.h>
|
||||
#include <asm/pgtable.h>
|
||||
|
||||
#ifndef CONFIG_XEN_PHYSDEV_ACCESS
|
||||
|
||||
void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags)
|
||||
{ return NULL; }
|
||||
|
||||
void *ioremap_nocache (unsigned long phys_addr, unsigned long size)
|
||||
{ return NULL; }
|
||||
|
||||
void iounmap(void *addr)
|
||||
{ }
|
||||
|
||||
void __init *bt_ioremap(unsigned long phys_addr, unsigned long size)
|
||||
{ return NULL; }
|
||||
|
||||
void __init bt_iounmap(void *addr, unsigned long size)
|
||||
{ }
|
||||
|
||||
#else
|
||||
|
||||
static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
|
||||
unsigned long phys_addr, unsigned long flags)
|
||||
{
|
||||
@@ -133,11 +152,11 @@ void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flag
|
||||
/*
|
||||
* Don't allow anybody to remap normal RAM that we're using..
|
||||
*/
|
||||
if (phys_addr < virt_to_phys(high_memory)) {
|
||||
if (machine_to_phys(phys_addr) < virt_to_phys(high_memory)) {
|
||||
char *t_addr, *t_end;
|
||||
struct page *page;
|
||||
|
||||
t_addr = __va(phys_addr);
|
||||
t_addr = bus_to_virt(phys_addr);
|
||||
t_end = t_addr + (size - 1);
|
||||
|
||||
for(page = virt_to_page(t_addr); page <= virt_to_page(t_end); page++)
|
||||
@@ -200,8 +219,8 @@ void *ioremap_nocache (unsigned long phys_addr, unsigned long size)
|
||||
/* Guaranteed to be > phys_addr, as per __ioremap() */
|
||||
last_addr = phys_addr + size - 1;
|
||||
|
||||
if (last_addr < virt_to_phys(high_memory)) {
|
||||
struct page *ppage = virt_to_page(__va(phys_addr));
|
||||
if (machine_to_phys(last_addr) < virt_to_phys(high_memory)) {
|
||||
struct page *ppage = virt_to_page(bus_to_virt(phys_addr));
|
||||
unsigned long npages;
|
||||
|
||||
phys_addr &= PAGE_MASK;
|
||||
@@ -237,8 +256,8 @@ void iounmap(void *addr)
|
||||
return;
|
||||
}
|
||||
|
||||
if (p->flags && p->phys_addr < virt_to_phys(high_memory)) {
|
||||
change_page_attr(virt_to_page(__va(p->phys_addr)),
|
||||
if (p->flags && machine_to_phys(p->phys_addr) < virt_to_phys(high_memory)) {
|
||||
change_page_attr(virt_to_page(bus_to_virt(p->phys_addr)),
|
||||
p->size >> PAGE_SHIFT,
|
||||
PAGE_KERNEL);
|
||||
global_flush_tlb();
|
||||
@@ -316,6 +335,7 @@ void __init bt_iounmap(void *addr, unsigned long size)
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFIG_XEN_PHYSDEV_ACCESS */
|
||||
|
||||
#if defined(CONFIG_XEN_PRIVILEGED_GUEST)
|
||||
|
||||
|
||||
@@ -0,0 +1,215 @@
|
||||
/*
|
||||
* Copyright 2002 Andi Kleen, SuSE Labs.
|
||||
* Thanks to Ben LaHaise for precious feedback.
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/highmem.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/tlbflush.h>
|
||||
|
||||
static spinlock_t cpa_lock = SPIN_LOCK_UNLOCKED;
|
||||
static struct list_head df_list = LIST_HEAD_INIT(df_list);
|
||||
|
||||
|
||||
pte_t *lookup_address(unsigned long address)
|
||||
{
|
||||
pgd_t *pgd = pgd_offset_k(address);
|
||||
pmd_t *pmd;
|
||||
if (pgd_none(*pgd))
|
||||
return NULL;
|
||||
pmd = pmd_offset(pgd, address);
|
||||
if (pmd_none(*pmd))
|
||||
return NULL;
|
||||
if (pmd_large(*pmd))
|
||||
return (pte_t *)pmd;
|
||||
return pte_offset_kernel(pmd, address);
|
||||
}
|
||||
|
||||
static struct page *split_large_page(unsigned long address, pgprot_t prot)
|
||||
{
|
||||
int i;
|
||||
unsigned long addr;
|
||||
struct page *base;
|
||||
pte_t *pbase;
|
||||
|
||||
spin_unlock_irq(&cpa_lock);
|
||||
base = alloc_pages(GFP_KERNEL, 0);
|
||||
spin_lock_irq(&cpa_lock);
|
||||
if (!base)
|
||||
return NULL;
|
||||
|
||||
address = __pa(address);
|
||||
addr = address & LARGE_PAGE_MASK;
|
||||
pbase = (pte_t *)page_address(base);
|
||||
for (i = 0; i < PTRS_PER_PTE; i++, addr += PAGE_SIZE) {
|
||||
pbase[i] = pfn_pte(addr >> PAGE_SHIFT,
|
||||
addr == address ? prot : PAGE_KERNEL);
|
||||
}
|
||||
return base;
|
||||
}
|
||||
|
||||
static void flush_kernel_map(void *dummy)
|
||||
{
|
||||
/* Could use CLFLUSH here if the CPU supports it (Hammer,P4) */
|
||||
if (boot_cpu_data.x86_model >= 4)
|
||||
wbinvd();
|
||||
/* Flush all to work around Errata in early athlons regarding
|
||||
* large page flushing.
|
||||
*/
|
||||
__flush_tlb_all();
|
||||
}
|
||||
|
||||
static void set_pmd_pte(pte_t *kpte, unsigned long address, pte_t pte)
|
||||
{
|
||||
struct page *page;
|
||||
unsigned long flags;
|
||||
|
||||
set_pte_atomic(kpte, pte); /* change init_mm */
|
||||
if (PTRS_PER_PMD > 1)
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&pgd_lock, flags);
|
||||
for (page = pgd_list; page; page = (struct page *)page->index) {
|
||||
pgd_t *pgd;
|
||||
pmd_t *pmd;
|
||||
pgd = (pgd_t *)page_address(page) + pgd_index(address);
|
||||
pmd = pmd_offset(pgd, address);
|
||||
set_pte_atomic((pte_t *)pmd, pte);
|
||||
}
|
||||
spin_unlock_irqrestore(&pgd_lock, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* No more special protections in this 2/4MB area - revert to a
|
||||
* large page again.
|
||||
*/
|
||||
static inline void revert_page(struct page *kpte_page, unsigned long address)
|
||||
{
|
||||
pte_t *linear = (pte_t *)
|
||||
pmd_offset(pgd_offset(&init_mm, address), address);
|
||||
set_pmd_pte(linear, address,
|
||||
pfn_pte((__pa(address) & LARGE_PAGE_MASK) >> PAGE_SHIFT,
|
||||
PAGE_KERNEL_LARGE));
|
||||
}
|
||||
|
||||
static int
|
||||
__change_page_attr(struct page *page, pgprot_t prot)
|
||||
{
|
||||
pte_t *kpte;
|
||||
unsigned long address;
|
||||
struct page *kpte_page;
|
||||
|
||||
#ifdef CONFIG_HIGHMEM
|
||||
if (page >= highmem_start_page)
|
||||
BUG();
|
||||
#endif
|
||||
address = (unsigned long)page_address(page);
|
||||
|
||||
kpte = lookup_address(address);
|
||||
if (!kpte)
|
||||
return -EINVAL;
|
||||
kpte_page = virt_to_page(((unsigned long)kpte) & PAGE_MASK);
|
||||
if (pgprot_val(prot) != pgprot_val(PAGE_KERNEL)) {
|
||||
if ((pte_val(*kpte) & _PAGE_PSE) == 0) {
|
||||
pte_t old = *kpte;
|
||||
pte_t standard = mk_pte(page, PAGE_KERNEL);
|
||||
set_pte_atomic(kpte, mk_pte(page, prot));
|
||||
if (pte_same(old,standard))
|
||||
get_page(kpte_page);
|
||||
} else {
|
||||
struct page *split = split_large_page(address, prot);
|
||||
if (!split)
|
||||
return -ENOMEM;
|
||||
get_page(kpte_page);
|
||||
set_pmd_pte(kpte,address,mk_pte(split, PAGE_KERNEL));
|
||||
}
|
||||
} else if ((pte_val(*kpte) & _PAGE_PSE) == 0) {
|
||||
set_pte_atomic(kpte, mk_pte(page, PAGE_KERNEL));
|
||||
__put_page(kpte_page);
|
||||
}
|
||||
|
||||
if (cpu_has_pse && (page_count(kpte_page) == 1)) {
|
||||
list_add(&kpte_page->lru, &df_list);
|
||||
revert_page(kpte_page, address);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void flush_map(void)
|
||||
{
|
||||
on_each_cpu(flush_kernel_map, NULL, 1, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Change the page attributes of an page in the linear mapping.
|
||||
*
|
||||
* This should be used when a page is mapped with a different caching policy
|
||||
* than write-back somewhere - some CPUs do not like it when mappings with
|
||||
* different caching policies exist. This changes the page attributes of the
|
||||
* in kernel linear mapping too.
|
||||
*
|
||||
* The caller needs to ensure that there are no conflicting mappings elsewhere.
|
||||
* This function only deals with the kernel linear map.
|
||||
*
|
||||
* Caller must call global_flush_tlb() after this.
|
||||
*/
|
||||
int change_page_attr(struct page *page, int numpages, pgprot_t prot)
|
||||
{
|
||||
int err = 0;
|
||||
int i;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&cpa_lock, flags);
|
||||
for (i = 0; i < numpages; i++, page++) {
|
||||
err = __change_page_attr(page, prot);
|
||||
if (err)
|
||||
break;
|
||||
}
|
||||
spin_unlock_irqrestore(&cpa_lock, flags);
|
||||
return err;
|
||||
}
|
||||
|
||||
void global_flush_tlb(void)
|
||||
{
|
||||
LIST_HEAD(l);
|
||||
struct list_head* n;
|
||||
|
||||
BUG_ON(irqs_disabled());
|
||||
|
||||
spin_lock_irq(&cpa_lock);
|
||||
list_splice_init(&df_list, &l);
|
||||
spin_unlock_irq(&cpa_lock);
|
||||
flush_map();
|
||||
n = l.next;
|
||||
while (n != &l) {
|
||||
struct page *pg = list_entry(n, struct page, lru);
|
||||
n = n->next;
|
||||
__free_page(pg);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DEBUG_PAGEALLOC
|
||||
void kernel_map_pages(struct page *page, int numpages, int enable)
|
||||
{
|
||||
if (PageHighMem(page))
|
||||
return;
|
||||
/* the return value is ignored - the calls cannot fail,
|
||||
* large pages are disabled at boot time.
|
||||
*/
|
||||
change_page_attr(page, numpages, enable ? PAGE_KERNEL : __pgprot(0));
|
||||
/* we should perform an IPI and flush all tlbs,
|
||||
* but that can deadlock->flush only current cpu.
|
||||
*/
|
||||
__flush_tlb_all();
|
||||
}
|
||||
EXPORT_SYMBOL(kernel_map_pages);
|
||||
#endif
|
||||
|
||||
EXPORT_SYMBOL(change_page_attr);
|
||||
EXPORT_SYMBOL(global_flush_tlb);
|
||||
@@ -185,32 +185,44 @@ pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
|
||||
return pte;
|
||||
}
|
||||
|
||||
void pte_ctor(void *pte, kmem_cache_t *cache, unsigned long unused)
|
||||
{
|
||||
|
||||
clear_page(pte);
|
||||
__make_page_readonly(pte);
|
||||
queue_pte_pin(virt_to_phys(pte));
|
||||
flush_page_update_queue();
|
||||
}
|
||||
|
||||
void pte_dtor(void *pte, kmem_cache_t *cache, unsigned long unused)
|
||||
{
|
||||
|
||||
queue_pte_unpin(virt_to_phys(pte));
|
||||
__make_page_writable(pte);
|
||||
flush_page_update_queue();
|
||||
}
|
||||
|
||||
struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
|
||||
{
|
||||
struct page *pte;
|
||||
pte_t *ptep;
|
||||
|
||||
#ifdef CONFIG_HIGHPTE
|
||||
struct page *pte;
|
||||
|
||||
pte = alloc_pages(GFP_KERNEL|__GFP_HIGHMEM|__GFP_REPEAT, 0);
|
||||
#else
|
||||
pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT, 0);
|
||||
#endif
|
||||
if (pte) {
|
||||
#ifdef CONFIG_HIGHPTE
|
||||
void *kaddr = kmap_atomic(pte, KM_USER0);
|
||||
clear_page(kaddr);
|
||||
kunmap_atomic_force(kaddr, KM_USER0);
|
||||
#else
|
||||
if (pte == NULL)
|
||||
return pte;
|
||||
if (pte >= highmem_start_page) {
|
||||
clear_highpage(pte);
|
||||
#endif
|
||||
#ifdef CONFIG_HIGHPTE
|
||||
if (pte < highmem_start_page)
|
||||
#endif
|
||||
{
|
||||
__make_page_readonly(phys_to_virt(page_to_pseudophys(pte)));
|
||||
flush_page_update_queue();
|
||||
}
|
||||
return pte;
|
||||
}
|
||||
return pte;
|
||||
/* not a highmem page -- free page and grab one from the cache */
|
||||
__free_page(pte);
|
||||
#endif
|
||||
ptep = kmem_cache_alloc(pte_cache, GFP_KERNEL);
|
||||
if (ptep)
|
||||
return virt_to_page(ptep);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void pmd_ctor(void *pmd, kmem_cache_t *cache, unsigned long flags)
|
||||
|
||||
@@ -1148,6 +1148,12 @@ static void blkif_status_change(blkif_fe_interface_status_changed_t *status)
|
||||
|
||||
break;
|
||||
|
||||
case BLKIF_INTERFACE_STATUS_CHANGED:
|
||||
/* The domain controller is notifying us that a device has been
|
||||
* added or removed.
|
||||
*/
|
||||
break;
|
||||
|
||||
default:
|
||||
printk(KERN_WARNING "Status change to unknown value %d\n",
|
||||
status->status);
|
||||
|
||||
@@ -26,6 +26,9 @@
|
||||
#include <asm-xen/hypervisor-ifs/io/netif.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
#include <net/arp.h>
|
||||
#include <net/route.h>
|
||||
|
||||
#if 0
|
||||
#define DPRINTK(fmt, args...) \
|
||||
printk(KERN_INFO "[XEN] %s" fmt, __FUNCTION__, ##args)
|
||||
@@ -171,6 +174,32 @@ static int netctrl_connected_count(void)
|
||||
return connected;
|
||||
}
|
||||
|
||||
/** Send a packet on a net device to encourage switches to learn the
|
||||
* MAC. We send a fake ARP request.
|
||||
*
|
||||
* @param dev device
|
||||
* @return 0 on success, error code otherwise
|
||||
*/
|
||||
static int vif_wake(struct net_device *dev){
|
||||
int err = 0;
|
||||
struct sk_buff *skb;
|
||||
u32 src_ip;
|
||||
u32 dst_ip = INADDR_BROADCAST;
|
||||
unsigned char dst_hw[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
||||
|
||||
src_ip = inet_select_addr(dev, dst_ip, RT_SCOPE_LINK);
|
||||
skb = arp_create(ARPOP_REQUEST, ETH_P_ARP,
|
||||
dst_ip, dev, src_ip,
|
||||
dst_hw, dev->dev_addr, NULL);
|
||||
if(skb == NULL){
|
||||
err = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
err = dev_queue_xmit(skb);
|
||||
exit:
|
||||
return err;
|
||||
}
|
||||
|
||||
static inline struct sk_buff *alloc_skb_page(void)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
@@ -739,6 +768,13 @@ static void netif_status_change(netif_fe_interface_status_changed_t *status)
|
||||
(void)request_irq(np->irq, netif_int, SA_SAMPLE_RANDOM,
|
||||
dev->name, dev);
|
||||
netctrl_connected_count();
|
||||
vif_wake(dev);
|
||||
break;
|
||||
|
||||
case NETIF_INTERFACE_STATUS_CHANGED:
|
||||
/* The domain controller is notifying us that a device has been
|
||||
* added or removed.
|
||||
*/
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -128,12 +128,12 @@ extern void bt_iounmap(void *addr, unsigned long size);
|
||||
/*
|
||||
* ISA I/O bus memory addresses are 1:1 with the physical address.
|
||||
*/
|
||||
#define isa_virt_to_bus(_x) BUG() // should be (void *)((FIX_ISAMAP_BEGIN - __virt_to_fix((_x))) << PAGE_SHIFT)
|
||||
#define isa_page_to_bus(_x) BUG() // page_to_phys(_x)
|
||||
#define isa_virt_to_bus(_x) isa_virt_to_bus_is_UNSUPPORTED->x
|
||||
#define isa_page_to_bus(_x) isa_page_to_bus_is_UNSUPPORTED->x
|
||||
#ifdef CONFIG_XEN_PRIVILEGED_GUEST
|
||||
#define isa_bus_to_virt(_x) (void *)__fix_to_virt(FIX_ISAMAP_BEGIN - ((_x) >> PAGE_SHIFT))
|
||||
#else
|
||||
#define isa_bus_to_virt(_x) (void *)0L /* XXXcl */
|
||||
#define isa_bus_to_virt(_x) isa_bus_to_virt_needs_PRIVILEGED_BUILD
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
||||
@@ -22,6 +22,17 @@ static char * __init machine_specific_memory_setup(void)
|
||||
return who;
|
||||
}
|
||||
|
||||
void __init machine_specific_modify_cpu_capabilities(struct cpuinfo_x86 *c)
|
||||
{
|
||||
clear_bit(X86_FEATURE_VME, c->x86_capability);
|
||||
clear_bit(X86_FEATURE_DE, c->x86_capability);
|
||||
clear_bit(X86_FEATURE_PSE, c->x86_capability);
|
||||
clear_bit(X86_FEATURE_TSC, c->x86_capability);
|
||||
clear_bit(X86_FEATURE_PGE, c->x86_capability);
|
||||
clear_bit(X86_FEATURE_MTRR, c->x86_capability);
|
||||
clear_bit(X86_FEATURE_FXSR, c->x86_capability);
|
||||
}
|
||||
|
||||
extern void hypervisor_callback(void);
|
||||
extern void failsafe_callback(void);
|
||||
|
||||
@@ -31,11 +42,5 @@ static void __init machine_specific_arch_setup(void)
|
||||
__KERNEL_CS, (unsigned long)hypervisor_callback,
|
||||
__KERNEL_CS, (unsigned long)failsafe_callback);
|
||||
|
||||
clear_bit(X86_FEATURE_VME, boot_cpu_data.x86_capability);
|
||||
clear_bit(X86_FEATURE_DE, boot_cpu_data.x86_capability);
|
||||
clear_bit(X86_FEATURE_PSE, boot_cpu_data.x86_capability);
|
||||
clear_bit(X86_FEATURE_TSC, boot_cpu_data.x86_capability);
|
||||
clear_bit(X86_FEATURE_PGE, boot_cpu_data.x86_capability);
|
||||
clear_bit(X86_FEATURE_MTRR, boot_cpu_data.x86_capability);
|
||||
clear_bit(X86_FEATURE_FXSR, boot_cpu_data.x86_capability);
|
||||
machine_specific_modify_cpu_capabilities(&boot_cpu_data);
|
||||
}
|
||||
@@ -41,19 +41,16 @@ static inline void pte_free(struct page *pte)
|
||||
#ifdef CONFIG_HIGHPTE
|
||||
if (pte < highmem_start_page)
|
||||
#endif
|
||||
{
|
||||
__make_page_writable(phys_to_virt(page_to_pseudophys(pte)));
|
||||
kmem_cache_free(pte_cache,
|
||||
phys_to_virt(page_to_pseudophys(pte)));
|
||||
#ifdef CONFIG_HIGHPTE
|
||||
else
|
||||
__free_page(pte);
|
||||
flush_page_update_queue();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#define __pte_free_tlb(tlb,pte) do { \
|
||||
tlb_remove_page((tlb),(pte)); \
|
||||
flush_page_update_queue(); \
|
||||
/* XXXcl queue */ \
|
||||
} while (0)
|
||||
#define __pte_free_tlb(tlb,pte) pte_free(pte)
|
||||
|
||||
/*
|
||||
* allocating and freeing a pmd is trivial: the 1-entry pmd is
|
||||
|
||||
@@ -35,9 +35,12 @@ extern unsigned long empty_zero_page[1024];
|
||||
extern pgd_t swapper_pg_dir[1024];
|
||||
extern kmem_cache_t *pgd_cache;
|
||||
extern kmem_cache_t *pmd_cache;
|
||||
extern kmem_cache_t *pte_cache;
|
||||
extern spinlock_t pgd_lock;
|
||||
extern struct page *pgd_list;
|
||||
|
||||
void pte_ctor(void *, kmem_cache_t *, unsigned long);
|
||||
void pte_dtor(void *, kmem_cache_t *, unsigned long);
|
||||
void pmd_ctor(void *, kmem_cache_t *, unsigned long);
|
||||
void pgd_ctor(void *, kmem_cache_t *, unsigned long);
|
||||
void pgd_dtor(void *, kmem_cache_t *, unsigned long);
|
||||
@@ -315,9 +318,7 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
|
||||
((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
|
||||
|
||||
#define pmd_clear(xp) do { \
|
||||
pmd_t p = *(xp); \
|
||||
set_pmd(xp, __pmd(0)); \
|
||||
__make_page_writable((void *)pmd_page_kernel(p)); \
|
||||
xen_flush_page_update_queue(); \
|
||||
} while (0)
|
||||
|
||||
|
||||
@@ -122,9 +122,13 @@ static inline unsigned long _get_base(char * addr)
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#define wbinvd() \
|
||||
BUG();
|
||||
// __asm__ __volatile__ ("wbinvd": : :"memory");
|
||||
static inline void wbinvd(void)
|
||||
{
|
||||
mmu_update_t u;
|
||||
u.ptr = MMU_EXTENDED_COMMAND;
|
||||
u.val = MMUEXT_FLUSH_CACHE;
|
||||
(void)HYPERVISOR_mmu_update(&u, 1, NULL);
|
||||
}
|
||||
|
||||
static inline unsigned long get_limit(unsigned long segment)
|
||||
{
|
||||
|
||||
@@ -34,7 +34,11 @@ void xen_cpu_idle (void);
|
||||
void do_hypervisor_callback(struct pt_regs *regs);
|
||||
|
||||
/* arch/xen/i386/mm/init.c */
|
||||
void wrprotect_bootpt(pgd_t *, void *, int);
|
||||
/* NOTE: caller must call flush_page_update_queue() */
|
||||
#define PROT_ON 1
|
||||
#define PROT_OFF 0
|
||||
void /* __init */ protect_page(pgd_t *dpgd, void *page, int mode);
|
||||
void /* __init */ protect_pagetable(pgd_t *dpgd, pgd_t *spgd, int mode);
|
||||
|
||||
/* arch/xen/i386/kernel/head.S */
|
||||
void lgdt_finish(void);
|
||||
|
||||
@@ -548,7 +548,7 @@ class Xend:
|
||||
return self.xendPost(self.domainurl(id),
|
||||
{'op' : 'device_destroy',
|
||||
'type' : type,
|
||||
'index' : idx })
|
||||
'idx' : idx })
|
||||
|
||||
def xend_consoles(self):
|
||||
return self.xendGet(self.consoleurl())
|
||||
|
||||
@@ -243,12 +243,12 @@ class XendDomain:
|
||||
if d['shutdown']:
|
||||
reason = XendDomainInfo.shutdown_reason(d['shutdown_reason'])
|
||||
log.debug('XendDomain>reap> shutdown id=%s reason=%s', id, reason)
|
||||
dominfo = self.domain_by_id.get(id)
|
||||
name = (dominfo and dominfo.name) or '??'
|
||||
if reason in ['suspend']:
|
||||
dominfo = self.domain_by_id.get(id)
|
||||
if dominfo.is_terminated():
|
||||
log.debug('XendDomain>reap> Suspended domain died id=%s', id)
|
||||
else:
|
||||
name = (dominfo and dominfo.name) or '??'
|
||||
eserver.inject('xend.domain.suspended', [name, id])
|
||||
continue
|
||||
if reason in ['poweroff', 'reboot']:
|
||||
|
||||
@@ -576,6 +576,16 @@ class XendDomainInfo:
|
||||
dl.append(dev)
|
||||
self.devices[type] = dl
|
||||
|
||||
def remove_device(self, type, dev):
|
||||
"""Remove a device from a virtual machine.
|
||||
|
||||
@param type: device type
|
||||
@param dev: device
|
||||
"""
|
||||
dl = self.devices.get(type, [])
|
||||
if dev in dl:
|
||||
dl.remove(dev)
|
||||
|
||||
def get_devices(self, type):
|
||||
"""Get a list of the devices of a given type.
|
||||
|
||||
@@ -812,7 +822,7 @@ class XendDomainInfo:
|
||||
devs = self.get_devices(dev_name)
|
||||
dev_index = len(devs)
|
||||
self.config.append(['device', dev_config])
|
||||
d = dev_handler(self, dev_config, dev_index)
|
||||
d = dev_handler(self, dev_config, dev_index, change=1)
|
||||
return d
|
||||
|
||||
def device_destroy(self, type, idx):
|
||||
@@ -829,7 +839,8 @@ class XendDomainInfo:
|
||||
dev_config = self.config_device(type, index)
|
||||
if dev_config:
|
||||
self.config.remove(['device', dev_config])
|
||||
dev.destroy()
|
||||
dev.destroy(change=1)
|
||||
self.remove_device(type, dev)
|
||||
|
||||
def configure_memory(self):
|
||||
"""Configure vm memory limit.
|
||||
@@ -1053,7 +1064,7 @@ def vm_image_netbsd(vm, image):
|
||||
return vm
|
||||
|
||||
|
||||
def vm_dev_vif(vm, val, index):
|
||||
def vm_dev_vif(vm, val, index, change=0):
|
||||
"""Create a virtual network interface (vif).
|
||||
|
||||
@param vm: virtual machine
|
||||
@@ -1069,11 +1080,13 @@ def vm_dev_vif(vm, val, index):
|
||||
def cbok(dev):
|
||||
dev.vifctl('up', vmname=vm.name)
|
||||
vm.add_device('vif', dev)
|
||||
if change:
|
||||
dev.interfaceChanged()
|
||||
return dev
|
||||
defer.addCallback(cbok)
|
||||
return defer
|
||||
|
||||
def vm_dev_vbd(vm, val, index):
|
||||
def vm_dev_vbd(vm, val, index, change=0):
|
||||
"""Create a virtual block device (vbd).
|
||||
|
||||
@param vm: virtual machine
|
||||
@@ -1094,6 +1107,8 @@ def vm_dev_vbd(vm, val, index):
|
||||
vbd.dev = dev
|
||||
vbd.uname = uname
|
||||
vm.add_device('vbd', vbd)
|
||||
if change:
|
||||
vbd.interfaceChanged()
|
||||
return vbd
|
||||
defer.addCallback(fn)
|
||||
return defer
|
||||
@@ -1110,7 +1125,7 @@ def parse_pci(val):
|
||||
v = val
|
||||
return v
|
||||
|
||||
def vm_dev_pci(vm, val, index):
|
||||
def vm_dev_pci(vm, val, index, change=0):
|
||||
"""Add a pci device.
|
||||
|
||||
@param vm: virtual machine
|
||||
|
||||
@@ -23,7 +23,6 @@ from twisted.internet import reactor
|
||||
from twisted.internet import protocol
|
||||
from twisted.internet import abstract
|
||||
from twisted.internet import defer
|
||||
#defer.Deferred.debug = 1
|
||||
|
||||
from xen.lowlevel import xu
|
||||
|
||||
@@ -45,127 +44,6 @@ from params import *
|
||||
|
||||
DEBUG = 1
|
||||
|
||||
class MgmtProtocol(protocol.DatagramProtocol):
|
||||
"""Handler for the management socket (unix-domain).
|
||||
"""
|
||||
|
||||
def __init__(self, daemon):
|
||||
#protocol.DatagramProtocol.__init__(self)
|
||||
self.daemon = daemon
|
||||
|
||||
def write(self, data, addr):
|
||||
return self.transport.write(data, addr)
|
||||
|
||||
def datagramReceived(self, data, addr):
|
||||
if DEBUG: print 'datagramReceived> addr=', addr, 'data=', data
|
||||
io = StringIO.StringIO(data)
|
||||
try:
|
||||
vals = sxp.parse(io)
|
||||
res = self.dispatch(vals[0])
|
||||
self.send_result(addr, res)
|
||||
except SystemExit:
|
||||
raise
|
||||
except:
|
||||
if DEBUG:
|
||||
raise
|
||||
else:
|
||||
self.send_error(addr)
|
||||
|
||||
def send_reply(self, addr, sxpr):
|
||||
io = StringIO.StringIO()
|
||||
sxp.show(sxpr, out=io)
|
||||
io.seek(0)
|
||||
self.write(io.getvalue(), addr)
|
||||
|
||||
def send_result(self, addr, res):
|
||||
|
||||
def fn(res, self=self, addr=addr):
|
||||
self.send_reply(addr, ['ok', res])
|
||||
|
||||
if isinstance(res, defer.Deferred):
|
||||
res.addCallback(fn)
|
||||
else:
|
||||
fn(res)
|
||||
|
||||
def send_error(self, addr):
|
||||
(extype, exval) = sys.exc_info()[:2]
|
||||
self.send_reply(addr, ['err',
|
||||
['type', str(extype) ],
|
||||
['value', str(exval) ] ] )
|
||||
|
||||
def opname(self, name):
|
||||
"""Get the name of the method for an operation.
|
||||
"""
|
||||
return 'op_' + name.replace('.', '_')
|
||||
|
||||
def operror(self, name, v):
|
||||
"""Default operation handler - signals an error.
|
||||
"""
|
||||
raise NotImplementedError('Invalid operation: ' +name)
|
||||
|
||||
def dispatch(self, req):
|
||||
"""Dispatch a request to its handler.
|
||||
"""
|
||||
op_name = sxp.name(req)
|
||||
op_method_name = self.opname(op_name)
|
||||
op_method = getattr(self, op_method_name, self.operror)
|
||||
return op_method(op_name, req)
|
||||
|
||||
def op_console_create(self, name, req):
|
||||
"""Create a new control interface - console for a domain.
|
||||
"""
|
||||
print name, req
|
||||
dom = sxp.child_value(req, 'domain')
|
||||
if not dom: raise XendError('Missing domain')
|
||||
dom = int(dom)
|
||||
console_port = sxp.child_value(req, 'console_port')
|
||||
if console_port:
|
||||
console_port = int(console_port)
|
||||
resp = self.daemon.console_create(dom, console_port).sxpr()
|
||||
print name, resp
|
||||
return resp
|
||||
|
||||
def op_consoles(self, name, req):
|
||||
"""Get a list of the consoles.
|
||||
"""
|
||||
return self.daemon.consoles()
|
||||
|
||||
def op_console_disconnect(self, name, req):
|
||||
id = sxp.child_value(req, 'id')
|
||||
if not id:
|
||||
raise XendError('Missing console id')
|
||||
id = int(id)
|
||||
console = self.daemon.get_console(id)
|
||||
if not console:
|
||||
raise XendError('Invalid console id')
|
||||
if console.conn:
|
||||
console.conn.loseConnection()
|
||||
return ['ok']
|
||||
|
||||
def op_blkifs(self, name, req):
|
||||
pass
|
||||
|
||||
def op_blkif_devs(self, name, req):
|
||||
pass
|
||||
|
||||
def op_blkif_create(self, name, req):
|
||||
pass
|
||||
|
||||
def op_blkif_dev_create(self, name, req):
|
||||
pass
|
||||
|
||||
def op_netifs(self, name, req):
|
||||
pass
|
||||
|
||||
def op_netif_devs(self, name, req):
|
||||
pass
|
||||
|
||||
def op_netif_create(self, name, req):
|
||||
pass
|
||||
|
||||
def op_netif_dev_create(self, name, req):
|
||||
pass
|
||||
|
||||
class NotifierProtocol(protocol.Protocol):
|
||||
"""Asynchronous handler for i/o on the notifier (event channel).
|
||||
"""
|
||||
@@ -245,17 +123,14 @@ class NotifierPort(abstract.FileDescriptor):
|
||||
del self.d
|
||||
|
||||
def doRead(self):
|
||||
#print 'NotifierPort>doRead>', self
|
||||
count = 0
|
||||
while 1:
|
||||
#print 'NotifierPort>doRead>', count
|
||||
notification = self.notifier.read()
|
||||
if not notification:
|
||||
break
|
||||
self.protocol.notificationReceived(notification)
|
||||
self.notifier.unmask(notification)
|
||||
count += 1
|
||||
#print 'NotifierPort>doRead<'
|
||||
|
||||
class EventProtocol(protocol.Protocol):
|
||||
"""Asynchronous handler for a connected event socket.
|
||||
@@ -481,25 +356,69 @@ class Daemon:
|
||||
err = 1
|
||||
print "Daemon already running: ", pids
|
||||
return err
|
||||
|
||||
def cleanup(self, kill=False):
|
||||
# No cleanup to do if PID_FILE is empty.
|
||||
if not os.path.isfile(PID_FILE) or not os.path.getsize(PID_FILE):
|
||||
return 0
|
||||
# Read the pid of the previous invocation and search active process list.
|
||||
pid = open(PID_FILE, 'r').read()
|
||||
lines = os.popen('ps ' + pid + ' 2>/dev/null').readlines()
|
||||
for line in lines:
|
||||
if re.search('^ *' + pid + '.+xend', line):
|
||||
if not kill:
|
||||
print "Daemon is already running (pid %d)" % int(pid)
|
||||
return 1
|
||||
# Old daemon is still active: terminate it.
|
||||
os.kill(int(pid), 1)
|
||||
# Delete the stale PID_FILE.
|
||||
os.remove(PID_FILE)
|
||||
return 0
|
||||
|
||||
def read_pid(self, pidfile):
|
||||
"""Read process id from a file.
|
||||
|
||||
@param pidfile: file to read
|
||||
@return pid or 0
|
||||
"""
|
||||
pid = 0
|
||||
if os.path.isfile(pidfile) and os.path.getsize(pidfile):
|
||||
try:
|
||||
pid = open(pidfile, 'r').read()
|
||||
pid = int(pid)
|
||||
except:
|
||||
pid = 0
|
||||
return pid
|
||||
|
||||
def find_process(self, pid, name):
|
||||
"""Search for a process.
|
||||
|
||||
@param pid: process id
|
||||
@param name: process name
|
||||
@return: pid if found, 0 otherwise
|
||||
"""
|
||||
running = 0
|
||||
if pid:
|
||||
lines = os.popen('ps %d 2>/dev/null' % pid).readlines()
|
||||
exp = '^ *%d.+%s' % (pid, name)
|
||||
for line in lines:
|
||||
if re.search(exp, line):
|
||||
running = pid
|
||||
break
|
||||
return running
|
||||
|
||||
def cleanup_process(self, pidfile, name, kill):
|
||||
"""Clean up the pidfile for a process.
|
||||
If a running process is found, kills it if 'kill' is true.
|
||||
|
||||
@param pidfile: pid file
|
||||
@param name: process name
|
||||
@param kill: whether to kill the process
|
||||
@return running process id or 0
|
||||
"""
|
||||
running = 0
|
||||
pid = self.read_pid(pidfile)
|
||||
if self.find_process(pid, name):
|
||||
if kill:
|
||||
os.kill(pid, 1)
|
||||
else:
|
||||
running = pid
|
||||
if running == 0 and os.path.isfile(pidfile):
|
||||
os.remove(pidfile)
|
||||
return running
|
||||
|
||||
def cleanup_xend(self, kill=False):
|
||||
return self.cleanup_process(XEND_PID_FILE, "xend", kill)
|
||||
|
||||
def cleanup_xfrd(self, kill=False):
|
||||
return self.cleanup_process(XFRD_PID_FILE, "xfrd", kill)
|
||||
|
||||
def cleanup(self, kill=False):
|
||||
self.cleanup_xend(kill=kill)
|
||||
self.cleanup_xfrd(kill=kill)
|
||||
|
||||
def install_child_reaper(self):
|
||||
#signal.signal(signal.SIGCHLD, self.onSIGCHLD)
|
||||
# Ensure that zombie children are automatically reaped.
|
||||
@@ -510,42 +429,65 @@ class Daemon:
|
||||
while code > 0:
|
||||
code = os.waitpid(-1, os.WNOHANG)
|
||||
|
||||
def fork_pid(self, pidfile):
|
||||
"""Fork and write the pid of the child to 'pidfile'.
|
||||
|
||||
@param pidfile: pid file
|
||||
@return: pid of child in parent, 0 in child
|
||||
"""
|
||||
pid = os.fork()
|
||||
if pid:
|
||||
# Parent
|
||||
pidfile = open(pidfile, 'w')
|
||||
pidfile.write(str(pid))
|
||||
pidfile.close()
|
||||
return pid
|
||||
|
||||
def start_xfrd(self):
|
||||
"""Fork and exec xfrd, writing its pid to XFRD_PID_FILE.
|
||||
"""
|
||||
if self.fork_pid(XFRD_PID_FILE):
|
||||
# Parent
|
||||
pass
|
||||
else:
|
||||
# Child
|
||||
self.set_user()
|
||||
os.execl("/usr/sbin/xfrd", "xfrd")
|
||||
|
||||
def start(self, trace=0):
|
||||
if self.cleanup(kill=False):
|
||||
xend_pid = self.cleanup_xend()
|
||||
xfrd_pid = self.cleanup_xfrd()
|
||||
if xfrd_pid == 0:
|
||||
self.start_xfrd()
|
||||
if xend_pid > 0:
|
||||
return 1
|
||||
|
||||
# Detach from TTY.
|
||||
if not DEBUG:
|
||||
os.setsid()
|
||||
|
||||
if self.set_user():
|
||||
return 1
|
||||
|
||||
self.install_child_reaper()
|
||||
|
||||
# Fork -- parent writes PID_FILE and exits.
|
||||
pid = os.fork()
|
||||
if pid:
|
||||
# Parent
|
||||
pidfile = open(PID_FILE, 'w')
|
||||
pidfile.write(str(pid))
|
||||
pidfile.close()
|
||||
return 0
|
||||
# Child
|
||||
self.tracing(trace)
|
||||
self.run()
|
||||
if self.fork_pid(XEND_PID_FILE):
|
||||
#Parent
|
||||
pass
|
||||
else:
|
||||
# Child
|
||||
self.tracing(trace)
|
||||
self.run()
|
||||
return 0
|
||||
|
||||
def tracing(self, traceon):
|
||||
"""Turn tracing on or off.
|
||||
|
||||
traceon tracing flag
|
||||
@param traceon: tracing flag
|
||||
"""
|
||||
if traceon == self.traceon:
|
||||
return
|
||||
self.traceon = traceon
|
||||
if traceon:
|
||||
self.tracefile = open('/var/log/xend.trace', 'w+', 1)
|
||||
self.tracefile = open(XEND_TRACE_FILE, 'w+', 1)
|
||||
self.traceindent = 0
|
||||
sys.settrace(self.trace)
|
||||
try:
|
||||
@@ -620,7 +562,6 @@ class Daemon:
|
||||
xroot = XendRoot.instance()
|
||||
log.info("Xend Daemon started")
|
||||
self.createFactories()
|
||||
self.listenMgmt()
|
||||
self.listenEvent()
|
||||
self.listenNotifier()
|
||||
self.listenVirq()
|
||||
@@ -634,13 +575,6 @@ class Daemon:
|
||||
self.netifCF = netif.NetifControllerFactory()
|
||||
self.consoleCF = console.ConsoleControllerFactory()
|
||||
|
||||
def listenMgmt(self):
|
||||
protocol = MgmtProtocol(self)
|
||||
s = os.path.join(CONTROL_DIR, MGMT_SOCK)
|
||||
if os.path.exists(s):
|
||||
os.unlink(s)
|
||||
return reactor.listenUNIXDatagram(s, protocol)
|
||||
|
||||
def listenEvent(self):
|
||||
protocol = EventFactory(self)
|
||||
return reactor.listenTCP(EVENT_PORT, protocol)
|
||||
@@ -656,7 +590,7 @@ class Daemon:
|
||||
virqChan.registerClient(VirqClient(self))
|
||||
|
||||
def exit(self):
|
||||
reactor.diconnectAll()
|
||||
reactor.disconnectAll()
|
||||
sys.exit(0)
|
||||
|
||||
def getDomChannel(self, dom):
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
"""
|
||||
|
||||
from twisted.internet import defer
|
||||
#defer.Deferred.debug = 1
|
||||
|
||||
from xen.xend import sxp
|
||||
from xen.xend.XendLogging import log
|
||||
@@ -88,14 +87,12 @@ class BlkifBackendInterface(controller.BackendInterface):
|
||||
self.send_be_disconnect(response=d)
|
||||
|
||||
def send_be_disconnect(self, response=None):
|
||||
log.debug('>BlkifBackendController>send_be_disconnect> %s', str(self))
|
||||
msg = packMsg('blkif_be_disconnect_t',
|
||||
{ 'domid' : self.controller.dom,
|
||||
'blkif_handle' : self.handle })
|
||||
self.writeRequest(msg, response=response)
|
||||
|
||||
def send_be_destroy(self, response=None):
|
||||
log.debug('>BlkifBackendController>send_be_destroy> %s', str(self))
|
||||
msg = packMsg('blkif_be_destroy_t',
|
||||
{ 'domid' : self.controller.dom,
|
||||
'blkif_handle' : self.handle })
|
||||
@@ -127,9 +124,28 @@ class BlkifBackendInterface(controller.BackendInterface):
|
||||
msg = packMsg('blkif_fe_interface_status_changed_t',
|
||||
{ 'handle' : self.handle,
|
||||
'status' : BLKIF_INTERFACE_STATUS_CONNECTED,
|
||||
'domid' : 0, ## FIXME: should be domid of backend
|
||||
'domid' : self.dom,
|
||||
'evtchn' : self.evtchn['port2'] })
|
||||
self.controller.writeRequest(msg, response=response)
|
||||
|
||||
def interfaceDisconnected(self):
|
||||
msg = packMsg('blkif_fe_interface_status_changed_t',
|
||||
{ 'handle' : self.handle,
|
||||
'status' : BLKIF_INTERFACE_STATUS_DISCONNECTED,
|
||||
'domid' : self.dom,
|
||||
'evtchn' : 0 })
|
||||
self.controller.writeRequest(msg)
|
||||
|
||||
def interfaceChanged(self):
|
||||
"""Notify the front-end that devices have been added or removed.
|
||||
The front-end should then probe for devices.
|
||||
"""
|
||||
msg = packMsg('blkif_fe_interface_status_changed_t',
|
||||
{ 'handle' : self.handle,
|
||||
'status' : BLKIF_INTERFACE_STATUS_CHANGED,
|
||||
'domid' : self.dom,
|
||||
'evtchn' : 0 })
|
||||
self.controller.writeRequest(msg)
|
||||
|
||||
class BlkifControllerFactory(controller.SplitControllerFactory):
|
||||
"""Factory for creating block device interface controllers.
|
||||
@@ -230,9 +246,21 @@ class BlkDev(controller.SplitDev):
|
||||
val.append(['uname', self.uname])
|
||||
return val
|
||||
|
||||
def destroy(self):
|
||||
def destroy(self, change=0):
|
||||
"""Destroy the device. If 'change' is true notify the front-end interface.
|
||||
|
||||
@param change: change flag
|
||||
"""
|
||||
log.debug("Destroying vbd domain=%d vdev=%d", self.controller.dom, self.vdev)
|
||||
self.send_be_vbd_destroy()
|
||||
d = self.send_be_vbd_destroy()
|
||||
if change:
|
||||
d.addCallback(lambda val: self.interfaceChanged())
|
||||
|
||||
def interfaceChanged(self):
|
||||
"""Tell the back-end to notify the front-end that a device has been
|
||||
added or removed.
|
||||
"""
|
||||
self.getBackendInterface().interfaceChanged()
|
||||
|
||||
def attach(self):
|
||||
"""Attach the device to its controller.
|
||||
@@ -295,16 +323,16 @@ class BlkDev(controller.SplitDev):
|
||||
% (self.vdev, status))
|
||||
return self
|
||||
|
||||
def send_be_vbd_destroy(self, response=None):
|
||||
log.debug('>BlkDev>send_be_vbd_destroy> dom=%d vdev=%d',
|
||||
self.controller.dom, self.vdev)
|
||||
def send_be_vbd_destroy(self):
|
||||
d = defer.Deferred()
|
||||
backend = self.getBackendInterface()
|
||||
msg = packMsg('blkif_be_vbd_destroy_t',
|
||||
{ 'domid' : self.controller.dom,
|
||||
'blkif_handle' : backend.handle,
|
||||
'vdevice' : self.vdev })
|
||||
self.controller.delDevice(self.vdev)
|
||||
backend.writeRequest(msg, response=response)
|
||||
backend.writeRequest(msg, response=d)
|
||||
return d
|
||||
|
||||
|
||||
class BlkifController(controller.SplitController):
|
||||
@@ -399,13 +427,8 @@ class BlkifController(controller.SplitController):
|
||||
|
||||
def recv_fe_driver_status_changed(self, msg, req):
|
||||
val = unpackMsg('blkif_fe_driver_status_changed_t', msg)
|
||||
# For each backend?
|
||||
msg = packMsg('blkif_fe_interface_status_changed_t',
|
||||
{ 'handle' : 0,
|
||||
'status' : BLKIF_INTERFACE_STATUS_DISCONNECTED,
|
||||
'domid' : 0, ## FIXME: should be domid of backend
|
||||
'evtchn' : 0 })
|
||||
self.writeRequest(msg)
|
||||
for backend in self.getBackendInterfaces():
|
||||
backend.interfaceDisconnected()
|
||||
|
||||
def recv_fe_interface_connect(self, msg, req):
|
||||
val = unpackMsg('blkif_fe_interface_connect_t', msg)
|
||||
|
||||
@@ -50,6 +50,7 @@ BLKIF_DRIVER_STATUS_UP = 1
|
||||
BLKIF_INTERFACE_STATUS_DESTROYED = 0 #/* Interface doesn't exist. */
|
||||
BLKIF_INTERFACE_STATUS_DISCONNECTED = 1 #/* Exists but is disconnected. */
|
||||
BLKIF_INTERFACE_STATUS_CONNECTED = 2 #/* Exists and is connected. */
|
||||
BLKIF_INTERFACE_STATUS_CHANGED = 3 #/* A device has been added or removed. */
|
||||
|
||||
BLKIF_BE_STATUS_OKAY = 0
|
||||
BLKIF_BE_STATUS_ERROR = 1
|
||||
@@ -117,6 +118,7 @@ CMSG_NETIF_BE_DRIVER_STATUS_CHANGED = 32
|
||||
NETIF_INTERFACE_STATUS_DESTROYED = 0 #/* Interface doesn't exist. */
|
||||
NETIF_INTERFACE_STATUS_DISCONNECTED = 1 #/* Exists but is disconnected. */
|
||||
NETIF_INTERFACE_STATUS_CONNECTED = 2 #/* Exists and is connected. */
|
||||
NETIF_INTERFACE_STATUS_CHANGED = 3 #/* A device has been added or removed. */
|
||||
|
||||
NETIF_DRIVER_STATUS_DOWN = 0
|
||||
NETIF_DRIVER_STATUS_UP = 1
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
import random
|
||||
|
||||
from twisted.internet import defer
|
||||
#defer.Deferred.debug = 1
|
||||
|
||||
from xen.xend import sxp
|
||||
from xen.xend import Vifctl
|
||||
@@ -208,13 +207,17 @@ class NetDev(controller.SplitDev):
|
||||
val = unpackMsg('netif_be_create_t', msg)
|
||||
return self
|
||||
|
||||
def destroy(self):
|
||||
def destroy(self, change=0):
|
||||
"""Destroy the device's resources and disconnect from the back-end
|
||||
device controller.
|
||||
device controller. If 'change' is true notify the front-end interface.
|
||||
|
||||
@param change: change flag
|
||||
"""
|
||||
def cb_destroy(val):
|
||||
self.send_be_destroy()
|
||||
self.getBackendInterface().close()
|
||||
if change:
|
||||
self.interfaceChanged()
|
||||
log.debug("Destroying vif domain=%d vif=%d", self.controller.dom, self.vif)
|
||||
self.vifctl('down')
|
||||
d = self.send_be_disconnect()
|
||||
@@ -256,7 +259,7 @@ class NetDev(controller.SplitDev):
|
||||
{ 'handle' : self.vif,
|
||||
'status' : NETIF_INTERFACE_STATUS_CONNECTED,
|
||||
'evtchn' : self.evtchn['port2'],
|
||||
'domid' : 0, ## FIXME: should be domid of backend
|
||||
'domid' : self.backendDomain,
|
||||
'mac' : self.mac })
|
||||
self.controller.writeRequest(msg)
|
||||
|
||||
@@ -265,7 +268,19 @@ class NetDev(controller.SplitDev):
|
||||
{ 'handle' : self.vif,
|
||||
'status' : NETIF_INTERFACE_STATUS_DISCONNECTED,
|
||||
'evtchn' : 0,
|
||||
'domid' : 0, ## FIXME: should be domid of backend
|
||||
'domid' : self.backendDomain,
|
||||
'mac' : self.mac })
|
||||
self.controller.writeRequest(msg)
|
||||
|
||||
def interfaceChanged(self):
|
||||
"""Notify the font-end that a device has been added or removed.
|
||||
The front-end should then probe the devices.
|
||||
"""
|
||||
msg = packMsg('netif_fe_interface_status_changed_t',
|
||||
{ 'handle' : self.vif,
|
||||
'status' : NETIF_INTERFACE_STATUS_CHANGED,
|
||||
'evtchn' : 0,
|
||||
'domid' : self.backendDomain,
|
||||
'mac' : self.mac })
|
||||
self.controller.writeRequest(msg)
|
||||
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
# The following parameters could be placed in a configuration file.
|
||||
PID_FILE = '/var/run/xend.pid'
|
||||
XEND_PID_FILE = '/var/run/xend.pid'
|
||||
XFRD_PID_FILE = '/var/run/xfrd.pid'
|
||||
XEND_TRACE_FILE = '/var/log/xend.trace'
|
||||
|
||||
USER = 'root'
|
||||
CONTROL_DIR = '/var/run/xend'
|
||||
MGMT_SOCK = 'xendsock' # relative to CONTROL_DIR
|
||||
|
||||
EVENT_PORT = 8001
|
||||
|
||||
CONSOLE_PORT_BASE = 9600
|
||||
|
||||
@@ -737,22 +737,26 @@ class ProgVbdCreate(Prog):
|
||||
info = """Create a new virtual block device for a domain"""
|
||||
|
||||
def help(self, args):
|
||||
print args[0], "DOM UNAME DEV MODE"
|
||||
print args[0], "DOM UNAME DEV MODE [BACKEND]"
|
||||
print """
|
||||
Create a virtual block device for a domain.
|
||||
|
||||
UNAME - device to export, e.g. phys:hda2
|
||||
DEV - device name in the domain, e.g. xda1
|
||||
MODE - access mode: r for read, w for read-write
|
||||
UNAME - device to export, e.g. phy:hda2
|
||||
DEV - device name in the domain, e.g. xda1
|
||||
MODE - access mode: r for read, w for read-write
|
||||
BACKEND - backend driver domain
|
||||
"""
|
||||
|
||||
def main(self, args):
|
||||
if len(args) != 5: self.err("%s: Invalid argument(s)" % args[0])
|
||||
n = len(args)
|
||||
if n < 5 or n > 6: self.err("%s: Invalid argument(s)" % args[0])
|
||||
dom = args[1]
|
||||
vbd = ['vbd',
|
||||
['uname', args[2]],
|
||||
['dev', args[3]],
|
||||
['mode', args[4]]]
|
||||
if n == 6:
|
||||
vbd.append(['backend', args[5]])
|
||||
server.xend_domain_device_create(dom, vbd)
|
||||
|
||||
xm.prog(ProgVbdCreate)
|
||||
@@ -766,13 +770,15 @@ class ProgVbdDestroy(Prog):
|
||||
print args[0], "DOM DEV"
|
||||
print """
|
||||
Destroy vbd DEV attached to domain DOM. Detaches the device
|
||||
from the domain, but does not destroy the device contents."""
|
||||
from the domain, but does not destroy the device contents.
|
||||
The device indentifier DEV is the idx field in the device
|
||||
information. This is visible in 'xm vbd-list'."""
|
||||
|
||||
def main(self, args):
|
||||
if len(args!=3): self.err("%s: Invalid argument(s)" % args[0])
|
||||
if len(args) != 3: self.err("%s: Invalid argument(s)" % args[0])
|
||||
dom = args[1]
|
||||
dev = args[2]
|
||||
sever.xend_domain_device_destroy(dom, "vbd", dev)
|
||||
server.xend_domain_device_destroy(dom, "vbd", dev)
|
||||
|
||||
xm.prog(ProgVbdDestroy)
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ typedef unsigned long u32;
|
||||
|
||||
#define MODULE_NAME "XFRD"
|
||||
#define DEBUG 1
|
||||
#undef DEBUG
|
||||
#include "debug.h"
|
||||
|
||||
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
|
||||
#define MODULE_NAME "XFRD"
|
||||
#define DEBUG 0
|
||||
#undef DEBUG
|
||||
#include "debug.h"
|
||||
|
||||
/*
|
||||
@@ -1142,7 +1143,11 @@ int main(int argc, char *argv[]){
|
||||
int err = 0;
|
||||
int key = 0;
|
||||
int long_index = 0;
|
||||
static const char * LOGFILE = "/var/log/xfrd.log";
|
||||
|
||||
freopen(LOGFILE, "w+", stdout);
|
||||
fclose(stderr);
|
||||
stderr = stdout;
|
||||
dprintf(">\n");
|
||||
set_defaults(args);
|
||||
while(1){
|
||||
|
||||
+65
-46
@@ -449,12 +449,68 @@ long do_iopl(domid_t domain, unsigned int new_io_pl)
|
||||
|
||||
#endif
|
||||
|
||||
void domain_relinquish_memory(struct domain *d)
|
||||
|
||||
static void relinquish_list(struct domain *d, struct list_head *list)
|
||||
{
|
||||
struct list_head *ent, *tmp;
|
||||
struct list_head *ent;
|
||||
struct pfn_info *page;
|
||||
unsigned long x, y;
|
||||
|
||||
/* Use a recursive lock, as we may enter 'free_domheap_page'. */
|
||||
spin_lock_recursive(&d->page_alloc_lock);
|
||||
|
||||
ent = list->next;
|
||||
while ( ent != list )
|
||||
{
|
||||
page = list_entry(ent, struct pfn_info, list);
|
||||
|
||||
/* Grab a reference to the page so it won't disappear from under us. */
|
||||
if ( unlikely(!get_page(page, d)) )
|
||||
{
|
||||
/* Couldn't get a reference -- someone is freeing this page. */
|
||||
ent = ent->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( test_and_clear_bit(_PGT_pinned, &page->u.inuse.type_info) )
|
||||
put_page_and_type(page);
|
||||
|
||||
if ( test_and_clear_bit(_PGC_allocated, &page->count_info) )
|
||||
put_page(page);
|
||||
|
||||
/*
|
||||
* Forcibly invalidate base page tables at this point to break circular
|
||||
* 'linear page table' references. This is okay because MMU structures
|
||||
* are not shared across domains and this domain is now dead. Thus base
|
||||
* tables are not in use so a non-zero count means circular reference.
|
||||
*/
|
||||
y = page->u.inuse.type_info;
|
||||
for ( ; ; )
|
||||
{
|
||||
x = y;
|
||||
if ( likely((x & (PGT_type_mask|PGT_validated)) !=
|
||||
(PGT_base_page_table|PGT_validated)) )
|
||||
break;
|
||||
|
||||
y = cmpxchg(&page->u.inuse.type_info, x, x & ~PGT_validated);
|
||||
if ( likely(y == x) )
|
||||
{
|
||||
free_page_type(page, PGT_base_page_table);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Follow the list chain and /then/ potentially free the page. */
|
||||
ent = ent->next;
|
||||
put_page(page);
|
||||
}
|
||||
|
||||
spin_unlock_recursive(&d->page_alloc_lock);
|
||||
}
|
||||
|
||||
|
||||
void domain_relinquish_memory(struct domain *d)
|
||||
{
|
||||
/* Ensure that noone is running over the dead domain's page tables. */
|
||||
synchronise_pagetables(~0UL);
|
||||
|
||||
@@ -472,49 +528,9 @@ void domain_relinquish_memory(struct domain *d)
|
||||
*/
|
||||
destroy_gdt(d);
|
||||
|
||||
/* Use a recursive lock, as we may enter 'free_domheap_page'. */
|
||||
spin_lock_recursive(&d->page_alloc_lock);
|
||||
|
||||
/* Relinquish Xen-heap pages. */
|
||||
list_for_each_safe ( ent, tmp, &d->xenpage_list )
|
||||
{
|
||||
page = list_entry(ent, struct pfn_info, list);
|
||||
|
||||
if ( test_and_clear_bit(_PGC_allocated, &page->count_info) )
|
||||
put_page(page);
|
||||
}
|
||||
|
||||
/* Relinquish all pages on the domain's allocation list. */
|
||||
list_for_each_safe ( ent, tmp, &d->page_list )
|
||||
{
|
||||
page = list_entry(ent, struct pfn_info, list);
|
||||
|
||||
if ( test_and_clear_bit(_PGC_guest_pinned, &page->count_info) )
|
||||
put_page_and_type(page);
|
||||
|
||||
if ( test_and_clear_bit(_PGC_allocated, &page->count_info) )
|
||||
put_page(page);
|
||||
|
||||
/*
|
||||
* Forcibly invalidate base page tables at this point to break circular
|
||||
* 'linear page table' references. This is okay because MMU structures
|
||||
* are not shared across domains and this domain is now dead. Thus base
|
||||
* tables are not in use so a non-zero count means circular reference.
|
||||
*/
|
||||
y = page->u.inuse.type_info;
|
||||
do {
|
||||
x = y;
|
||||
if ( likely((x & (PGT_type_mask|PGT_validated)) !=
|
||||
(PGT_base_page_table|PGT_validated)) )
|
||||
break;
|
||||
y = cmpxchg(&page->u.inuse.type_info, x, x & ~PGT_validated);
|
||||
if ( likely(y == x) )
|
||||
free_page_type(page, PGT_base_page_table);
|
||||
}
|
||||
while ( unlikely(y != x) );
|
||||
}
|
||||
|
||||
spin_unlock_recursive(&d->page_alloc_lock);
|
||||
/* Relinquish every page of memory. */
|
||||
relinquish_list(d, &d->xenpage_list);
|
||||
relinquish_list(d, &d->page_list);
|
||||
}
|
||||
|
||||
|
||||
@@ -739,12 +755,15 @@ int construct_dom0(struct domain *p,
|
||||
/* Get another ref to L2 page so that it can be pinned. */
|
||||
if ( !get_page_and_type(page, p, PGT_l2_page_table) )
|
||||
BUG();
|
||||
set_bit(_PGC_guest_pinned, &page->count_info);
|
||||
set_bit(_PGT_pinned, &page->u.inuse.type_info);
|
||||
}
|
||||
else
|
||||
{
|
||||
page->u.inuse.type_info &= ~PGT_type_mask;
|
||||
page->u.inuse.type_info |= PGT_l1_page_table;
|
||||
page->u.inuse.type_info |=
|
||||
((v_start>>L2_PAGETABLE_SHIFT)+(count-1))<<PGT_va_shift;
|
||||
|
||||
get_page(page, p); /* an extra ref because of readable mapping */
|
||||
}
|
||||
l1tab++;
|
||||
|
||||
+69
-75
@@ -142,8 +142,6 @@ static struct domain *dom_xen, *dom_io;
|
||||
|
||||
void arch_init_memory(void)
|
||||
{
|
||||
static void ptwr_init_backpointers(void);
|
||||
static void ptwr_disable(void);
|
||||
unsigned long mfn;
|
||||
|
||||
/*
|
||||
@@ -165,10 +163,15 @@ void arch_init_memory(void)
|
||||
|
||||
memset(percpu_info, 0, sizeof(percpu_info));
|
||||
|
||||
/* XXXX WRITEABLE PAGETABLES SHOULD BE A DOMAIN CREATION-TIME
|
||||
DECISION, NOT SOMETHING THAT IS CHANGED ON A RUNNING DOMAIN
|
||||
!!! FIX ME !!!!
|
||||
*/
|
||||
|
||||
vm_assist_info[VMASST_TYPE_writable_pagetables].enable =
|
||||
ptwr_init_backpointers;
|
||||
NULL;
|
||||
vm_assist_info[VMASST_TYPE_writable_pagetables].disable =
|
||||
ptwr_disable;
|
||||
NULL;
|
||||
|
||||
for ( mfn = 0; mfn < max_page; mfn++ )
|
||||
frame_table[mfn].count_info |= PGC_always_set;
|
||||
@@ -322,17 +325,6 @@ static int get_page_and_type_from_pagenr(unsigned long page_nr,
|
||||
}
|
||||
|
||||
|
||||
static inline void set_l1_page_va(unsigned long pfn,
|
||||
unsigned long va_idx)
|
||||
{
|
||||
struct pfn_info *page;
|
||||
|
||||
page = &frame_table[pfn];
|
||||
page->u.inuse.type_info &= ~PGT_va_mask;
|
||||
page->u.inuse.type_info |= va_idx << PGT_va_shift;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* We allow an L2 tables to map each other (a.k.a. linear page tables). It
|
||||
* needs some special care with reference counst and access permissions:
|
||||
@@ -466,8 +458,11 @@ get_page_from_l1e(
|
||||
/* NB. Virtual address 'l2e' maps to a machine address within frame 'pfn'. */
|
||||
static int
|
||||
get_page_from_l2e(
|
||||
l2_pgentry_t l2e, unsigned long pfn, struct domain *d)
|
||||
l2_pgentry_t l2e, unsigned long pfn,
|
||||
struct domain *d, unsigned long va_idx)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if ( !(l2_pgentry_val(l2e) & _PAGE_PRESENT) )
|
||||
return 1;
|
||||
|
||||
@@ -478,8 +473,11 @@ get_page_from_l2e(
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( unlikely(!get_page_and_type_from_pagenr(
|
||||
l2_pgentry_to_pagenr(l2e), PGT_l1_page_table, d)) )
|
||||
rc = get_page_and_type_from_pagenr(
|
||||
l2_pgentry_to_pagenr(l2e),
|
||||
PGT_l1_page_table | (va_idx<<PGT_va_shift), d);
|
||||
|
||||
if ( unlikely(!rc) )
|
||||
return get_linear_pagetable(l2e, pfn, d);
|
||||
|
||||
return 1;
|
||||
@@ -553,9 +551,8 @@ static int alloc_l2_table(struct pfn_info *page)
|
||||
pl2e = map_domain_mem(page_nr << PAGE_SHIFT);
|
||||
|
||||
for ( i = 0; i < DOMAIN_ENTRIES_PER_L2_PAGETABLE; i++ ) {
|
||||
if ( unlikely(!get_page_from_l2e(pl2e[i], page_nr, d)) )
|
||||
if ( unlikely(!get_page_from_l2e(pl2e[i], page_nr, d, i)) )
|
||||
goto fail;
|
||||
set_l1_page_va(l2_pgentry_val(pl2e[i]) >> PAGE_SHIFT, i);
|
||||
}
|
||||
|
||||
#if defined(__i386__)
|
||||
@@ -677,11 +674,10 @@ static int mod_l2_entry(l2_pgentry_t *pl2e,
|
||||
if ( ((l2_pgentry_val(ol2e) ^ l2_pgentry_val(nl2e)) & ~0xffe) == 0 )
|
||||
return update_l2e(pl2e, ol2e, nl2e);
|
||||
|
||||
if ( unlikely(!get_page_from_l2e(nl2e, pfn, current)) )
|
||||
if ( unlikely(!get_page_from_l2e(nl2e, pfn, current,
|
||||
((unsigned long)pl2e &
|
||||
~PAGE_MASK) >> 2)) )
|
||||
return 0;
|
||||
|
||||
set_l1_page_va(l2_pgentry_val(nl2e) >> PAGE_SHIFT,
|
||||
((unsigned long)pl2e & (PAGE_SIZE-1)) >> 2);
|
||||
|
||||
if ( unlikely(!update_l2e(pl2e, ol2e, nl2e)) )
|
||||
{
|
||||
@@ -836,10 +832,17 @@ static int do_extended_command(unsigned long ptr, unsigned long val)
|
||||
{
|
||||
case MMUEXT_PIN_L1_TABLE:
|
||||
case MMUEXT_PIN_L2_TABLE:
|
||||
/*
|
||||
* We insist that, if you pin an L1 page, it's the first thing that
|
||||
* you do to it. This is because we require the backptr to still be
|
||||
* mutable. This assumption seems safe.
|
||||
*/
|
||||
okay = get_page_and_type_from_pagenr(
|
||||
pfn,
|
||||
(cmd==MMUEXT_PIN_L2_TABLE) ? PGT_l2_page_table : PGT_l1_page_table,
|
||||
((cmd==MMUEXT_PIN_L2_TABLE) ?
|
||||
PGT_l2_page_table : (PGT_l1_page_table|PGT_va_mutable)),
|
||||
FOREIGNDOM);
|
||||
|
||||
if ( unlikely(!okay) )
|
||||
{
|
||||
MEM_LOG("Error while pinning pfn %08lx", pfn);
|
||||
@@ -847,8 +850,8 @@ static int do_extended_command(unsigned long ptr, unsigned long val)
|
||||
break;
|
||||
}
|
||||
|
||||
if ( unlikely(test_and_set_bit(_PGC_guest_pinned,
|
||||
&page->count_info)) )
|
||||
if ( unlikely(test_and_set_bit(_PGT_pinned,
|
||||
&page->u.inuse.type_info)) )
|
||||
{
|
||||
MEM_LOG("Pfn %08lx already pinned", pfn);
|
||||
put_page_and_type(page);
|
||||
@@ -864,8 +867,8 @@ static int do_extended_command(unsigned long ptr, unsigned long val)
|
||||
MEM_LOG("Page %08lx bad domain (dom=%p)",
|
||||
ptr, page->u.inuse.domain);
|
||||
}
|
||||
else if ( likely(test_and_clear_bit(_PGC_guest_pinned,
|
||||
&page->count_info)) )
|
||||
else if ( likely(test_and_clear_bit(_PGT_pinned,
|
||||
&page->u.inuse.type_info)) )
|
||||
{
|
||||
put_page_and_type(page);
|
||||
put_page(page);
|
||||
@@ -897,8 +900,7 @@ static int do_extended_command(unsigned long ptr, unsigned long val)
|
||||
/*
|
||||
* Note that we tick the clock /after/ dropping the old base's
|
||||
* reference count. If the page tables got freed then this will
|
||||
* avoid unnecessary TLB flushes when the pages are reused.
|
||||
*/
|
||||
* avoid unnecessary TLB flushes when the pages are reused. */
|
||||
tlb_clocktick();
|
||||
}
|
||||
else
|
||||
@@ -915,6 +917,18 @@ static int do_extended_command(unsigned long ptr, unsigned long val)
|
||||
__flush_tlb_one(ptr);
|
||||
break;
|
||||
|
||||
case MMUEXT_FLUSH_CACHE:
|
||||
if ( unlikely(!IS_CAPABLE_PHYSDEV(d)) )
|
||||
{
|
||||
MEM_LOG("Non-physdev domain tried to FLUSH_CACHE.\n");
|
||||
okay = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
wbinvd();
|
||||
}
|
||||
break;
|
||||
|
||||
case MMUEXT_SET_LDT:
|
||||
{
|
||||
unsigned long ents = val >> MMUEXT_CMD_SHIFT;
|
||||
@@ -1040,13 +1054,18 @@ static int do_extended_command(unsigned long ptr, unsigned long val)
|
||||
|
||||
spin_lock(&e->page_alloc_lock);
|
||||
|
||||
/* Check that 'e' will accept the page and has reservation headroom. */
|
||||
/*
|
||||
* Check that 'e' will accept the page and has reservation headroom.
|
||||
* Also, a domain mustn't have PGC_allocated pages when it is dying.
|
||||
*/
|
||||
ASSERT(e->tot_pages <= e->max_pages);
|
||||
if ( unlikely(e->tot_pages == e->max_pages) ||
|
||||
if ( unlikely(test_bit(DF_DYING, &e->flags)) ||
|
||||
unlikely(e->tot_pages == e->max_pages) ||
|
||||
unlikely(!gnttab_prepare_for_transfer(e, d, gntref)) )
|
||||
{
|
||||
MEM_LOG("Transferee has no reservation headroom (%d,%d), or "
|
||||
"provided a bad grant ref.\n", e->tot_pages, e->max_pages);
|
||||
"provided a bad grant ref, or is dying (%08lx).\n",
|
||||
e->tot_pages, e->max_pages, e->flags);
|
||||
spin_unlock(&e->page_alloc_lock);
|
||||
put_domain(e);
|
||||
okay = 0;
|
||||
@@ -1182,6 +1201,7 @@ int do_mmu_update(mmu_update_t *ureqs, int count, int *success_count)
|
||||
unsigned long prev_spfn = 0;
|
||||
l1_pgentry_t *prev_spl1e = 0;
|
||||
struct domain *d = current;
|
||||
u32 type_info;
|
||||
|
||||
perfc_incrc(calls_to_mmu_update);
|
||||
perfc_addc(num_page_updates, count);
|
||||
@@ -1230,10 +1250,11 @@ int do_mmu_update(mmu_update_t *ureqs, int count, int *success_count)
|
||||
}
|
||||
|
||||
page = &frame_table[pfn];
|
||||
switch ( (page->u.inuse.type_info & PGT_type_mask) )
|
||||
switch ( (type_info = page->u.inuse.type_info) & PGT_type_mask )
|
||||
{
|
||||
case PGT_l1_page_table:
|
||||
if ( likely(get_page_type(page, PGT_l1_page_table)) )
|
||||
if ( likely(get_page_type(
|
||||
page, type_info & (PGT_type_mask|PGT_va_mask))) )
|
||||
{
|
||||
okay = mod_l1_entry((l1_pgentry_t *)va,
|
||||
mk_l1_pgentry(req.val));
|
||||
@@ -1483,11 +1504,11 @@ void ptwr_reconnect_disconnected(unsigned long addr)
|
||||
[ptwr_info[cpu].writable_l1>>PAGE_SHIFT];
|
||||
|
||||
#ifdef PTWR_TRACK_DOMAIN
|
||||
if (ptwr_domain[cpu] != get_current()->domain)
|
||||
if (ptwr_domain[cpu] != current->domain)
|
||||
printk("ptwr_reconnect_disconnected domain mismatch %d != %d\n",
|
||||
ptwr_domain[cpu], get_current()->domain);
|
||||
ptwr_domain[cpu], current->domain);
|
||||
#endif
|
||||
PTWR_PRINTK(("[A] page fault in disconnected space: addr %08lx space %08lx\n",
|
||||
PTWR_PRINTK(("[A] page fault in disconn space: addr %08lx space %08lx\n",
|
||||
addr, ptwr_info[cpu].disconnected << L2_PAGETABLE_SHIFT));
|
||||
pl2e = &linear_l2_table[ptwr_info[cpu].disconnected];
|
||||
|
||||
@@ -1559,9 +1580,9 @@ void ptwr_flush_inactive(void)
|
||||
int i, idx;
|
||||
|
||||
#ifdef PTWR_TRACK_DOMAIN
|
||||
if (ptwr_info[cpu].domain != get_current()->domain)
|
||||
if (ptwr_info[cpu].domain != current->domain)
|
||||
printk("ptwr_flush_inactive domain mismatch %d != %d\n",
|
||||
ptwr_info[cpu].domain, get_current()->domain);
|
||||
ptwr_info[cpu].domain, current->domain);
|
||||
#endif
|
||||
#if 0
|
||||
{
|
||||
@@ -1626,9 +1647,11 @@ int ptwr_do_page_fault(unsigned long addr)
|
||||
PTWR_PRINTK(("get user %p for va %08lx\n",
|
||||
&linear_pg_table[addr>>PAGE_SHIFT], addr));
|
||||
#endif
|
||||
|
||||
/* Testing for page_present in the L2 avoids lots of unncessary fixups */
|
||||
if ( (l2_pgentry_val(linear_l2_table[addr >> L2_PAGETABLE_SHIFT]) &
|
||||
_PAGE_PRESENT) &&
|
||||
(__get_user(pte, (unsigned long *)
|
||||
_PAGE_PRESENT) &&
|
||||
(__get_user(pte, (unsigned long *)
|
||||
&linear_pg_table[addr >> PAGE_SHIFT]) == 0) )
|
||||
{
|
||||
pfn = pte >> PAGE_SHIFT;
|
||||
@@ -1640,9 +1663,9 @@ int ptwr_do_page_fault(unsigned long addr)
|
||||
if ( (page->u.inuse.type_info & PGT_type_mask) == PGT_l1_page_table )
|
||||
{
|
||||
#ifdef PTWR_TRACK_DOMAIN
|
||||
if ( ptwr_info[cpu].domain != get_current()->domain )
|
||||
if ( ptwr_info[cpu].domain != current->domain )
|
||||
printk("ptwr_do_page_fault domain mismatch %d != %d\n",
|
||||
ptwr_info[cpu].domain, get_current()->domain);
|
||||
ptwr_info[cpu].domain, current->domain);
|
||||
#endif
|
||||
pl2e = &linear_l2_table[(page->u.inuse.type_info &
|
||||
PGT_va_mask) >> PGT_va_shift];
|
||||
@@ -1653,6 +1676,7 @@ int ptwr_do_page_fault(unsigned long addr)
|
||||
|
||||
if ( l2_pgentry_val(*pl2e) >> PAGE_SHIFT != pfn )
|
||||
{
|
||||
/* this L1 is not in the current address space */
|
||||
l1_pgentry_t *pl1e;
|
||||
PTWR_PRINTK(("[I] freeing l1 page %p taf %08x/%08x\n", page,
|
||||
page->u.inuse.type_info,
|
||||
@@ -1718,36 +1742,6 @@ int ptwr_do_page_fault(unsigned long addr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ptwr_init_backpointers(void)
|
||||
{
|
||||
struct pfn_info *page;
|
||||
unsigned long pde;
|
||||
int va_idx;
|
||||
|
||||
for ( va_idx = 0; va_idx < DOMAIN_ENTRIES_PER_L2_PAGETABLE; va_idx++ )
|
||||
{
|
||||
/* check if entry valid */
|
||||
pde = l2_pgentry_val(linear_l2_table[va_idx]);
|
||||
if ( (pde & _PAGE_PRESENT) == 0 )
|
||||
continue;
|
||||
|
||||
page = &frame_table[pde >> PAGE_SHIFT];
|
||||
/* assert that page is an l1_page_table XXXcl maybe l2? */
|
||||
if ( (page->u.inuse.type_info & PGT_type_mask) != PGT_l1_page_table ) {
|
||||
MEM_LOG("ptwr: Inconsistent pagetable: pde %lx not an l1 page\n",
|
||||
pde >> PAGE_SHIFT);
|
||||
domain_crash();
|
||||
}
|
||||
page->u.inuse.type_info &= ~PGT_va_mask;
|
||||
page->u.inuse.type_info |= va_idx << PGT_va_shift;
|
||||
}
|
||||
}
|
||||
|
||||
static void ptwr_disable(void)
|
||||
{
|
||||
__cleanup_writable_pagetable(PTWR_CLEANUP_ACTIVE | PTWR_CLEANUP_INACTIVE);
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
void ptwr_status(void)
|
||||
{
|
||||
|
||||
@@ -262,7 +262,7 @@ void __shadow_mode_disable(struct domain *d)
|
||||
__free_shadow_table(m);
|
||||
m->shadow_mode = 0;
|
||||
|
||||
SH_LOG("freed tables count=%d l1=%d l2=%d",
|
||||
SH_VLOG("freed tables count=%d l1=%d l2=%d",
|
||||
m->shadow_page_count, perfc_value(shadow_l1_pages),
|
||||
perfc_value(shadow_l2_pages));
|
||||
|
||||
|
||||
@@ -330,9 +330,9 @@ asmlinkage void do_page_fault(struct pt_regs *regs, long error_code)
|
||||
return; /* successfully copied the mapping */
|
||||
}
|
||||
|
||||
if ( unlikely(VM_ASSIST(d, VMASST_TYPE_writable_pagetables)) )
|
||||
if ( likely(VM_ASSIST(d, VMASST_TYPE_writable_pagetables)) )
|
||||
{
|
||||
if ( (addr >> L2_PAGETABLE_SHIFT) == ptwr_info[cpu].disconnected )
|
||||
if ( unlikely((addr >> L2_PAGETABLE_SHIFT) == ptwr_info[cpu].disconnected ))
|
||||
{
|
||||
ptwr_reconnect_disconnected(addr);
|
||||
return;
|
||||
|
||||
@@ -628,7 +628,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
|
||||
break;
|
||||
}
|
||||
|
||||
if ( page->count_info & PGC_guest_pinned )
|
||||
if ( page->u.inuse.type_info & PGT_pinned )
|
||||
type |= LPINTAB;
|
||||
l_arr[j] |= type;
|
||||
put_page(page);
|
||||
|
||||
@@ -82,7 +82,7 @@ static long free_dom_mem(struct domain *d,
|
||||
return i;
|
||||
}
|
||||
|
||||
if ( test_and_clear_bit(_PGC_guest_pinned, &page->count_info) )
|
||||
if ( test_and_clear_bit(_PGT_pinned, &page->u.inuse.type_info) )
|
||||
put_page_and_type(page);
|
||||
|
||||
if ( test_and_clear_bit(_PGC_allocated, &page->count_info) )
|
||||
|
||||
+3
-3
@@ -65,7 +65,7 @@ struct domain *do_createdomain(domid_t dom_id, unsigned int cpu)
|
||||
strncpy(d->name, buf, MAX_DOMAIN_NAME);
|
||||
d->name[MAX_DOMAIN_NAME-1] = '\0';
|
||||
|
||||
arch_do_createdomain(d);
|
||||
arch_do_createdomain(d);
|
||||
|
||||
sched_add_domain(d);
|
||||
|
||||
@@ -152,8 +152,8 @@ void domain_crash(void)
|
||||
{
|
||||
struct domain *d;
|
||||
|
||||
if (current->domain == 0)
|
||||
BUG();
|
||||
if ( current->domain == 0 )
|
||||
BUG();
|
||||
|
||||
set_bit(DF_CRASHED, ¤t->flags);
|
||||
|
||||
|
||||
@@ -393,10 +393,13 @@ struct pfn_info *alloc_domheap_pages(struct domain *d, int order)
|
||||
|
||||
spin_lock(&d->page_alloc_lock);
|
||||
|
||||
if ( unlikely((d->tot_pages + (1 << order)) > d->max_pages) )
|
||||
if ( unlikely(test_bit(DF_DYING, &d->flags)) ||
|
||||
unlikely((d->tot_pages + (1 << order)) > d->max_pages) )
|
||||
{
|
||||
DPRINTK("Over-allocation for domain %u: %u > %u\n",
|
||||
d->domain, d->tot_pages + (1 << order), d->max_pages);
|
||||
DPRINTK("...or the domain is dying (%d)\n",
|
||||
!!test_bit(DF_DYING, &d->flags));
|
||||
spin_unlock(&d->page_alloc_lock);
|
||||
free_heap_pages(MEMZONE_DOM, pg, order);
|
||||
return NULL;
|
||||
@@ -427,6 +430,7 @@ void free_domheap_pages(struct pfn_info *pg, int order)
|
||||
|
||||
if ( unlikely(IS_XEN_HEAP_FRAME(pg)) )
|
||||
{
|
||||
/* NB. May recursively lock from domain_relinquish_memory(). */
|
||||
spin_lock_recursive(&d->page_alloc_lock);
|
||||
|
||||
for ( i = 0; i < (1 << order); i++ )
|
||||
|
||||
@@ -374,20 +374,6 @@ void __enter_scheduler(void)
|
||||
cleanup_writable_pagetable(
|
||||
prev, PTWR_CLEANUP_ACTIVE | PTWR_CLEANUP_INACTIVE);
|
||||
|
||||
#ifdef PTWR_TRACK_DOMAIN
|
||||
{
|
||||
extern domid_t ptwr_domain[];
|
||||
int cpu = smp_processor_id();
|
||||
if (ptwr_domain[cpu] != prev->domain)
|
||||
printk("switch_to domain mismatch %d != %d\n",
|
||||
ptwr_domain[cpu], prev->domain);
|
||||
ptwr_domain[cpu] = next->domain;
|
||||
if (ptwr_disconnected[cpu] != ENTRIES_PER_L2_PAGETABLE ||
|
||||
ptwr_writable_idx[cpu])
|
||||
printk("switch_to ptwr dirty!!!\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
perfc_incrc(sched_ctx);
|
||||
|
||||
#if defined(WAKE_HISTO)
|
||||
|
||||
+46
-22
@@ -71,26 +71,27 @@ struct pfn_info
|
||||
/* Has this page been validated for use as its current type? */
|
||||
#define _PGT_validated 28
|
||||
#define PGT_validated (1<<_PGT_validated)
|
||||
/* 10-bit most significant bits of va address if used as l1 page table */
|
||||
#define PGT_va_shift 18
|
||||
/* Owning guest has pinned this page to its current type? */
|
||||
#define _PGT_pinned 27
|
||||
#define PGT_pinned (1<<_PGT_pinned)
|
||||
/* The 10 most significant bits of virt address if this is a page table. */
|
||||
#define PGT_va_shift 17
|
||||
#define PGT_va_mask (((1<<10)-1)<<PGT_va_shift)
|
||||
/* 18-bit count of uses of this frame as its current type. */
|
||||
#define PGT_count_mask ((1<<18)-1)
|
||||
#define PGT_va_mutable PGT_va_mask /* va backpointer is mutable? */
|
||||
/* 17-bit count of uses of this frame as its current type. */
|
||||
#define PGT_count_mask ((1<<17)-1)
|
||||
|
||||
/* For safety, force a TLB flush when this page's type changes. */
|
||||
#define _PGC_tlb_flush_on_type_change 31
|
||||
#define PGC_tlb_flush_on_type_change (1<<_PGC_tlb_flush_on_type_change)
|
||||
/* Owning guest has pinned this page to its current type? */
|
||||
#define _PGC_guest_pinned 30
|
||||
#define PGC_guest_pinned (1<<_PGC_guest_pinned)
|
||||
/* Cleared when the owning guest 'frees' this page. */
|
||||
#define _PGC_allocated 29
|
||||
#define _PGC_allocated 30
|
||||
#define PGC_allocated (1<<_PGC_allocated)
|
||||
/* This bit is always set, guaranteeing that the count word is never zero. */
|
||||
#define _PGC_always_set 28
|
||||
#define _PGC_always_set 29
|
||||
#define PGC_always_set (1<<_PGC_always_set)
|
||||
/* 27-bit count of references to this frame. */
|
||||
#define PGC_count_mask ((1<<28)-1)
|
||||
/* 29-bit count of references to this frame. */
|
||||
#define PGC_count_mask ((1<<29)-1)
|
||||
|
||||
/* We trust the slab allocator in slab.c, and our use of it. */
|
||||
#define PageSlab(page) (1)
|
||||
@@ -198,6 +199,12 @@ static inline void put_page_type(struct pfn_info *page)
|
||||
nx &= ~PGT_validated;
|
||||
}
|
||||
}
|
||||
else if ( unlikely((nx & (PGT_pinned | PGT_count_mask)) ==
|
||||
(PGT_pinned | 1)) )
|
||||
{
|
||||
/* Page is now only pinned. Make the back pointer mutable again. */
|
||||
nx |= PGT_va_mutable;
|
||||
}
|
||||
}
|
||||
while ( unlikely((y = cmpxchg(&page->u.inuse.type_info, x, nx)) != x) );
|
||||
}
|
||||
@@ -217,29 +224,45 @@ static inline int get_page_type(struct pfn_info *page, u32 type)
|
||||
}
|
||||
else if ( unlikely((x & PGT_count_mask) == 0) )
|
||||
{
|
||||
if ( (x & PGT_type_mask) != type )
|
||||
if ( (x & (PGT_type_mask|PGT_va_mask)) != type )
|
||||
{
|
||||
nx &= ~(PGT_type_mask | PGT_validated);
|
||||
nx &= ~(PGT_type_mask | PGT_va_mask | PGT_validated);
|
||||
nx |= type;
|
||||
/* No extra validation needed for writable pages. */
|
||||
if ( type == PGT_writable_page )
|
||||
nx |= PGT_validated;
|
||||
}
|
||||
}
|
||||
else if ( unlikely((x & PGT_type_mask) != type) )
|
||||
else if ( unlikely((x & (PGT_type_mask|PGT_va_mask)) != type) )
|
||||
{
|
||||
if ( unlikely((x & PGT_type_mask) != (type & PGT_type_mask) ) )
|
||||
{
|
||||
#ifdef VERBOSE
|
||||
if ((x & PGT_type_mask) != PGT_l2_page_table &&
|
||||
type != PGT_l1_page_table)
|
||||
DPRINTK("Unexpected type (saw %08x != exp %08x) for pfn %08lx\n",
|
||||
x & PGT_type_mask, type, page_to_pfn(page));
|
||||
if ( ((x & PGT_type_mask) != PGT_l2_page_table) ||
|
||||
((type & PGT_type_mask) != PGT_l1_page_table) )
|
||||
DPRINTK("Bad type (saw %08x != exp %08x) for pfn %08lx\n",
|
||||
x & PGT_type_mask, type, page_to_pfn(page));
|
||||
#endif
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
else if ( (x & PGT_va_mask) == PGT_va_mutable )
|
||||
{
|
||||
/* The va backpointer is mutable, hence we update it. */
|
||||
nx &= ~PGT_va_mask;
|
||||
nx |= type; /* we know the actual type is correct */
|
||||
}
|
||||
else if ( unlikely((x & PGT_va_mask) != (type & PGT_va_mask)) )
|
||||
{
|
||||
/* The va backpointer wasn't mutable, and is different. */
|
||||
DPRINTK("Unexpected va backpointer (saw %08x != exp %08x)"
|
||||
" for pfn %08lx\n", x, type, page_to_pfn(page));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if ( unlikely(!(x & PGT_validated)) )
|
||||
else if ( unlikely(!(x & PGT_validated)) )
|
||||
{
|
||||
/* Someone else is updating validation of this page. Wait... */
|
||||
while ( (y = page->u.inuse.type_info) != x )
|
||||
while ( (y = page->u.inuse.type_info) == x )
|
||||
{
|
||||
rep_nop();
|
||||
barrier();
|
||||
@@ -252,7 +275,7 @@ static inline int get_page_type(struct pfn_info *page, u32 type)
|
||||
if ( unlikely(!(nx & PGT_validated)) )
|
||||
{
|
||||
/* Try to validate page type; drop the new reference on failure. */
|
||||
if ( unlikely(!alloc_page_type(page, type)) )
|
||||
if ( unlikely(!alloc_page_type(page, type & PGT_type_mask)) )
|
||||
{
|
||||
DPRINTK("Error while validating pfn %08lx for type %08x."
|
||||
" caf=%08x taf=%08x\n",
|
||||
@@ -262,6 +285,7 @@ static inline int get_page_type(struct pfn_info *page, u32 type)
|
||||
put_page_type(page);
|
||||
return 0;
|
||||
}
|
||||
|
||||
set_bit(_PGT_validated, &page->u.inuse.type_info);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
* This makes sure that old versions of dom0 tools will stop working in a
|
||||
* well-defined way (rather than crashing the machine, for instance).
|
||||
*/
|
||||
#define DOM0_INTERFACE_VERSION 0xAAAA0012
|
||||
#define DOM0_INTERFACE_VERSION 0xAAAA0014
|
||||
|
||||
#define MAX_DOMAIN_NAME 16
|
||||
|
||||
|
||||
@@ -117,6 +117,9 @@
|
||||
* val[7:0] == MMUEXT_INVLPG:
|
||||
* ptr[:2] -- Linear address to be flushed from the TLB.
|
||||
*
|
||||
* val[7:0] == MMUEXT_FLUSH_CACHE:
|
||||
* No additional arguments. Writes back and flushes cache contents.
|
||||
*
|
||||
* val[7:0] == MMUEXT_SET_LDT:
|
||||
* ptr[:2] -- Linear address of LDT base (NB. must be page-aligned).
|
||||
* val[:8] -- Number of entries in LDT.
|
||||
@@ -150,11 +153,12 @@
|
||||
#define MMUEXT_NEW_BASEPTR 5 /* ptr = MA of new pagetable base */
|
||||
#define MMUEXT_TLB_FLUSH 6 /* ptr = NULL */
|
||||
#define MMUEXT_INVLPG 7 /* ptr = VA to invalidate */
|
||||
#define MMUEXT_SET_LDT 8 /* ptr = VA of table; val = # entries */
|
||||
#define MMUEXT_TRANSFER_PAGE 9 /* ptr = MA of frame; val[31:16] = dom */
|
||||
#define MMUEXT_FLUSH_CACHE 8
|
||||
#define MMUEXT_SET_LDT 9 /* ptr = VA of table; val = # entries */
|
||||
#define MMUEXT_SET_FOREIGNDOM 10 /* val[31:16] = dom */
|
||||
#define MMUEXT_CLEAR_FOREIGNDOM 11
|
||||
#define MMUEXT_REASSIGN_PAGE 12
|
||||
#define MMUEXT_TRANSFER_PAGE 12 /* ptr = MA of frame; val[31:16] = dom */
|
||||
#define MMUEXT_REASSIGN_PAGE 13
|
||||
#define MMUEXT_CMD_MASK 255
|
||||
#define MMUEXT_CMD_SHIFT 8
|
||||
|
||||
|
||||
@@ -93,6 +93,7 @@ typedef struct {
|
||||
#define BLKIF_INTERFACE_STATUS_DESTROYED 0 /* Interface doesn't exist. */
|
||||
#define BLKIF_INTERFACE_STATUS_DISCONNECTED 1 /* Exists but is disconnected. */
|
||||
#define BLKIF_INTERFACE_STATUS_CONNECTED 2 /* Exists and is connected. */
|
||||
#define BLKIF_INTERFACE_STATUS_CHANGED 3 /* A device has been added or removed. */
|
||||
typedef struct {
|
||||
u32 handle; /* 0 */
|
||||
u32 status; /* 4 */
|
||||
@@ -357,6 +358,7 @@ typedef struct {
|
||||
#define NETIF_INTERFACE_STATUS_DESTROYED 0 /* Interface doesn't exist. */
|
||||
#define NETIF_INTERFACE_STATUS_DISCONNECTED 1 /* Exists but is disconnected. */
|
||||
#define NETIF_INTERFACE_STATUS_CONNECTED 2 /* Exists and is connected. */
|
||||
#define NETIF_INTERFACE_STATUS_CHANGED 3 /* A device has been added or removed. */
|
||||
typedef struct {
|
||||
u32 handle; /* 0 */
|
||||
u32 status; /* 4 */
|
||||
|
||||