This commit is contained in:
cl349@firebug.cl.cam.ac.uk committed 2005-08-23 17:33:11 +00:00
commit ae28fe8a0e
26 files changed
+246 -593

No files matched your search

+1
View File
@@ -147,6 +147,7 @@
^tools/xcs/xcsdump$
^tools/xcutils/xc_restore$
^tools/xcutils/xc_save$
^tools/xenstat/xentop/xentop$
^tools/xenstore/testsuite/tmp/.*$
^tools/xenstore/xen$
^tools/xenstore/xenstored$
@@ -807,7 +807,107 @@ CONFIG_DUMMY_CONSOLE=y
#
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
# CONFIG_USB is not set
CONFIG_USB=y
# CONFIG_USB_DEBUG is not set
#
# Miscellaneous USB options
#
# CONFIG_USB_DEVICEFS is not set
# CONFIG_USB_BANDWIDTH is not set
# CONFIG_USB_DYNAMIC_MINORS is not set
# CONFIG_USB_OTG is not set
#
# USB Host Controller Drivers
#
# CONFIG_USB_EHCI_HCD is not set
CONFIG_USB_OHCI_HCD=y
# CONFIG_USB_OHCI_BIG_ENDIAN is not set
CONFIG_USB_OHCI_LITTLE_ENDIAN=y
CONFIG_USB_UHCI_HCD=y
# CONFIG_USB_SL811_HCD is not set
#
# USB Device Class drivers
#
# CONFIG_USB_BLUETOOTH_TTY is not set
# CONFIG_USB_ACM is not set
# CONFIG_USB_PRINTER is not set
#
# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
#
# CONFIG_USB_STORAGE is not set
#
# USB Input Devices
#
CONFIG_USB_HID=y
CONFIG_USB_HIDINPUT=y
# CONFIG_HID_FF is not set
# CONFIG_USB_HIDDEV is not set
# CONFIG_USB_AIPTEK is not set
# CONFIG_USB_WACOM is not set
# CONFIG_USB_KBTAB is not set
# CONFIG_USB_POWERMATE is not set
# CONFIG_USB_MTOUCH is not set
# CONFIG_USB_EGALAX is not set
# CONFIG_USB_XPAD is not set
# CONFIG_USB_ATI_REMOTE is not set
#
# USB Imaging devices
#
# CONFIG_USB_MDC800 is not set
# CONFIG_USB_MICROTEK is not set
#
# USB Multimedia devices
#
# CONFIG_USB_DABUSB is not set
#
# Video4Linux support is needed for USB Multimedia device support
#
#
# USB Network Adapters
#
# CONFIG_USB_CATC is not set
# CONFIG_USB_KAWETH is not set
# CONFIG_USB_PEGASUS is not set
# CONFIG_USB_RTL8150 is not set
# CONFIG_USB_USBNET is not set
CONFIG_USB_MON=y
#
# USB port drivers
#
#
# USB Serial Converter support
#
# CONFIG_USB_SERIAL is not set
#
# USB Miscellaneous drivers
#
# CONFIG_USB_EMI62 is not set
# CONFIG_USB_EMI26 is not set
# CONFIG_USB_AUERSWALD is not set
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_LCD is not set
# CONFIG_USB_LED is not set
# CONFIG_USB_CYTHERM is not set
# CONFIG_USB_PHIDGETKIT is not set
# CONFIG_USB_PHIDGETSERVO is not set
# CONFIG_USB_IDMOUSE is not set
#
# USB ATM/DSL drivers
#
#
# USB Gadget Support
@@ -1575,19 +1575,20 @@ void __init setup_arch(char **cmdline_p)
/* Make sure we have a correctly sized P->M table. */
if (max_pfn != xen_start_info.nr_pages) {
phys_to_machine_mapping = alloc_bootmem_low_pages(
max_pfn * sizeof(unsigned long));
max_pfn * sizeof(unsigned int));
if (max_pfn > xen_start_info.nr_pages) {
/* set to INVALID_P2M_ENTRY */
memset(phys_to_machine_mapping, ~0,
max_pfn * sizeof(unsigned long));
max_pfn * sizeof(unsigned int));
memcpy(phys_to_machine_mapping,
(unsigned long *)xen_start_info.mfn_list,
xen_start_info.nr_pages * sizeof(unsigned long));
(unsigned int *)xen_start_info.mfn_list,
xen_start_info.nr_pages * sizeof(unsigned int));
} else {
memcpy(phys_to_machine_mapping,
(unsigned long *)xen_start_info.mfn_list,
max_pfn * sizeof(unsigned long));
(unsigned int *)xen_start_info.mfn_list,
max_pfn * sizeof(unsigned int));
/* N.B. below relies on sizeof(int) == sizeof(long). */
if (HYPERVISOR_dom_mem_op(
MEMOP_decrease_reservation,
(unsigned long *)xen_start_info.mfn_list + max_pfn,
@@ -1597,11 +1598,11 @@ void __init setup_arch(char **cmdline_p)
free_bootmem(
__pa(xen_start_info.mfn_list),
PFN_PHYS(PFN_UP(xen_start_info.nr_pages *
sizeof(unsigned long))));
sizeof(unsigned int))));
}
pfn_to_mfn_frame_list = alloc_bootmem_low_pages(PAGE_SIZE);
for ( i=0, j=0; i < max_pfn; i+=(PAGE_SIZE/sizeof(unsigned long)), j++ )
for ( i=0, j=0; i < max_pfn; i+=(PAGE_SIZE/sizeof(unsigned int)), j++ )
{
pfn_to_mfn_frame_list[j] =
virt_to_mfn(&phys_to_machine_mapping[i]);
@@ -281,7 +281,7 @@ fastcall void do_page_fault(struct pt_regs *regs, unsigned long error_code,
siginfo_t info;
/* Set the "privileged fault" bit to something sane. */
error_code &= 3;
error_code &= ~4;
error_code |= (regs->xcs & 2) << 1;
if (regs->eflags & X86_EFLAGS_VM)
error_code |= 4;
@@ -348,9 +348,12 @@ static void __init pagetable_init (void)
{
unsigned long vaddr;
pgd_t *pgd_base = (pgd_t *)xen_start_info.pt_base;
int i;
swapper_pg_dir = pgd_base;
init_mm.pgd = pgd_base;
for (i = 0; i < NR_CPUS; i++)
per_cpu(cur_pgd, i) = pgd_base;
/* Enable PSE if available */
if (cpu_has_pse) {
@@ -36,6 +36,8 @@ void iounmap(volatile void __iomem *addr)
{
}
#ifdef __i386__
void __init *bt_ioremap(unsigned long phys_addr, unsigned long size)
{
return NULL;
@@ -45,6 +47,8 @@ void __init bt_iounmap(void *addr, unsigned long size)
{
}
#endif /* __i386__ */
#else
/*
@@ -58,7 +62,7 @@ static inline int is_local_lowmem(unsigned long address)
extern unsigned long max_low_pfn;
unsigned long mfn = address >> PAGE_SHIFT;
unsigned long pfn = mfn_to_pfn(mfn);
return ((pfn < max_low_pfn) && (pfn_to_mfn(pfn) == mfn));
return ((pfn < max_low_pfn) && (phys_to_machine_mapping[pfn] == mfn));
}
/*
@@ -126,10 +130,12 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l
return NULL;
area->phys_addr = phys_addr;
addr = (void __iomem *) area->addr;
flags |= _PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED;
#ifdef __x86_64__
flags |= _PAGE_USER;
#endif
if (direct_remap_area_pages(&init_mm, (unsigned long) addr, phys_addr,
size, __pgprot(_PAGE_PRESENT | _PAGE_RW |
_PAGE_DIRTY | _PAGE_ACCESSED
| flags), domid)) {
size, __pgprot(flags), domid)) {
vunmap((void __force *) addr);
return NULL;
}
@@ -218,6 +224,8 @@ void iounmap(volatile void __iomem *addr)
kfree(p);
}
#ifdef __i386__
void __init *bt_ioremap(unsigned long phys_addr, unsigned long size)
{
unsigned long offset, last_addr;
@@ -289,6 +297,8 @@ void __init bt_iounmap(void *addr, unsigned long size)
}
}
#endif /* __i386__ */
#endif /* CONFIG_XEN_PHYSDEV_ACCESS */
/* These hacky macros avoid phys->machine translations. */
@@ -346,7 +356,7 @@ int direct_remap_area_pages(struct mm_struct *mm,
* Fill in the machine address: PTE ptr is done later by
* __direct_remap_area_pages().
*/
v->val = (machine_addr & PAGE_MASK) | pgprot_val(prot);
v->val = pte_val_ma(pfn_pte_ma(machine_addr >> PAGE_SHIFT, prot));
machine_addr += PAGE_SIZE;
address += PAGE_SIZE;
@@ -44,7 +44,7 @@ obj-$(CONFIG_X86_PM_TIMER) += pmtimer.o
c-obj-$(CONFIG_MODULES) += module.o
#obj-y += topology.o
obj-y += topology.o
c-obj-y += intel_cacheinfo.o
bootflag-y += ../../../i386/kernel/bootflag.o
@@ -778,21 +778,21 @@ void __init setup_arch(char **cmdline_p)
/* Make sure we have a large enough P->M table. */
if (end_pfn > xen_start_info.nr_pages) {
phys_to_machine_mapping = alloc_bootmem(
max_pfn * sizeof(unsigned long));
max_pfn * sizeof(u32));
memset(phys_to_machine_mapping, ~0,
max_pfn * sizeof(unsigned long));
max_pfn * sizeof(u32));
memcpy(phys_to_machine_mapping,
(unsigned long *)xen_start_info.mfn_list,
xen_start_info.nr_pages * sizeof(unsigned long));
(u32 *)xen_start_info.mfn_list,
xen_start_info.nr_pages * sizeof(u32));
free_bootmem(
__pa(xen_start_info.mfn_list),
PFN_PHYS(PFN_UP(xen_start_info.nr_pages *
sizeof(unsigned long))));
sizeof(u32))));
}
pfn_to_mfn_frame_list = alloc_bootmem(PAGE_SIZE);
for ( i=0, j=0; i < end_pfn; i+=(PAGE_SIZE/sizeof(unsigned long)), j++ )
for ( i=0, j=0; i < end_pfn; i+=(PAGE_SIZE/sizeof(u32)), j++ )
{
pfn_to_mfn_frame_list[j] =
virt_to_mfn(&phys_to_machine_mapping[i]);
@@ -6,10 +6,10 @@ XENARCH := $(subst ",,$(CONFIG_XENARCH))
CFLAGS += -Iarch/$(XENARCH)/mm
obj-y := init.o fault.o ioremap.o pageattr.o
obj-y := init.o fault.o pageattr.o
c-obj-y := extable.o
i386-obj-y := hypervisor.o
i386-obj-y := hypervisor.o ioremap.o
#obj-y := init.o fault.o ioremap.o extable.o pageattr.o
#c-obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
@@ -559,6 +559,11 @@ static void xen_copy_pt(void)
void __init xen_init_pt(void)
{
int i;
for (i = 0; i < NR_CPUS; i++)
per_cpu(cur_pgd, i) = init_mm.pgd;
memcpy((void *)init_level4_pgt,
(void *)xen_start_info.pt_base, PAGE_SIZE);
@@ -1,499 +0,0 @@
/*
* arch/x86_64/mm/ioremap.c
*
* Re-map IO memory to kernel address space so that we can access it.
* This is needed for high PCI addresses that aren't mapped in the
* 640k-1MB IO memory area on PC's
*
* (C) Copyright 1995 1996 Linus Torvalds
*/
#include <linux/vmalloc.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <asm/io.h>
#include <asm/fixmap.h>
#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
#include <asm/pgtable.h>
#include <asm/pgalloc.h>
/*
* Reuse arch/xen/i396/mm/ioremap.c. Need to merge later
*/
#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(volatile void __iomem *addr)
{
}
void __init *bt_ioremap(unsigned long phys_addr, unsigned long size)
{
return NULL;
}
void __init bt_iounmap(void *addr, unsigned long size)
{
}
#else
#if defined(__i386__)
/*
* Does @address reside within a non-highmem page that is local to this virtual
* machine (i.e., not an I/O page, nor a memory page belonging to another VM).
* See the comment that accompanies pte_pfn() in pgtable-2level.h to understand
* why this works.
*/
static inline int is_local_lowmem(unsigned long address)
{
extern unsigned long max_low_pfn;
unsigned long mfn = address >> PAGE_SHIFT;
unsigned long pfn = mfn_to_pfn(mfn);
return ((pfn < max_low_pfn) && (pfn_to_mfn(pfn) == mfn));
}
#elif defined(__x86_64__)
/*
*
*/
static inline int is_local_lowmem(unsigned long address)
{
return 0;
}
#endif
/*
* Generic mapping function (not visible outside):
*/
/*
* Remap an arbitrary physical address space into the kernel virtual
* address space. Needed when the kernel wants to access high addresses
* directly.
*
* NOTE! We need to allow non-page-aligned mappings too: we will obviously
* have to convert them into an offset in a page-aligned mapping, but the
* caller shouldn't need to know that small detail.
*/
void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags)
{
void __iomem * addr;
struct vm_struct * area;
unsigned long offset, last_addr;
domid_t domid = DOMID_IO;
/* Don't allow wraparound or zero size */
last_addr = phys_addr + size - 1;
if (!size || last_addr < phys_addr)
return NULL;
#ifdef CONFIG_XEN_PRIVILEGED_GUEST
/*
* Don't remap the low PCI/ISA area, it's always mapped..
*/
if (phys_addr >= 0x0 && last_addr < 0x100000)
return isa_bus_to_virt(phys_addr);
#endif
/*
* Don't allow anybody to remap normal RAM that we're using..
*/
if (is_local_lowmem(phys_addr)) {
char *t_addr, *t_end;
struct page *page;
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++)
if(!PageReserved(page))
return NULL;
domid = DOMID_LOCAL;
}
/*
* Mappings have to be page-aligned
*/
offset = phys_addr & ~PAGE_MASK;
phys_addr &= PAGE_MASK;
size = PAGE_ALIGN(last_addr+1) - phys_addr;
/*
* Ok, go for it..
*/
area = get_vm_area(size, VM_IOREMAP | (flags << 20));
if (!area)
return NULL;
area->phys_addr = phys_addr;
addr = (void __iomem *) area->addr;
if (direct_remap_area_pages(&init_mm, (unsigned long) addr, phys_addr,
size, __pgprot(_PAGE_PRESENT | _PAGE_RW |
_PAGE_DIRTY | _PAGE_ACCESSED
#if defined(__x86_64__)
| _PAGE_USER
#endif
| flags), domid)) {
vunmap((void __force *) addr);
return NULL;
}
return (void __iomem *) (offset + (char __iomem *)addr);
}
/**
* ioremap_nocache - map bus memory into CPU space
* @offset: bus address of the memory
* @size: size of the resource to map
*
* ioremap_nocache performs a platform specific sequence of operations to
* make bus memory CPU accessible via the readb/readw/readl/writeb/
* writew/writel functions and the other mmio helpers. The returned
* address is not guaranteed to be usable directly as a virtual
* address.
*
* This version of ioremap ensures that the memory is marked uncachable
* on the CPU as well as honouring existing caching rules from things like
* the PCI bus. Note that there are other caches and buffers on many
* busses. In particular driver authors should read up on PCI writes
*
* It's useful if some control registers are in such an area and
* write combining or read caching is not desirable:
*
* Must be freed with iounmap.
*/
void __iomem *ioremap_nocache (unsigned long phys_addr, unsigned long size)
{
unsigned long last_addr;
void __iomem *p = __ioremap(phys_addr, size, _PAGE_PCD);
if (!p)
return p;
/* Guaranteed to be > phys_addr, as per __ioremap() */
last_addr = phys_addr + size - 1;
if (is_local_lowmem(last_addr)) {
struct page *ppage = virt_to_page(bus_to_virt(phys_addr));
unsigned long npages;
phys_addr &= PAGE_MASK;
/* This might overflow and become zero.. */
last_addr = PAGE_ALIGN(last_addr);
/* .. but that's ok, because modulo-2**n arithmetic will make
* the page-aligned "last - first" come out right.
*/
npages = (last_addr - phys_addr) >> PAGE_SHIFT;
if (change_page_attr(ppage, npages, PAGE_KERNEL_NOCACHE) < 0) {
iounmap(p);
p = NULL;
}
global_flush_tlb();
}
return p;
}
void iounmap(volatile void __iomem *addr)
{
struct vm_struct *p;
if ((void __force *) addr <= high_memory)
return;
#ifdef CONFIG_XEN_PRIVILEGED_GUEST
if ((unsigned long) addr >= fix_to_virt(FIX_ISAMAP_BEGIN))
return;
#endif
p = remove_vm_area((void *) (PAGE_MASK & (unsigned long __force) addr));
if (!p) {
printk("__iounmap: bad address %p\n", addr);
return;
}
if ((p->flags >> 20) && is_local_lowmem(p->phys_addr)) {
/* p->size includes the guard page, but cpa doesn't like that */
change_page_attr(virt_to_page(bus_to_virt(p->phys_addr)),
(p->size - PAGE_SIZE) >> PAGE_SHIFT,
PAGE_KERNEL);
global_flush_tlb();
}
kfree(p);
}
#if defined(__i386__)
void __init *bt_ioremap(unsigned long phys_addr, unsigned long size)
{
unsigned long offset, last_addr;
unsigned int nrpages;
enum fixed_addresses idx;
/* Don't allow wraparound or zero size */
last_addr = phys_addr + size - 1;
if (!size || last_addr < phys_addr)
return NULL;
#ifdef CONFIG_XEN_PRIVILEGED_GUEST
/*
* Don't remap the low PCI/ISA area, it's always mapped..
*/
if (phys_addr >= 0x0 && last_addr < 0x100000)
return isa_bus_to_virt(phys_addr);
#endif
/*
* Mappings have to be page-aligned
*/
offset = phys_addr & ~PAGE_MASK;
phys_addr &= PAGE_MASK;
size = PAGE_ALIGN(last_addr) - phys_addr;
/*
* Mappings have to fit in the FIX_BTMAP area.
*/
nrpages = size >> PAGE_SHIFT;
if (nrpages > NR_FIX_BTMAPS)
return NULL;
/*
* Ok, go for it..
*/
idx = FIX_BTMAP_BEGIN;
while (nrpages > 0) {
set_fixmap(idx, phys_addr);
phys_addr += PAGE_SIZE;
--idx;
--nrpages;
}
return (void*) (offset + fix_to_virt(FIX_BTMAP_BEGIN));
}
void __init bt_iounmap(void *addr, unsigned long size)
{
unsigned long virt_addr;
unsigned long offset;
unsigned int nrpages;
enum fixed_addresses idx;
virt_addr = (unsigned long)addr;
if (virt_addr < fix_to_virt(FIX_BTMAP_BEGIN))
return;
#ifdef CONFIG_XEN_PRIVILEGED_GUEST
if (virt_addr >= fix_to_virt(FIX_ISAMAP_BEGIN))
return;
#endif
offset = virt_addr & ~PAGE_MASK;
nrpages = PAGE_ALIGN(offset + size - 1) >> PAGE_SHIFT;
idx = FIX_BTMAP_BEGIN;
while (nrpages > 0) {
clear_fixmap(idx);
--idx;
--nrpages;
}
}
#endif /* defined(__i386__) */
#endif /* CONFIG_XEN_PHYSDEV_ACCESS */
/* These hacky macros avoid phys->machine translations. */
#define __direct_pte(x) ((pte_t) { (x) } )
#define __direct_mk_pte(page_nr,pgprot) \
__direct_pte(((page_nr) << PAGE_SHIFT) | pgprot_val(pgprot))
#define direct_mk_pte_phys(physpage, pgprot) \
__direct_mk_pte((physpage) >> PAGE_SHIFT, pgprot)
static inline void direct_remap_area_pte(pte_t *pte,
unsigned long address,
unsigned long size,
mmu_update_t **v)
{
unsigned long end;
address &= ~PMD_MASK;
end = address + size;
if (end > PMD_SIZE)
end = PMD_SIZE;
if (address >= end)
BUG();
do {
(*v)->ptr = virt_to_machine(pte);
(*v)++;
address += PAGE_SIZE;
pte++;
} while (address && (address < end));
}
static inline int direct_remap_area_pmd(struct mm_struct *mm,
pmd_t *pmd,
unsigned long address,
unsigned long size,
mmu_update_t **v)
{
unsigned long end;
address &= ~PGDIR_MASK;
end = address + size;
if (end > PGDIR_SIZE)
end = PGDIR_SIZE;
if (address >= end)
BUG();
do {
pte_t *pte = (mm == &init_mm) ?
pte_alloc_kernel(mm, pmd, address) :
pte_alloc_map(mm, pmd, address);
if (!pte)
return -ENOMEM;
direct_remap_area_pte(pte, address, end - address, v);
pte_unmap(pte);
address = (address + PMD_SIZE) & PMD_MASK;
pmd++;
} while (address && (address < end));
return 0;
}
int __direct_remap_area_pages(struct mm_struct *mm,
unsigned long address,
unsigned long size,
mmu_update_t *v)
{
pgd_t * dir;
unsigned long end = address + size;
int error;
#if defined(__i386__)
dir = pgd_offset(mm, address);
#elif defined (__x86_64)
dir = (mm == &init_mm) ?
pgd_offset_k(address):
pgd_offset(mm, address);
#endif
if (address >= end)
BUG();
spin_lock(&mm->page_table_lock);
do {
pud_t *pud;
pmd_t *pmd;
error = -ENOMEM;
pud = pud_alloc(mm, dir, address);
if (!pud)
break;
pmd = pmd_alloc(mm, pud, address);
if (!pmd)
break;
error = 0;
direct_remap_area_pmd(mm, pmd, address, end - address, &v);
address = (address + PGDIR_SIZE) & PGDIR_MASK;
dir++;
} while (address && (address < end));
spin_unlock(&mm->page_table_lock);
return error;
}
int direct_remap_area_pages(struct mm_struct *mm,
unsigned long address,
unsigned long machine_addr,
unsigned long size,
pgprot_t prot,
domid_t domid)
{
int i;
unsigned long start_address;
#define MAX_DIRECTMAP_MMU_QUEUE 130
mmu_update_t u[MAX_DIRECTMAP_MMU_QUEUE], *v = u;
start_address = address;
flush_cache_all();
for (i = 0; i < size; i += PAGE_SIZE) {
if ((v - u) == MAX_DIRECTMAP_MMU_QUEUE) {
/* Fill in the PTE pointers. */
__direct_remap_area_pages(mm,
start_address,
address-start_address,
u);
if (HYPERVISOR_mmu_update(u, v - u, NULL, domid) < 0)
return -EFAULT;
v = u;
start_address = address;
}
/*
* Fill in the machine address: PTE ptr is done later by
* __direct_remap_area_pages().
*/
v->val = (machine_addr & PAGE_MASK) | pgprot_val(prot);
machine_addr += PAGE_SIZE;
address += PAGE_SIZE;
v++;
}
if (v != u) {
/* get the ptep's filled in */
__direct_remap_area_pages(mm,
start_address,
address-start_address,
u);
if (unlikely(HYPERVISOR_mmu_update(u, v - u, NULL, domid) < 0))
return -EFAULT;
}
flush_tlb_all();
return 0;
}
EXPORT_SYMBOL(direct_remap_area_pages);
static int lookup_pte_fn(
pte_t *pte, struct page *pte_page, unsigned long addr, void *data)
{
unsigned long *ptep = (unsigned long *)data;
if (ptep) *ptep = (pfn_to_mfn(page_to_pfn(pte_page)) << PAGE_SHIFT)
| ((unsigned long)pte & ~PAGE_MASK);
return 0;
}
int create_lookup_pte_addr(struct mm_struct *mm,
unsigned long address,
unsigned long *ptep)
{
return generic_page_range(mm, address, PAGE_SIZE, lookup_pte_fn, ptep);
}
EXPORT_SYMBOL(create_lookup_pte_addr);
static int noop_fn(
pte_t *pte, struct page *pte_page, unsigned long addr, void *data)
{
return 0;
}
int touch_pte_range(struct mm_struct *mm,
unsigned long address,
unsigned long size)
{
return generic_page_range(mm, address, size, noop_fn, NULL);
}
EXPORT_SYMBOL(touch_pte_range);
@@ -167,7 +167,7 @@ static int privcmd_ioctl(struct inode *inode, struct file *file,
if (ret)
goto batch_err;
u.val = (mfn << PAGE_SHIFT) | pgprot_val(vma->vm_page_prot);
u.val = pte_val_ma(pfn_pte_ma(mfn, vma->vm_page_prot));
u.ptr = ptep;
if ( unlikely(HYPERVISOR_mmu_update(&u, 1, NULL, m.dom) < 0) )
@@ -60,9 +60,13 @@
#define copy_user_page(to, from, vaddr, pg) copy_page(to, from)
/**** MACHINE <-> PHYSICAL CONVERSION MACROS ****/
#define INVALID_P2M_ENTRY (~0U)
#define FOREIGN_FRAME(m) ((m) | 0x80000000U)
extern unsigned int *phys_to_machine_mapping;
#define pfn_to_mfn(_pfn) ((unsigned long)(phys_to_machine_mapping[(_pfn)]))
#define mfn_to_pfn(_mfn) ((unsigned long)(machine_to_phys_mapping[(_mfn)]))
#define pfn_to_mfn(pfn) \
((unsigned long)phys_to_machine_mapping[(unsigned int)(pfn)] & 0x7FFFFFFFUL)
#define mfn_to_pfn(mfn) \
((unsigned long)machine_to_phys_mapping[(unsigned int)(mfn)])
/* Definitions for machine and pseudophysical addresses. */
#ifdef CONFIG_X86_PAE
@@ -63,17 +63,15 @@ inline static void set_pte_at_sync(struct mm_struct *mm, unsigned long addr,
*
* NB2. When deliberately mapping foreign pages into the p2m table, you *must*
* use FOREIGN_FRAME(). This will cause pte_pfn() to choke on it, as we
* require. In all the cases we care about, the high bit gets shifted out
* (e.g., phys_to_machine()) so behaviour there is correct.
* require. In all the cases we care about, the FOREIGN_FRAME bit is
* masked (e.g., pfn_to_mfn()) so behaviour there is correct.
*/
#define INVALID_P2M_ENTRY (~0U)
#define FOREIGN_FRAME(_m) ((_m) | (1UL<<((sizeof(unsigned long)*8)-1)))
#define pte_mfn(_pte) ((_pte).pte_low >> PAGE_SHIFT)
#define pte_pfn(_pte) \
({ \
unsigned long mfn = pte_mfn(_pte); \
unsigned long pfn = mfn_to_pfn(mfn); \
if ((pfn >= max_mapnr) || (pfn_to_mfn(pfn) != mfn)) \
if ((pfn >= max_mapnr) || (phys_to_machine_mapping[pfn] != mfn))\
pfn = max_mapnr; /* special: force !pfn_valid() */ \
pfn; \
})
@@ -150,15 +150,13 @@ static inline int pte_none(pte_t pte)
return !pte.pte_low && !pte.pte_high;
}
#define INVALID_P2M_ENTRY (~0U)
#define FOREIGN_FRAME(_m) ((_m) | (1UL<<((sizeof(unsigned long)*8)-1)))
#define pte_mfn(_pte) ( ((_pte).pte_low >> PAGE_SHIFT) |\
(((_pte).pte_high & 0xfff) << (32-PAGE_SHIFT)) )
#define pte_pfn(_pte) \
({ \
unsigned long mfn = pte_mfn(_pte); \
unsigned long pfn = mfn_to_pfn(mfn); \
if ((pfn >= max_mapnr) || (pfn_to_mfn(pfn) != mfn)) \
if ((pfn >= max_mapnr) || (phys_to_machine_mapping[pfn] != mfn))\
pfn = max_mapnr; /* special: force !pfn_valid() */ \
pfn; \
})
@@ -62,9 +62,13 @@ void copy_page(void *, void *);
#define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE
/**** MACHINE <-> PHYSICAL CONVERSION MACROS ****/
#define INVALID_P2M_ENTRY (~0U)
#define FOREIGN_FRAME(m) ((m) | 0x80000000U)
extern u32 *phys_to_machine_mapping;
#define pfn_to_mfn(_pfn) ((unsigned long) phys_to_machine_mapping[(unsigned int)(_pfn)])
#define mfn_to_pfn(_mfn) ((unsigned long) machine_to_phys_mapping[(unsigned int)(_mfn)])
#define pfn_to_mfn(pfn) \
((unsigned long)phys_to_machine_mapping[(unsigned int)(pfn)] & 0x7FFFFFFFUL)
#define mfn_to_pfn(mfn) \
((unsigned long)machine_to_phys_mapping[(unsigned int)(mfn)])
/* Definitions for machine and pseudophysical addresses. */
typedef unsigned long paddr_t;
@@ -300,17 +300,15 @@ inline static void set_pte_at(struct mm_struct *mm, unsigned long addr,
*
* NB2. When deliberately mapping foreign pages into the p2m table, you *must*
* use FOREIGN_FRAME(). This will cause pte_pfn() to choke on it, as we
* require. In all the cases we care about, the high bit gets shifted out
* (e.g., phys_to_machine()) so behaviour there is correct.
* require. In all the cases we care about, the FOREIGN_FRAME bit is
* masked (e.g., pfn_to_mfn()) so behaviour there is correct.
*/
#define INVALID_P2M_ENTRY (~0U)
#define FOREIGN_FRAME(_m) ((_m) | (1UL<<((sizeof(unsigned long)*8)-1)))
#define pte_mfn(_pte) (((_pte).pte & PTE_MASK) >> PAGE_SHIFT)
#define pte_pfn(_pte) \
({ \
unsigned long mfn = pte_mfn(_pte); \
unsigned pfn = mfn_to_pfn(mfn); \
if ((pfn >= max_mapnr) || (pfn_to_mfn(pfn) != mfn)) \
if ((pfn >= max_mapnr) || (phys_to_machine_mapping[pfn] != mfn))\
pfn = max_mapnr; /* special: force !pfn_valid() */ \
pfn; \
})
+1 -1
View File
@@ -28,7 +28,7 @@ sbindir=$(prefix)/sbin
CFLAGS += -DGCC_PRINTF -Wall -Werror -I$(XEN_LIBXENSTAT)
LDFLAGS += -L$(XEN_LIBXENSTAT)
LDLIBS += -lxenstat -lcurses
LDLIBS += -lxenstat -lncurses
all: xentop
+23 -1
View File
@@ -1751,8 +1751,30 @@ int ioapic_guest_write(int apicid, int address, u32 val)
pin = (address - 0x10) >> 1;
*(u32 *)&rte = val;
rte.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS);
*(int *)&rte = val;
/*
* What about weird destination types?
* SMI: Ignore? Ought to be set up by the BIOS.
* NMI: Ignore? Watchdog functionality is Xen's concern.
* INIT: Definitely ignore: probably a guest OS bug.
* ExtINT: Ignore? Linux only asserts this at start of day.
* For now, print a message and return an error. We can fix up on demand.
*/
if ( rte.delivery_mode > dest_LowestPrio )
{
printk("ERROR: Attempt to write weird IOAPIC destination mode!\n");
printk(" APIC=%d/%d, lo-reg=%x\n", apicid, pin, val);
return -EINVAL;
}
/*
* The guest does not know physical APIC arrangement (flat vs. cluster).
* Apply genapic conventions for this platform.
*/
rte.delivery_mode = INT_DELIVERY_MODE;
rte.dest_mode = INT_DEST_MODE;
if ( rte.vector >= FIRST_DEVICE_VECTOR )
{
+25 -25
View File
@@ -444,7 +444,7 @@ get_page_from_l1e(
if ( unlikely(l1e_get_flags(l1e) & L1_DISALLOW_MASK) )
{
MEM_LOG("Bad L1 flags %x\n", l1e_get_flags(l1e) & L1_DISALLOW_MASK);
MEM_LOG("Bad L1 flags %x", l1e_get_flags(l1e) & L1_DISALLOW_MASK);
return 0;
}
@@ -490,7 +490,7 @@ get_page_from_l2e(
if ( unlikely((l2e_get_flags(l2e) & L2_DISALLOW_MASK)) )
{
MEM_LOG("Bad L2 flags %x\n", l2e_get_flags(l2e) & L2_DISALLOW_MASK);
MEM_LOG("Bad L2 flags %x", l2e_get_flags(l2e) & L2_DISALLOW_MASK);
return 0;
}
@@ -523,7 +523,7 @@ get_page_from_l3e(
if ( unlikely((l3e_get_flags(l3e) & L3_DISALLOW_MASK)) )
{
MEM_LOG("Bad L3 flags %x\n", l3e_get_flags(l3e) & L3_DISALLOW_MASK);
MEM_LOG("Bad L3 flags %x", l3e_get_flags(l3e) & L3_DISALLOW_MASK);
return 0;
}
@@ -557,7 +557,7 @@ get_page_from_l4e(
if ( unlikely((l4e_get_flags(l4e) & L4_DISALLOW_MASK)) )
{
MEM_LOG("Bad L4 flags %x\n", l4e_get_flags(l4e) & L4_DISALLOW_MASK);
MEM_LOG("Bad L4 flags %x", l4e_get_flags(l4e) & L4_DISALLOW_MASK);
return 0;
}
@@ -1025,7 +1025,7 @@ static inline int update_l1e(l1_pgentry_t *pl1e,
unlikely(o != l1e_get_intpte(ol1e)) )
{
MEM_LOG("Failed to update %" PRIpte " -> %" PRIpte
": saw %" PRIpte "\n",
": saw %" PRIpte,
l1e_get_intpte(ol1e),
l1e_get_intpte(nl1e),
o);
@@ -1051,7 +1051,7 @@ static int mod_l1_entry(l1_pgentry_t *pl1e, l1_pgentry_t nl1e)
{
if ( unlikely(l1e_get_flags(nl1e) & L1_DISALLOW_MASK) )
{
MEM_LOG("Bad L1 flags %x\n",
MEM_LOG("Bad L1 flags %x",
l1e_get_flags(nl1e) & L1_DISALLOW_MASK);
return 0;
}
@@ -1113,7 +1113,7 @@ static int mod_l2_entry(l2_pgentry_t *pl2e,
{
if ( unlikely(l2e_get_flags(nl2e) & L2_DISALLOW_MASK) )
{
MEM_LOG("Bad L2 flags %x\n",
MEM_LOG("Bad L2 flags %x",
l2e_get_flags(nl2e) & L2_DISALLOW_MASK);
return 0;
}
@@ -1175,7 +1175,7 @@ static int mod_l3_entry(l3_pgentry_t *pl3e,
{
if ( unlikely(l3e_get_flags(nl3e) & L3_DISALLOW_MASK) )
{
MEM_LOG("Bad L3 flags %x\n",
MEM_LOG("Bad L3 flags %x",
l3e_get_flags(nl3e) & L3_DISALLOW_MASK);
return 0;
}
@@ -1237,7 +1237,7 @@ static int mod_l4_entry(l4_pgentry_t *pl4e,
{
if ( unlikely(l4e_get_flags(nl4e) & L4_DISALLOW_MASK) )
{
MEM_LOG("Bad L4 flags %x\n",
MEM_LOG("Bad L4 flags %x",
l4e_get_flags(nl4e) & L4_DISALLOW_MASK);
return 0;
}
@@ -1598,7 +1598,7 @@ static int set_foreigndom(unsigned int cpu, domid_t domid)
percpu_info[cpu].foreign = dom_io;
break;
default:
MEM_LOG("Dom %u cannot set foreign dom\n", d->domain_id);
MEM_LOG("Dom %u cannot set foreign dom", d->domain_id);
okay = 0;
break;
}
@@ -1831,7 +1831,7 @@ int do_mmuext_op(
case MMUEXT_FLUSH_CACHE:
if ( unlikely(!IS_CAPABLE_PHYSDEV(d)) )
{
MEM_LOG("Non-physdev domain tried to FLUSH_CACHE.\n");
MEM_LOG("Non-physdev domain tried to FLUSH_CACHE.");
okay = 0;
}
else
@@ -1845,7 +1845,7 @@ int do_mmuext_op(
if ( shadow_mode_external(d) )
{
MEM_LOG("ignoring SET_LDT hypercall from external "
"domain %u\n", d->domain_id);
"domain %u", d->domain_id);
okay = 0;
break;
}
@@ -1916,7 +1916,7 @@ int do_mmuext_op(
unlikely(IS_XEN_HEAP_FRAME(page)) )
{
MEM_LOG("Transferee has no reservation headroom (%d,%d), or "
"page is in Xen heap (%lx), or dom is dying (%ld).\n",
"page is in Xen heap (%lx), or dom is dying (%ld).",
e->tot_pages, e->max_pages, op.mfn, e->domain_flags);
okay = 0;
goto reassign_fail;
@@ -1937,7 +1937,7 @@ int do_mmuext_op(
unlikely(_nd != _d) )
{
MEM_LOG("Bad page values %lx: ed=%p(%u), sd=%p,"
" caf=%08x, taf=%" PRtype_info "\n",
" caf=%08x, taf=%" PRtype_info,
page_to_pfn(page), d, d->domain_id,
unpickle_domptr(_nd), x, page->u.inuse.type_info);
okay = 0;
@@ -2301,7 +2301,7 @@ int update_grant_pte_mapping(
if ( ((type_info & PGT_type_mask) != PGT_l1_page_table) ||
!get_page_type(page, type_info & (PGT_type_mask|PGT_va_mask)) )
{
DPRINTK("Grant map attempted to update a non-L1 page\n");
MEM_LOG("Grant map attempted to update a non-L1 page");
rc = GNTST_general_error;
goto failed;
}
@@ -2363,7 +2363,7 @@ int clear_grant_pte_mapping(
if ( ((type_info & PGT_type_mask) != PGT_l1_page_table) ||
!get_page_type(page, type_info & (PGT_type_mask|PGT_va_mask)) )
{
DPRINTK("Grant map attempted to update a non-L1 page\n");
MEM_LOG("Grant map attempted to update a non-L1 page");
rc = GNTST_general_error;
goto failed;
}
@@ -2378,7 +2378,7 @@ int clear_grant_pte_mapping(
/* Check that the virtual address supplied is actually mapped to frame. */
if ( unlikely((l1e_get_intpte(ol1e) >> PAGE_SHIFT) != frame) )
{
DPRINTK("PTE entry %lx for address %lx doesn't match frame %lx\n",
MEM_LOG("PTE entry %lx for address %lx doesn't match frame %lx",
(unsigned long)l1e_get_intpte(ol1e), addr, frame);
put_page_type(page);
rc = GNTST_general_error;
@@ -2388,7 +2388,7 @@ int clear_grant_pte_mapping(
/* Delete pagetable entry. */
if ( unlikely(__put_user(0, (intpte_t *)va)))
{
DPRINTK("Cannot delete PTE entry at %p.\n", va);
MEM_LOG("Cannot delete PTE entry at %p", va);
put_page_type(page);
rc = GNTST_general_error;
goto failed;
@@ -2452,7 +2452,7 @@ int clear_grant_va_mapping(unsigned long addr, unsigned long frame)
if ( unlikely(__get_user(ol1e.l1, &pl1e->l1) != 0) )
{
DPRINTK("Could not find PTE entry for address %lx\n", addr);
MEM_LOG("Could not find PTE entry for address %lx", addr);
return GNTST_general_error;
}
@@ -2462,7 +2462,7 @@ int clear_grant_va_mapping(unsigned long addr, unsigned long frame)
*/
if ( unlikely(l1e_get_pfn(ol1e) != frame) )
{
DPRINTK("PTE entry %lx for address %lx doesn't match frame %lx\n",
MEM_LOG("PTE entry %lx for address %lx doesn't match frame %lx",
l1e_get_pfn(ol1e), addr, frame);
return GNTST_general_error;
}
@@ -2470,7 +2470,7 @@ int clear_grant_va_mapping(unsigned long addr, unsigned long frame)
/* Delete pagetable entry. */
if ( unlikely(__put_user(0, &pl1e->l1)) )
{
DPRINTK("Cannot delete PTE entry at %p.\n", (unsigned long *)pl1e);
MEM_LOG("Cannot delete PTE entry at %p", (unsigned long *)pl1e);
return GNTST_general_error;
}
@@ -2930,7 +2930,7 @@ int revalidate_l1(
if ( unlikely(!get_page_from_l1e(nl1e, d)) )
{
MEM_LOG("ptwr: Could not re-validate l1 page\n");
MEM_LOG("ptwr: Could not re-validate l1 page");
/*
* Make the remaining p.t's consistent before crashing, so the
* reference counts are correct.
@@ -3056,7 +3056,7 @@ static int ptwr_emulated_update(
/* Aligned access only, thank you. */
if ( !access_ok(addr, bytes) || ((addr & (bytes-1)) != 0) )
{
MEM_LOG("ptwr_emulate: Unaligned or bad size ptwr access (%d, %lx)\n",
MEM_LOG("ptwr_emulate: Unaligned or bad size ptwr access (%d, %lx)",
bytes, addr);
return X86EMUL_UNHANDLEABLE;
}
@@ -3089,7 +3089,7 @@ static int ptwr_emulated_update(
if (__copy_from_user(&pte, &linear_pg_table[l1_linear_offset(addr)],
sizeof(pte)))
{
MEM_LOG("ptwr_emulate: Cannot read thru linear_pg_table\n");
MEM_LOG("ptwr_emulate: Cannot read thru linear_pg_table");
return X86EMUL_UNHANDLEABLE;
}
@@ -3102,7 +3102,7 @@ static int ptwr_emulated_update(
(page_get_owner(page) != d) )
{
MEM_LOG("ptwr_emulate: Page is mistyped or bad pte "
"(%lx, %" PRtype_info ")\n",
"(%lx, %" PRtype_info ")",
l1e_get_pfn(pte), page->u.inuse.type_info);
return X86EMUL_UNHANDLEABLE;
}
-3
View File
@@ -1712,9 +1712,6 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs regs)
default:
__vmx_bug(&regs); /* should not happen */
}
vmx_intr_assist(v);
return;
}
asmlinkage void load_cr2(void)
+4 -5
View File
@@ -631,12 +631,14 @@ static inline int irq_masked(unsigned long eflags)
return ((eflags & X86_EFLAGS_IF) == 0);
}
void vmx_intr_assist(struct vcpu *v)
asmlinkage void vmx_intr_assist(void)
{
int intr_type = 0;
int highest_vector = find_highest_pending_irq(v, &intr_type);
int highest_vector;
unsigned long intr_fields, eflags, interruptibility, cpu_exec_control;
struct vcpu *v = current;
highest_vector = find_highest_pending_irq(v, &intr_type);
__vmread(CPU_BASED_VM_EXEC_CONTROL, &cpu_exec_control);
if (highest_vector == -1) {
@@ -712,9 +714,6 @@ void vmx_do_resume(struct vcpu *d)
/* We can't resume the guest if we're waiting on I/O */
ASSERT(!test_bit(ARCH_VMX_IO_WAIT, &d->arch.arch_vmx.flags));
/* We always check for interrupts before resuming guest */
vmx_intr_assist(d);
}
#endif /* CONFIG_VMX */
+1
View File
@@ -140,6 +140,7 @@ ENTRY(vmx_asm_vmexit_handler)
jnz 2f
/* vmx_restore_all_guest */
call vmx_intr_assist
call load_cr2
.endif
VMX_RESTORE_ALL_NOSEGREGS
+25 -15
View File
@@ -1,5 +1,6 @@
#include <xen/config.h>
#include <xen/domain_page.h>
#include <xen/init.h>
#include <xen/sched.h>
#include <xen/lib.h>
@@ -86,24 +87,33 @@ void show_registers(struct cpu_user_regs *regs)
void show_page_walk(unsigned long addr)
{
l2_pgentry_t pmd;
l1_pgentry_t *pte;
if ( addr < PAGE_OFFSET )
return;
unsigned long pfn = read_cr3() >> PAGE_SHIFT;
intpte_t *ptab, ent;
printk("Pagetable walk from %08lx:\n", addr);
pmd = idle_pg_table_l2[l2_linear_offset(addr)];
printk(" L2 = %"PRIpte" %s\n", l2e_get_intpte(pmd),
(l2e_get_flags(pmd) & _PAGE_PSE) ? "(2/4MB)" : "");
if ( !(l2e_get_flags(pmd) & _PAGE_PRESENT) ||
(l2e_get_flags(pmd) & _PAGE_PSE) )
return;
pte = __va(l2e_get_paddr(pmd));
pte += l1_table_offset(addr);
printk(" L1 = %"PRIpte"\n", l1e_get_intpte(*pte));
#ifdef CONFIG_X86_PAE
ptab = map_domain_page(pfn);
ent = ptab[l3_table_offset(addr)];
printk(" L3 = %"PRIpte"\n", ent);
unmap_domain_page(ptab);
if ( !(ent & _PAGE_PRESENT) )
return;
pfn = ent >> PAGE_SHIFT;
#endif
ptab = map_domain_page(pfn);
ent = ptab[l2_table_offset(addr)];
printk(" L2 = %"PRIpte" %s\n", ent, (ent & _PAGE_PSE) ? "(PSE)" : "");
unmap_domain_page(ptab);
if ( !(ent & _PAGE_PRESENT) || (ent & _PAGE_PSE) )
return;
pfn = ent >> PAGE_SHIFT;
ptab = map_domain_page(ent >> PAGE_SHIFT);
ent = ptab[l2_table_offset(addr)];
printk(" L1 = %"PRIpte"\n", ent);
unmap_domain_page(ptab);
}
#define DOUBLEFAULT_STACK_SIZE 1024
+1
View File
@@ -233,6 +233,7 @@ ENTRY(vmx_asm_vmexit_handler)
jnz 2f
/* vmx_restore_all_guest */
call vmx_intr_assist
call load_cr2
.endif
/*
+2 -2
View File
@@ -31,7 +31,7 @@
extern void vmx_asm_vmexit_handler(struct cpu_user_regs);
extern void vmx_asm_do_resume(void);
extern void vmx_asm_do_launch(void);
extern void vmx_intr_assist(struct vcpu *d);
extern void vmx_intr_assist(void);
extern void arch_vmx_do_launch(struct vcpu *);
extern void arch_vmx_do_resume(struct vcpu *);
@@ -355,7 +355,7 @@ static inline int __vmxon (u64 addr)
}
/* Make sure that xen intercepts any FP accesses from current */
static inline void vmx_stts()
static inline void vmx_stts(void)
{
unsigned long cr0;
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.