mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
Merge with xenppc-unstable-merge.hg.
This commit is contained in:
commit
8a1ca3b97e
76 files changed
+2090
-1591
No files matched your search
@@ -69,7 +69,7 @@ dig_setup (char **cmdline_p)
|
||||
screen_info.orig_video_isVGA = 1; /* XXX fake */
|
||||
screen_info.orig_video_ega_bx = 3; /* XXX fake */
|
||||
#ifdef CONFIG_XEN
|
||||
if (!is_running_on_xen())
|
||||
if (!is_running_on_xen() || !is_initial_xendomain())
|
||||
return;
|
||||
|
||||
if (xen_start_info->console.dom0.info_size >=
|
||||
|
||||
@@ -560,7 +560,9 @@ setup_arch (char **cmdline_p)
|
||||
|
||||
platform_setup(cmdline_p);
|
||||
paging_init();
|
||||
#ifdef CONFIG_XEN
|
||||
contiguous_bitmap_init(max_pfn);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -371,6 +371,8 @@ gnttab_map_grant_ref_pre(struct gnttab_map_grant_ref *uop)
|
||||
int
|
||||
HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count)
|
||||
{
|
||||
__u64 va1, va2, pa1, pa2;
|
||||
|
||||
if (cmd == GNTTABOP_map_grant_ref) {
|
||||
unsigned int i;
|
||||
for (i = 0; i < count; i++) {
|
||||
@@ -378,8 +380,29 @@ HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count)
|
||||
(struct gnttab_map_grant_ref*)uop + i);
|
||||
}
|
||||
}
|
||||
|
||||
return ____HYPERVISOR_grant_table_op(cmd, uop, count);
|
||||
va1 = (__u64)uop & PAGE_MASK;
|
||||
pa1 = pa2 = 0;
|
||||
if ((REGION_NUMBER(va1) == 5) &&
|
||||
((va1 - KERNEL_START) >= KERNEL_TR_PAGE_SIZE)) {
|
||||
pa1 = ia64_tpa(va1);
|
||||
if (cmd <= GNTTABOP_transfer) {
|
||||
static uint32_t uop_size[GNTTABOP_transfer + 1] = {
|
||||
sizeof(struct gnttab_map_grant_ref),
|
||||
sizeof(struct gnttab_unmap_grant_ref),
|
||||
sizeof(struct gnttab_setup_table),
|
||||
sizeof(struct gnttab_dump_table),
|
||||
sizeof(struct gnttab_transfer),
|
||||
};
|
||||
va2 = (__u64)uop + (uop_size[cmd] * count) - 1;
|
||||
va2 &= PAGE_MASK;
|
||||
if (va1 != va2) {
|
||||
/* maximum size of uop is 2pages */
|
||||
BUG_ON(va2 > va1 + PAGE_SIZE);
|
||||
pa2 = ia64_tpa(va2);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ____HYPERVISOR_grant_table_op(cmd, uop, count, pa1, pa2);
|
||||
}
|
||||
EXPORT_SYMBOL(HYPERVISOR_grant_table_op);
|
||||
|
||||
|
||||
@@ -846,7 +846,7 @@ void __init setup_arch(char **cmdline_p)
|
||||
|
||||
if (!xen_feature(XENFEAT_auto_translated_physmap)) {
|
||||
/* Make sure we have a large enough P->M table. */
|
||||
phys_to_machine_mapping = alloc_bootmem(
|
||||
phys_to_machine_mapping = alloc_bootmem_pages(
|
||||
end_pfn * sizeof(unsigned long));
|
||||
memset(phys_to_machine_mapping, ~0,
|
||||
end_pfn * sizeof(unsigned long));
|
||||
@@ -863,7 +863,7 @@ void __init setup_arch(char **cmdline_p)
|
||||
* list of frames that make up the p2m table. Used by
|
||||
* save/restore.
|
||||
*/
|
||||
pfn_to_mfn_frame_list_list = alloc_bootmem(PAGE_SIZE);
|
||||
pfn_to_mfn_frame_list_list = alloc_bootmem_pages(PAGE_SIZE);
|
||||
HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list =
|
||||
virt_to_mfn(pfn_to_mfn_frame_list_list);
|
||||
|
||||
@@ -873,7 +873,7 @@ void __init setup_arch(char **cmdline_p)
|
||||
k++;
|
||||
BUG_ON(k>=fpp);
|
||||
pfn_to_mfn_frame_list[k] =
|
||||
alloc_bootmem(PAGE_SIZE);
|
||||
alloc_bootmem_pages(PAGE_SIZE);
|
||||
pfn_to_mfn_frame_list_list[k] =
|
||||
virt_to_mfn(pfn_to_mfn_frame_list[k]);
|
||||
j=0;
|
||||
|
||||
@@ -193,6 +193,7 @@ static void netfront_closing(struct xenbus_device *);
|
||||
|
||||
static void end_access(int, void *);
|
||||
static void netif_disconnect_backend(struct netfront_info *);
|
||||
static int open_netdev(struct netfront_info *);
|
||||
static void close_netdev(struct netfront_info *);
|
||||
static void netif_free(struct netfront_info *);
|
||||
|
||||
@@ -263,15 +264,22 @@ static int __devinit netfront_probe(struct xenbus_device *dev,
|
||||
dev->dev.driver_data = info;
|
||||
|
||||
err = talk_to_backend(dev, info);
|
||||
if (err) {
|
||||
xennet_sysfs_delif(info->netdev);
|
||||
unregister_netdev(netdev);
|
||||
free_netdev(netdev);
|
||||
dev->dev.driver_data = NULL;
|
||||
return err;
|
||||
}
|
||||
if (err)
|
||||
goto fail_backend;
|
||||
|
||||
err = open_netdev(info);
|
||||
if (err)
|
||||
goto fail_open;
|
||||
|
||||
return 0;
|
||||
|
||||
fail_open:
|
||||
xennet_sysfs_delif(info->netdev);
|
||||
unregister_netdev(netdev);
|
||||
fail_backend:
|
||||
free_netdev(netdev);
|
||||
dev->dev.driver_data = NULL;
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
@@ -1887,27 +1895,9 @@ create_netdev(int handle, int copying_receiver, struct xenbus_device *dev)
|
||||
SET_MODULE_OWNER(netdev);
|
||||
SET_NETDEV_DEV(netdev, &dev->dev);
|
||||
|
||||
err = register_netdev(netdev);
|
||||
if (err) {
|
||||
printk(KERN_WARNING "%s> register_netdev err=%d\n",
|
||||
__FUNCTION__, err);
|
||||
goto exit_free_rx;
|
||||
}
|
||||
|
||||
err = xennet_sysfs_addif(netdev);
|
||||
if (err) {
|
||||
/* This can be non-fatal: it only means no tuning parameters */
|
||||
printk(KERN_WARNING "%s> add sysfs failed err=%d\n",
|
||||
__FUNCTION__, err);
|
||||
}
|
||||
|
||||
np->netdev = netdev;
|
||||
|
||||
return netdev;
|
||||
|
||||
|
||||
exit_free_rx:
|
||||
gnttab_free_grant_references(np->gref_rx_head);
|
||||
exit_free_tx:
|
||||
gnttab_free_grant_references(np->gref_tx_head);
|
||||
exit:
|
||||
@@ -1967,6 +1957,26 @@ static int __devexit netfront_remove(struct xenbus_device *dev)
|
||||
}
|
||||
|
||||
|
||||
static int open_netdev(struct netfront_info *info)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = register_netdev(info->netdev);
|
||||
if (err) {
|
||||
printk(KERN_WARNING "%s: register_netdev err=%d\n",
|
||||
__FUNCTION__, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = xennet_sysfs_addif(info->netdev);
|
||||
if (err) {
|
||||
/* This can be non-fatal: it only means no tuning parameters */
|
||||
printk(KERN_WARNING "%s: add sysfs failed err=%d\n",
|
||||
__FUNCTION__, err);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void close_netdev(struct netfront_info *info)
|
||||
{
|
||||
del_timer_sync(&info->rx_refill_timer);
|
||||
|
||||
@@ -19,10 +19,21 @@
|
||||
#define flush_agp_cache() mb()
|
||||
|
||||
/* Convert a physical address to an address suitable for the GART. */
|
||||
#ifndef CONFIG_XEN
|
||||
#define phys_to_gart(x) (x)
|
||||
#define gart_to_phys(x) (x)
|
||||
#else
|
||||
#define phys_to_gart(x) phys_to_machine_for_dma(x)
|
||||
#define gart_to_phys(x) machine_to_phys_for_dma(x)
|
||||
#endif
|
||||
|
||||
/* GATT allocation. Returns/accepts GATT kernel virtual address. */
|
||||
#ifndef CONFIG_XEN
|
||||
#define alloc_gatt_pages(order) \
|
||||
((char *)__get_free_pages(GFP_KERNEL, (order)))
|
||||
#define free_gatt_pages(table, order) \
|
||||
free_pages((unsigned long)(table), (order))
|
||||
#else
|
||||
#include <asm/hypervisor.h>
|
||||
static inline char*
|
||||
alloc_gatt_pages(unsigned int order)
|
||||
@@ -46,5 +57,6 @@ free_gatt_pages(void* table, unsigned int order)
|
||||
xen_destroy_contiguous_region((unsigned long)table, order);
|
||||
free_pages((unsigned long)table, order);
|
||||
}
|
||||
#endif /* CONFIG_XEN */
|
||||
|
||||
#endif /* _ASM_IA64_AGP_H */
|
||||
@@ -7,11 +7,28 @@
|
||||
*/
|
||||
#include <linux/config.h>
|
||||
#include <asm/machvec.h>
|
||||
#ifdef CONFIG_XEN
|
||||
/* Needed for arch/i386/kernel/swiotlb.c and arch/i386/kernel/pci-dma-xen.c */
|
||||
#include <asm/hypervisor.h>
|
||||
/* Needed for arch/i386/kernel/swiotlb.c */
|
||||
#include <asm-i386/mach-xen/asm/swiotlb.h>
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_XEN
|
||||
#define dma_alloc_coherent platform_dma_alloc_coherent
|
||||
#define dma_alloc_noncoherent platform_dma_alloc_coherent /* coherent mem. is cheap */
|
||||
#define dma_free_coherent platform_dma_free_coherent
|
||||
#define dma_free_noncoherent platform_dma_free_coherent
|
||||
#define dma_map_single platform_dma_map_single
|
||||
#define dma_map_sg platform_dma_map_sg
|
||||
#define dma_unmap_single platform_dma_unmap_single
|
||||
#define dma_unmap_sg platform_dma_unmap_sg
|
||||
#define dma_sync_single_for_cpu platform_dma_sync_single_for_cpu
|
||||
#define dma_sync_sg_for_cpu platform_dma_sync_sg_for_cpu
|
||||
#define dma_sync_single_for_device platform_dma_sync_single_for_device
|
||||
#define dma_sync_sg_for_device platform_dma_sync_sg_for_device
|
||||
#define dma_mapping_error platform_dma_mapping_error
|
||||
#else
|
||||
int dma_map_sg(struct device *hwdev, struct scatterlist *sg, int nents,
|
||||
enum dma_data_direction direction);
|
||||
void dma_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents,
|
||||
@@ -50,6 +67,7 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
|
||||
swiotlb_sync_sg_for_device(dev,sg,nelems,direction);
|
||||
flush_write_buffers();
|
||||
}
|
||||
#endif
|
||||
|
||||
#define dma_map_page(dev, pg, off, size, dir) \
|
||||
dma_map_single(dev, page_address(pg) + (off), (size), (dir))
|
||||
@@ -91,6 +109,7 @@ dma_cache_sync (void *vaddr, size_t size, enum dma_data_direction dir)
|
||||
|
||||
#define dma_is_consistent(dma_handle) (1) /* all we do is coherent memory... */
|
||||
|
||||
#ifdef CONFIG_XEN
|
||||
/* arch/i386/kernel/swiotlb.o requires */
|
||||
void contiguous_bitmap_init(unsigned long end_pfn);
|
||||
|
||||
@@ -111,5 +130,6 @@ range_straddles_page_boundary(void *p, size_t size)
|
||||
return (((((unsigned long)p & ~PAGE_MASK) + size) > PAGE_SIZE) &&
|
||||
!test_bit(__pa(p) >> PAGE_SHIFT, contiguous_bitmap));
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ASM_IA64_DMA_MAPPING_H */
|
||||
@@ -51,7 +51,7 @@
|
||||
"break 0x1000 ;;\n" \
|
||||
"mov %0=r8 ;;\n" \
|
||||
: "=r" (__res) \
|
||||
: "i" (__HYPERVISOR_##name) \
|
||||
: "J" (__HYPERVISOR_##name) \
|
||||
: "r2","r8", \
|
||||
"memory" ); \
|
||||
(type)__res; \
|
||||
@@ -66,8 +66,8 @@
|
||||
"break 0x1000 ;;\n" \
|
||||
"mov %0=r8 ;;\n" \
|
||||
: "=r" (__res) \
|
||||
: "i" (__HYPERVISOR_##name), \
|
||||
"r" ((unsigned long)(a1)) \
|
||||
: "J" (__HYPERVISOR_##name), \
|
||||
"rI" ((unsigned long)(a1)) \
|
||||
: "r14","r2","r8", \
|
||||
"memory" ); \
|
||||
(type)__res; \
|
||||
@@ -83,9 +83,9 @@
|
||||
"break 0x1000 ;;\n" \
|
||||
"mov %0=r8 ;;\n" \
|
||||
: "=r" (__res) \
|
||||
: "i" (__HYPERVISOR_##name), \
|
||||
"r" ((unsigned long)(a1)), \
|
||||
"r" ((unsigned long)(a2)) \
|
||||
: "J" (__HYPERVISOR_##name), \
|
||||
"rI" ((unsigned long)(a1)), \
|
||||
"rI" ((unsigned long)(a2)) \
|
||||
: "r14","r15","r2","r8", \
|
||||
"memory" ); \
|
||||
(type)__res; \
|
||||
@@ -102,10 +102,10 @@
|
||||
"break 0x1000 ;;\n" \
|
||||
"mov %0=r8 ;;\n" \
|
||||
: "=r" (__res) \
|
||||
: "i" (__HYPERVISOR_##name), \
|
||||
"r" ((unsigned long)(a1)), \
|
||||
"r" ((unsigned long)(a2)), \
|
||||
"r" ((unsigned long)(a3)) \
|
||||
: "J" (__HYPERVISOR_##name), \
|
||||
"rI" ((unsigned long)(a1)), \
|
||||
"rI" ((unsigned long)(a2)), \
|
||||
"rI" ((unsigned long)(a3)) \
|
||||
: "r14","r15","r16","r2","r8", \
|
||||
"memory" ); \
|
||||
(type)__res; \
|
||||
@@ -123,11 +123,11 @@
|
||||
"break 0x1000 ;;\n" \
|
||||
"mov %0=r8 ;;\n" \
|
||||
: "=r" (__res) \
|
||||
: "i" (__HYPERVISOR_##name), \
|
||||
"r" ((unsigned long)(a1)), \
|
||||
"r" ((unsigned long)(a2)), \
|
||||
"r" ((unsigned long)(a3)), \
|
||||
"r" ((unsigned long)(a4)) \
|
||||
: "J" (__HYPERVISOR_##name), \
|
||||
"rI" ((unsigned long)(a1)), \
|
||||
"rI" ((unsigned long)(a2)), \
|
||||
"rI" ((unsigned long)(a3)), \
|
||||
"rI" ((unsigned long)(a4)) \
|
||||
: "r14","r15","r16","r2","r8", \
|
||||
"r17","memory" ); \
|
||||
(type)__res; \
|
||||
@@ -146,12 +146,12 @@
|
||||
"break 0x1000 ;;\n" \
|
||||
"mov %0=r8 ;;\n" \
|
||||
: "=r" (__res) \
|
||||
: "i" (__HYPERVISOR_##name), \
|
||||
"r" ((unsigned long)(a1)), \
|
||||
"r" ((unsigned long)(a2)), \
|
||||
"r" ((unsigned long)(a3)), \
|
||||
"r" ((unsigned long)(a4)), \
|
||||
"r" ((unsigned long)(a5)) \
|
||||
: "J" (__HYPERVISOR_##name), \
|
||||
"rI" ((unsigned long)(a1)), \
|
||||
"rI" ((unsigned long)(a2)), \
|
||||
"rI" ((unsigned long)(a3)), \
|
||||
"rI" ((unsigned long)(a4)), \
|
||||
"rI" ((unsigned long)(a5)) \
|
||||
: "r14","r15","r16","r2","r8", \
|
||||
"r17","r18","memory" ); \
|
||||
(type)__res; \
|
||||
@@ -275,9 +275,10 @@ HYPERVISOR_physdev_op(
|
||||
//XXX __HYPERVISOR_grant_table_op is used for this hypercall constant.
|
||||
static inline int
|
||||
____HYPERVISOR_grant_table_op(
|
||||
unsigned int cmd, void *uop, unsigned int count)
|
||||
unsigned int cmd, void *uop, unsigned int count,
|
||||
unsigned long pa1, unsigned long pa2)
|
||||
{
|
||||
return _hypercall3(int, grant_table_op, cmd, uop, count);
|
||||
return _hypercall5(int, grant_table_op, cmd, uop, count, pa1, pa2);
|
||||
}
|
||||
|
||||
int HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count);
|
||||
@@ -291,6 +292,13 @@ HYPERVISOR_vcpu_op(
|
||||
|
||||
extern int HYPERVISOR_suspend(unsigned long srec);
|
||||
|
||||
static inline unsigned long
|
||||
HYPERVISOR_hvm_op(
|
||||
int cmd, void *arg)
|
||||
{
|
||||
return _hypercall2(unsigned long, hvm_op, cmd, arg);
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_callback_op(
|
||||
int cmd, void *arg)
|
||||
@@ -307,99 +315,15 @@ static inline void exit_idle(void) {}
|
||||
})
|
||||
|
||||
#include <linux/err.h>
|
||||
#ifdef CONFIG_XEN
|
||||
#include <asm/xen/privop.h>
|
||||
|
||||
#define _hypercall_imm1(type, name, imm, a1) \
|
||||
({ \
|
||||
long __res; \
|
||||
__asm__ __volatile__ (";;\n" \
|
||||
"mov r14=%2\n" \
|
||||
"mov r15=%3\n" \
|
||||
"mov r2=%1\n" \
|
||||
"break 0x1000 ;;\n" \
|
||||
"mov %0=r8 ;;\n" \
|
||||
: "=r" (__res) \
|
||||
: "i" (__HYPERVISOR_##name), \
|
||||
"i" (imm), \
|
||||
"r" ((unsigned long)(a1)) \
|
||||
: "r14","r15","r2","r8", \
|
||||
"memory" ); \
|
||||
(type)__res; \
|
||||
})
|
||||
|
||||
#define _hypercall_imm2(type, name, imm, a1, a2) \
|
||||
({ \
|
||||
long __res; \
|
||||
__asm__ __volatile__ (";;\n" \
|
||||
"mov r14=%2\n" \
|
||||
"mov r15=%3\n" \
|
||||
"mov r16=%4\n" \
|
||||
"mov r2=%1\n" \
|
||||
"break 0x1000 ;;\n" \
|
||||
"mov %0=r8 ;;\n" \
|
||||
: "=r" (__res) \
|
||||
: "i" (__HYPERVISOR_##name), \
|
||||
"i" (imm), \
|
||||
"r" ((unsigned long)(a1)), \
|
||||
"r" ((unsigned long)(a2)) \
|
||||
: "r14","r15","r16","r2","r8", \
|
||||
"memory" ); \
|
||||
(type)__res; \
|
||||
})
|
||||
|
||||
#define _hypercall_imm3(type, name, imm, a1, a2, a3) \
|
||||
({ \
|
||||
long __res; \
|
||||
__asm__ __volatile__ (";;\n" \
|
||||
"mov r14=%2\n" \
|
||||
"mov r15=%3\n" \
|
||||
"mov r16=%4\n" \
|
||||
"mov r17=%5\n" \
|
||||
"mov r2=%1\n" \
|
||||
"break 0x1000 ;;\n" \
|
||||
"mov %0=r8 ;;\n" \
|
||||
: "=r" (__res) \
|
||||
: "i" (__HYPERVISOR_##name), \
|
||||
"i" (imm), \
|
||||
"r" ((unsigned long)(a1)), \
|
||||
"r" ((unsigned long)(a2)), \
|
||||
"r" ((unsigned long)(a3)) \
|
||||
: "r14","r15","r16","r17", \
|
||||
"r2","r8", \
|
||||
"memory" ); \
|
||||
(type)__res; \
|
||||
})
|
||||
|
||||
#define _hypercall_imm4(type, name, imm, a1, a2, a3, a4) \
|
||||
({ \
|
||||
long __res; \
|
||||
__asm__ __volatile__ (";;\n" \
|
||||
"mov r14=%2\n" \
|
||||
"mov r15=%3\n" \
|
||||
"mov r16=%4\n" \
|
||||
"mov r17=%5\n" \
|
||||
"mov r18=%6\n" \
|
||||
"mov r2=%1\n" \
|
||||
"break 0x1000 ;;\n" \
|
||||
"mov %0=r8 ;;\n" \
|
||||
: "=r" (__res) \
|
||||
: "i" (__HYPERVISOR_##name), \
|
||||
"i" (imm), \
|
||||
"r" ((unsigned long)(a1)), \
|
||||
"r" ((unsigned long)(a2)), \
|
||||
"r" ((unsigned long)(a3)), \
|
||||
"r" ((unsigned long)(a4)) \
|
||||
: "r14","r15","r16","r17","r18", \
|
||||
"r2","r8", \
|
||||
"memory" ); \
|
||||
(type)__res; \
|
||||
})
|
||||
#endif /* CONFIG_XEN */
|
||||
|
||||
static inline unsigned long
|
||||
__HYPERVISOR_ioremap(unsigned long ioaddr, unsigned long size)
|
||||
{
|
||||
return _hypercall_imm2(unsigned long, ia64_dom0vp_op,
|
||||
IA64_DOM0VP_ioremap, ioaddr, size);
|
||||
return _hypercall3(unsigned long, ia64_dom0vp_op,
|
||||
IA64_DOM0VP_ioremap, ioaddr, size);
|
||||
}
|
||||
|
||||
static inline unsigned long
|
||||
@@ -421,8 +345,8 @@ HYPERVISOR_ioremap(unsigned long ioaddr, unsigned long size)
|
||||
static inline unsigned long
|
||||
__HYPERVISOR_phystomach(unsigned long gpfn)
|
||||
{
|
||||
return _hypercall_imm1(unsigned long, ia64_dom0vp_op,
|
||||
IA64_DOM0VP_phystomach, gpfn);
|
||||
return _hypercall2(unsigned long, ia64_dom0vp_op,
|
||||
IA64_DOM0VP_phystomach, gpfn);
|
||||
}
|
||||
|
||||
static inline unsigned long
|
||||
@@ -438,8 +362,8 @@ HYPERVISOR_phystomach(unsigned long gpfn)
|
||||
static inline unsigned long
|
||||
__HYPERVISOR_machtophys(unsigned long mfn)
|
||||
{
|
||||
return _hypercall_imm1(unsigned long, ia64_dom0vp_op,
|
||||
IA64_DOM0VP_machtophys, mfn);
|
||||
return _hypercall2(unsigned long, ia64_dom0vp_op,
|
||||
IA64_DOM0VP_machtophys, mfn);
|
||||
}
|
||||
|
||||
static inline unsigned long
|
||||
@@ -455,8 +379,8 @@ HYPERVISOR_machtophys(unsigned long mfn)
|
||||
static inline unsigned long
|
||||
__HYPERVISOR_zap_physmap(unsigned long gpfn, unsigned int extent_order)
|
||||
{
|
||||
return _hypercall_imm2(unsigned long, ia64_dom0vp_op,
|
||||
IA64_DOM0VP_zap_physmap, gpfn, extent_order);
|
||||
return _hypercall3(unsigned long, ia64_dom0vp_op,
|
||||
IA64_DOM0VP_zap_physmap, gpfn, extent_order);
|
||||
}
|
||||
|
||||
static inline unsigned long
|
||||
@@ -473,9 +397,8 @@ static inline unsigned long
|
||||
__HYPERVISOR_add_physmap(unsigned long gpfn, unsigned long mfn,
|
||||
unsigned long flags, domid_t domid)
|
||||
{
|
||||
return _hypercall_imm4(unsigned long, ia64_dom0vp_op,
|
||||
IA64_DOM0VP_add_physmap, gpfn, mfn, flags,
|
||||
domid);
|
||||
return _hypercall5(unsigned long, ia64_dom0vp_op,
|
||||
IA64_DOM0VP_add_physmap, gpfn, mfn, flags, domid);
|
||||
}
|
||||
|
||||
static inline unsigned long
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
#ifndef __HYPERVISOR_H__
|
||||
#define __HYPERVISOR_H__
|
||||
|
||||
#ifndef CONFIG_XEN
|
||||
#if !defined(CONFIG_XEN) && !defined(CONFIG_VMX_GUEST)
|
||||
#define is_running_on_xen() (0)
|
||||
#define HYPERVISOR_ioremap(offset, size) (offset)
|
||||
#else
|
||||
@@ -41,7 +41,7 @@ extern int running_on_xen;
|
||||
#define is_running_on_xen() (running_on_xen)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_XEN
|
||||
#if defined(CONFIG_XEN) || defined(CONFIG_VMX_GUEST)
|
||||
#include <linux/config.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/kernel.h>
|
||||
@@ -59,10 +59,9 @@ extern int running_on_xen;
|
||||
extern shared_info_t *HYPERVISOR_shared_info;
|
||||
extern start_info_t *xen_start_info;
|
||||
|
||||
#define is_initial_xendomain() (xen_start_info->flags & SIF_INITDOMAIN)
|
||||
|
||||
void force_evtchn_callback(void);
|
||||
|
||||
#ifndef CONFIG_VMX_GUEST
|
||||
/* Turn jiffies into Xen system time. XXX Implement me. */
|
||||
#define jiffies_to_st(j) 0
|
||||
|
||||
@@ -145,10 +144,14 @@ int privcmd_mmap(struct file * file, struct vm_area_struct * vma);
|
||||
#define scrub_pages(_p,_n) ((void)0)
|
||||
#endif
|
||||
#define pte_mfn(_x) pte_pfn(_x)
|
||||
#define __pte_ma(_x) ((pte_t) {(_x)})
|
||||
#define phys_to_machine_mapping_valid(_x) (1)
|
||||
#define pfn_pte_ma(_x,_y) __pte_ma(0)
|
||||
|
||||
#endif /* !CONFIG_VMX_GUEST */
|
||||
|
||||
#define __pte_ma(_x) ((pte_t) {(_x)}) /* unmodified use */
|
||||
#define pfn_pte_ma(_x,_y) __pte_ma(0) /* unmodified use */
|
||||
|
||||
#ifndef CONFIG_VMX_GUEST
|
||||
int __xen_create_contiguous_region(unsigned long vstart, unsigned int order, unsigned int address_bits);
|
||||
static inline int
|
||||
xen_create_contiguous_region(unsigned long vstart,
|
||||
@@ -170,6 +173,8 @@ xen_destroy_contiguous_region(unsigned long vstart, unsigned int order)
|
||||
__xen_destroy_contiguous_region(vstart, order);
|
||||
}
|
||||
|
||||
#endif /* !CONFIG_VMX_GUEST */
|
||||
|
||||
// for netfront.c, netback.c
|
||||
#define MULTI_UVMFLAGS_INDEX 0 //XXX any value
|
||||
|
||||
@@ -182,10 +187,27 @@ MULTI_update_va_mapping(
|
||||
mcl->result = 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
MULTI_grant_table_op(multicall_entry_t *mcl, unsigned int cmd,
|
||||
void *uop, unsigned int count)
|
||||
{
|
||||
mcl->op = __HYPERVISOR_grant_table_op;
|
||||
mcl->args[0] = cmd;
|
||||
mcl->args[1] = (unsigned long)uop;
|
||||
mcl->args[2] = count;
|
||||
}
|
||||
|
||||
// for debug
|
||||
asmlinkage int xprintk(const char *fmt, ...);
|
||||
#define xprintd(fmt, ...) xprintk("%s:%d " fmt, __func__, __LINE__, \
|
||||
##__VA_ARGS__)
|
||||
#endif /* CONFIG_XEN */
|
||||
|
||||
#endif /* CONFIG_XEN || CONFIG_VMX_GUEST */
|
||||
|
||||
#ifdef CONFIG_XEN_PRIVILEGED_GUEST
|
||||
#define is_initial_xendomain() (xen_start_info->flags & SIF_INITDOMAIN)
|
||||
#else
|
||||
#define is_initial_xendomain() 0
|
||||
#endif
|
||||
|
||||
#endif /* __HYPERVISOR_H__ */
|
||||
@@ -97,6 +97,11 @@ extern int valid_mmap_phys_addr_range (unsigned long addr, size_t *count);
|
||||
* The following two macros are deprecated and scheduled for removal.
|
||||
* Please use the PCI-DMA interface defined in <asm/pci.h> instead.
|
||||
*/
|
||||
#ifndef CONFIG_XEN
|
||||
#define bus_to_virt phys_to_virt
|
||||
#define virt_to_bus virt_to_phys
|
||||
#define page_to_bus page_to_phys
|
||||
#else
|
||||
#define bus_to_virt(bus) \
|
||||
phys_to_virt(machine_to_phys_for_dma(bus))
|
||||
#define virt_to_bus(virt) \
|
||||
@@ -124,6 +129,7 @@ extern int valid_mmap_phys_addr_range (unsigned long addr, size_t *count);
|
||||
(((bvec_to_bus((vec1)) + (vec1)->bv_len) == bvec_to_bus((vec2))) && \
|
||||
((bvec_to_pseudophys((vec1)) + (vec1)->bv_len) == \
|
||||
bvec_to_pseudophys((vec2))))
|
||||
#endif /* CONFIG_XEN */
|
||||
|
||||
# endif /* KERNEL */
|
||||
|
||||
|
||||
@@ -247,6 +247,7 @@ extern void machvec_init (const char *name);
|
||||
# error Unknown configuration. Update asm-ia64/machvec.h.
|
||||
# endif /* CONFIG_IA64_GENERIC */
|
||||
|
||||
#ifdef CONFIG_XEN
|
||||
# define platform_dma_map_sg dma_map_sg
|
||||
# define platform_dma_unmap_sg dma_unmap_sg
|
||||
# define platform_dma_mapping_error dma_mapping_error
|
||||
@@ -259,6 +260,7 @@ extern void machvec_init (const char *name);
|
||||
dma_sync_single_for_cpu
|
||||
# define platform_dma_sync_single_for_device \
|
||||
dma_sync_single_for_device
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Declare default routines which aren't declared anywhere else:
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
#ifndef _ASM_IA64_MADDR_H
|
||||
#define _ASM_IA64_MADDR_H
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <asm/hypervisor.h>
|
||||
#include <xen/features.h>
|
||||
#include <xen/interface/xen.h>
|
||||
|
||||
#ifdef CONFIG_XEN
|
||||
|
||||
#define INVALID_P2M_ENTRY (~0UL)
|
||||
|
||||
/* XXX xen page size != page size */
|
||||
static inline unsigned long
|
||||
pfn_to_mfn_for_dma(unsigned long pfn)
|
||||
{
|
||||
unsigned long mfn;
|
||||
mfn = HYPERVISOR_phystomach(pfn);
|
||||
BUG_ON(mfn == 0); // XXX
|
||||
BUG_ON(mfn == INVALID_P2M_ENTRY); // XXX
|
||||
BUG_ON(mfn == INVALID_MFN);
|
||||
return mfn;
|
||||
}
|
||||
|
||||
static inline unsigned long
|
||||
phys_to_machine_for_dma(unsigned long phys)
|
||||
{
|
||||
unsigned long machine =
|
||||
pfn_to_mfn_for_dma(phys >> PAGE_SHIFT) << PAGE_SHIFT;
|
||||
machine |= (phys & ~PAGE_MASK);
|
||||
return machine;
|
||||
}
|
||||
|
||||
static inline unsigned long
|
||||
mfn_to_pfn_for_dma(unsigned long mfn)
|
||||
{
|
||||
unsigned long pfn;
|
||||
pfn = HYPERVISOR_machtophys(mfn);
|
||||
BUG_ON(pfn == 0);
|
||||
//BUG_ON(pfn == INVALID_M2P_ENTRY);
|
||||
return pfn;
|
||||
}
|
||||
|
||||
static inline unsigned long
|
||||
machine_to_phys_for_dma(unsigned long machine)
|
||||
{
|
||||
unsigned long phys =
|
||||
mfn_to_pfn_for_dma(machine >> PAGE_SHIFT) << PAGE_SHIFT;
|
||||
phys |= (machine & ~PAGE_MASK);
|
||||
return phys;
|
||||
}
|
||||
|
||||
static inline unsigned long
|
||||
mfn_to_local_pfn(unsigned long mfn)
|
||||
{
|
||||
extern unsigned long max_mapnr;
|
||||
unsigned long pfn = mfn_to_pfn_for_dma(mfn);
|
||||
if (!pfn_valid(pfn))
|
||||
return INVALID_P2M_ENTRY;
|
||||
return pfn;
|
||||
}
|
||||
|
||||
#else /* !CONFIG_XEN */
|
||||
|
||||
#define pfn_to_mfn_for_dma(pfn) (pfn)
|
||||
#define mfn_to_pfn_for_dma(mfn) (mfn)
|
||||
#define phys_to_machine_for_dma(phys) (phys)
|
||||
#define machine_to_phys_for_dma(machine) (machine)
|
||||
#define mfn_to_local_pfn(mfn) (mfn)
|
||||
|
||||
#endif /* !CONFIG_XEN */
|
||||
|
||||
/* XXX to compile set_phys_to_machine(vaddr, FOREIGN_FRAME(m)) */
|
||||
#define FOREIGN_FRAME(m) (INVALID_P2M_ENTRY)
|
||||
|
||||
#define mfn_to_pfn(mfn) (mfn)
|
||||
#define pfn_to_mfn(pfn) (pfn)
|
||||
|
||||
#define mfn_to_virt(mfn) (__va((mfn) << PAGE_SHIFT))
|
||||
#define virt_to_mfn(virt) (__pa(virt) >> PAGE_SHIFT)
|
||||
#define virt_to_machine(virt) __pa(virt) // for tpmfront.c
|
||||
|
||||
#define set_phys_to_machine(pfn, mfn) do { } while (0)
|
||||
#define xen_machphys_update(mfn, pfn) do { } while (0)
|
||||
|
||||
typedef unsigned long maddr_t; // to compile netback, netfront
|
||||
|
||||
#endif /* _ASM_IA64_MADDR_H */
|
||||
@@ -117,6 +117,9 @@ extern unsigned long max_low_pfn;
|
||||
# define pfn_to_page(pfn) (vmem_map + (pfn))
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_XEN
|
||||
#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT)
|
||||
#endif
|
||||
#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
|
||||
#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT)
|
||||
|
||||
@@ -221,12 +224,9 @@ get_order (unsigned long size)
|
||||
#ifndef __ASSEMBLY__
|
||||
#ifdef CONFIG_XEN
|
||||
|
||||
#define INVALID_P2M_ENTRY (~0UL)
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <asm/hypervisor.h>
|
||||
#include <xen/features.h> // to compile netback, netfront
|
||||
typedef unsigned long maddr_t; // to compile netback, netfront
|
||||
|
||||
/*
|
||||
* XXX hack!
|
||||
@@ -265,68 +265,7 @@ extern struct address_space xen_ia64_foreign_dummy_mapping;
|
||||
})
|
||||
#define HAVE_ARCH_FREE_PAGE
|
||||
|
||||
/* XXX xen page size != page size */
|
||||
|
||||
static inline unsigned long
|
||||
pfn_to_mfn_for_dma(unsigned long pfn)
|
||||
{
|
||||
unsigned long mfn;
|
||||
mfn = HYPERVISOR_phystomach(pfn);
|
||||
BUG_ON(mfn == 0); // XXX
|
||||
BUG_ON(mfn == INVALID_P2M_ENTRY); // XXX
|
||||
BUG_ON(mfn == INVALID_MFN);
|
||||
return mfn;
|
||||
}
|
||||
|
||||
static inline unsigned long
|
||||
phys_to_machine_for_dma(unsigned long phys)
|
||||
{
|
||||
unsigned long machine =
|
||||
pfn_to_mfn_for_dma(phys >> PAGE_SHIFT) << PAGE_SHIFT;
|
||||
machine |= (phys & ~PAGE_MASK);
|
||||
return machine;
|
||||
}
|
||||
|
||||
static inline unsigned long
|
||||
mfn_to_pfn_for_dma(unsigned long mfn)
|
||||
{
|
||||
unsigned long pfn;
|
||||
pfn = HYPERVISOR_machtophys(mfn);
|
||||
BUG_ON(pfn == 0);
|
||||
//BUG_ON(pfn == INVALID_M2P_ENTRY);
|
||||
return pfn;
|
||||
}
|
||||
|
||||
static inline unsigned long
|
||||
machine_to_phys_for_dma(unsigned long machine)
|
||||
{
|
||||
unsigned long phys =
|
||||
mfn_to_pfn_for_dma(machine >> PAGE_SHIFT) << PAGE_SHIFT;
|
||||
phys |= (machine & ~PAGE_MASK);
|
||||
return phys;
|
||||
}
|
||||
|
||||
#define set_phys_to_machine(pfn, mfn) do { } while (0)
|
||||
#define xen_machphys_update(mfn, pfn) do { } while (0)
|
||||
|
||||
/* XXX to compile set_phys_to_machine(vaddr, FOREIGN_FRAME(m)) */
|
||||
#define FOREIGN_FRAME(m) (INVALID_P2M_ENTRY)
|
||||
|
||||
#define mfn_to_pfn(mfn) (mfn)
|
||||
#define mfn_to_virt(mfn) (__va((mfn) << PAGE_SHIFT))
|
||||
#define pfn_to_mfn(pfn) (pfn)
|
||||
#define virt_to_mfn(virt) (__pa(virt) >> PAGE_SHIFT)
|
||||
#define virt_to_machine(virt) __pa(virt) // for tpmfront.c
|
||||
|
||||
static inline unsigned long
|
||||
mfn_to_local_pfn(unsigned long mfn)
|
||||
{
|
||||
extern unsigned long max_mapnr;
|
||||
unsigned long pfn = mfn_to_pfn_for_dma(mfn);
|
||||
if (!pfn_valid(pfn))
|
||||
return INVALID_P2M_ENTRY;
|
||||
return pfn;
|
||||
}
|
||||
#include <asm/maddr.h>
|
||||
|
||||
#endif /* CONFIG_XEN */
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
@@ -126,7 +126,11 @@ static inline void pmd_free(pmd_t * pmd)
|
||||
static inline void
|
||||
pmd_populate(struct mm_struct *mm, pmd_t * pmd_entry, struct page *pte)
|
||||
{
|
||||
#ifndef CONFIG_XEN
|
||||
pmd_val(*pmd_entry) = page_to_phys(pte);
|
||||
#else
|
||||
pmd_val(*pmd_entry) = page_to_pseudophys(pte);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
||||
@@ -18,7 +18,7 @@ cd gdb-6.2.1-linux-i386-xen
|
||||
if [ "$MAKE" ]; then
|
||||
$MAKE
|
||||
elif which gmake ; then
|
||||
gmake -j4
|
||||
gmake -j4 CFLAGS=-D__XEN_TOOLS__
|
||||
else
|
||||
make -j4
|
||||
make -j4 CFLAGS=-D__XEN_TOOLS__
|
||||
fi
|
||||
@@ -37,11 +37,9 @@ name = "ExampleVTIDomain"
|
||||
|
||||
# Optionally define mac and/or bridge for the network interfaces.
|
||||
# Random MACs are assigned if not given.
|
||||
#vif = [ 'type=ioemu, mac=00:16:3e:00:00:11, bridge=xenbr0' ]
|
||||
#vif = [ 'type=ioemu, mac=00:16:3e:00:00:11, bridge=xenbr0, model=ne2k_pci' ]
|
||||
# type=ioemu specify the NIC is an ioemu device not netfront
|
||||
vif = [ 'type=ioemu, bridge=xenbr0' ]
|
||||
# for multiple NICs in device model, 3 in this example
|
||||
#vif = [ 'type=ioemu, bridge=xenbr0', 'type=ioemu', 'type=ioemu']
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Define the disk devices you want the domain to have access to, and
|
||||
@@ -51,7 +49,7 @@ vif = [ 'type=ioemu, bridge=xenbr0' ]
|
||||
# and MODE is r for read-only, w for read-write.
|
||||
|
||||
#disk = [ 'phy:hda1,hda1,r' ]
|
||||
disk = [ 'file:/var/images/xenia64.img,ioemu:hda,w' ]
|
||||
disk = [ 'file:/var/images/xenia64.img,hda,w', ',hdc:cdrom,r' ]
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Set according to whether you want the domain restarted when it exits.
|
||||
@@ -66,13 +64,6 @@ disk = [ 'file:/var/images/xenia64.img,ioemu:hda,w' ]
|
||||
# New stuff
|
||||
device_model = '/usr/' + arch_libdir + '/xen/bin/qemu-dm'
|
||||
|
||||
# Advanced users only. Don't touch if you don't know what you're doing
|
||||
memmap = '/usr/lib/xen/boot/mem-map.sxp'
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Disk image for
|
||||
#cdrom=
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# boot on floppy (a), hard disk (c) or CD-ROM (d)
|
||||
# default: hard disk, cd-rom, floppy
|
||||
@@ -91,8 +82,17 @@ sdl=1
|
||||
vnc=0
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# enable spawning vncviewer(only valid when vnc=1), default = 1
|
||||
vncviewer=0
|
||||
# set VNC display number, default = domid
|
||||
#vncdisplay=1
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# try to find an unused port for the VNC server, default = 1
|
||||
#vncunused=1
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# enable spawning vncviewer for domain's console
|
||||
# (only valid when vnc=1), default = 0
|
||||
#vncconsole=0
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# no graphics, use serial port
|
||||
@@ -108,15 +108,13 @@ stdvga=0
|
||||
serial='pty'
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# enable audio support
|
||||
#enable-audio=1
|
||||
|
||||
# enable sound card support, [sb16|es1370|all|..,..], default none
|
||||
#soundhw='sb16'
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# set the real time clock to local time [default=0 i.e. set to utc]
|
||||
#localtime=1
|
||||
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# start in full screen
|
||||
#full-screen=1 diff -r 42cab8724273 tools/libxc/xc_ia64_stubs.c
|
||||
|
||||
@@ -553,7 +553,6 @@ setup_guest(int xc_handle, uint32_t dom, unsigned long memsize,
|
||||
{
|
||||
unsigned long page_array[2];
|
||||
shared_iopage_t *sp;
|
||||
int i;
|
||||
unsigned long dom_memsize = (memsize << 20);
|
||||
DECLARE_DOMCTL;
|
||||
|
||||
@@ -604,18 +603,6 @@ setup_guest(int xc_handle, uint32_t dom, unsigned long memsize,
|
||||
goto error_out;
|
||||
|
||||
memset(sp, 0, PAGE_SIZE);
|
||||
|
||||
for (i = 0; i < vcpus; i++) {
|
||||
uint32_t vp_eport;
|
||||
|
||||
vp_eport = xc_evtchn_alloc_unbound(xc_handle, dom, 0);
|
||||
if (vp_eport < 0) {
|
||||
DPRINTF("Couldn't get unbound port from VMX guest.\n");
|
||||
goto error_out;
|
||||
}
|
||||
sp->vcpu_iodata[i].vp_eport = vp_eport;
|
||||
}
|
||||
|
||||
munmap(sp, PAGE_SIZE);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -79,7 +79,7 @@ static int xc_ia64_shadow_control(int xc_handle,
|
||||
}
|
||||
|
||||
return xc_shadow_control(xc_handle, domid, sop,
|
||||
dirty_bitmap, pages, stats);
|
||||
dirty_bitmap, pages, NULL, 0, stats);
|
||||
}
|
||||
|
||||
static inline ssize_t
|
||||
|
||||
@@ -36,7 +36,6 @@ xc_ia64_get_pfn_list(int xc_handle, uint32_t domid, xen_pfn_t *pfn_buf,
|
||||
struct xen_domctl domctl;
|
||||
int num_pfns,ret;
|
||||
unsigned int __start_page, __nr_pages;
|
||||
unsigned long max_pfns;
|
||||
xen_pfn_t *__pfn_buf;
|
||||
|
||||
__start_page = start_page;
|
||||
@@ -44,27 +43,22 @@ xc_ia64_get_pfn_list(int xc_handle, uint32_t domid, xen_pfn_t *pfn_buf,
|
||||
__pfn_buf = pfn_buf;
|
||||
|
||||
while (__nr_pages) {
|
||||
max_pfns = ((unsigned long)__start_page << 32) | __nr_pages;
|
||||
domctl.cmd = XEN_DOMCTL_getmemlist;
|
||||
domctl.domain = (domid_t)domid;
|
||||
domctl.u.getmemlist.max_pfns = max_pfns;
|
||||
domctl.domain = (domid_t)domid;
|
||||
domctl.u.getmemlist.max_pfns = __nr_pages;
|
||||
domctl.u.getmemlist.start_pfn =__start_page;
|
||||
domctl.u.getmemlist.num_pfns = 0;
|
||||
set_xen_guest_handle(domctl.u.getmemlist.buffer, __pfn_buf);
|
||||
|
||||
if ((max_pfns != -1UL)
|
||||
&& mlock(__pfn_buf, __nr_pages * sizeof(xen_pfn_t)) != 0) {
|
||||
if (mlock(__pfn_buf, __nr_pages * sizeof(xen_pfn_t)) != 0) {
|
||||
PERROR("Could not lock pfn list buffer");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = do_domctl(xc_handle, &domctl);
|
||||
|
||||
if (max_pfns != -1UL)
|
||||
(void)munlock(__pfn_buf, __nr_pages * sizeof(xen_pfn_t));
|
||||
(void)munlock(__pfn_buf, __nr_pages * sizeof(xen_pfn_t));
|
||||
|
||||
if (max_pfns == -1UL)
|
||||
return 0;
|
||||
|
||||
num_pfns = domctl.u.getmemlist.num_pfns;
|
||||
__start_page += num_pfns;
|
||||
__nr_pages -= num_pfns;
|
||||
|
||||
@@ -31,7 +31,6 @@ void foo(void)
|
||||
DEFINE(IA64_SWITCH_STACK_SIZE, sizeof (struct switch_stack));
|
||||
DEFINE(IA64_CPU_SIZE, sizeof (struct cpuinfo_ia64));
|
||||
DEFINE(UNW_FRAME_INFO_SIZE, sizeof (struct unw_frame_info));
|
||||
DEFINE(SHARED_INFO_SIZE, sizeof (struct shared_info));
|
||||
DEFINE(MAPPED_REGS_T_SIZE, sizeof (mapped_regs_t));
|
||||
|
||||
BLANK();
|
||||
|
||||
@@ -292,28 +292,6 @@ efi_memmap_walk_uc (efi_freemem_callback_t callback, void *arg)
|
||||
walk(callback, arg, EFI_MEMORY_UC);
|
||||
}
|
||||
|
||||
#ifdef XEN
|
||||
void
|
||||
efi_memmap_walk_type(u32 type, efi_walk_type_callback_t callback, void *arg)
|
||||
{
|
||||
void *efi_map_start, *efi_map_end, *p;
|
||||
efi_memory_desc_t *md;
|
||||
u64 efi_desc_size;
|
||||
|
||||
efi_map_start = __va(ia64_boot_param->efi_memmap);
|
||||
efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
|
||||
efi_desc_size = ia64_boot_param->efi_memdesc_size;
|
||||
|
||||
for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
|
||||
md = p;
|
||||
if (md->type == type) {
|
||||
if ((*callback)(md, arg) < 0)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Look for the PAL_CODE region reported by EFI and maps it using an
|
||||
* ITR to enable safe PAL calls in virtual mode. See IA-64 Processor
|
||||
|
||||
@@ -77,6 +77,8 @@
|
||||
#include <linux/list.h>
|
||||
#ifndef XEN
|
||||
#include <linux/pci.h>
|
||||
#else
|
||||
#include <xen/errno.h>
|
||||
#endif
|
||||
#include <linux/smp.h>
|
||||
#include <linux/smp_lock.h>
|
||||
|
||||
@@ -40,6 +40,10 @@
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/system.h>
|
||||
|
||||
#ifdef XEN
|
||||
#include <xen/perfc.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PERFMON
|
||||
# include <asm/perfmon.h>
|
||||
#endif
|
||||
@@ -108,6 +112,9 @@ ia64_handle_irq (ia64_vector vector, struct pt_regs *regs)
|
||||
{
|
||||
unsigned long saved_tpr;
|
||||
|
||||
#ifdef XEN
|
||||
perfc_incrc(irqs);
|
||||
#endif
|
||||
#if IRQ_DEBUG
|
||||
#ifdef XEN
|
||||
xen_debug_irq(vector, regs);
|
||||
@@ -290,8 +297,5 @@ ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect)
|
||||
ipi_data = (delivery_mode << 8) | (vector & 0xff);
|
||||
ipi_addr = ipi_base_addr + ((phys_cpu_id << 4) | ((redirect & 1) << 3));
|
||||
|
||||
#ifdef XEN
|
||||
//printf ("send_ipi to %d (%x)\n", cpu, phys_cpu_id);
|
||||
#endif
|
||||
writeq(ipi_data, ipi_addr);
|
||||
}
|
||||
@@ -79,6 +79,7 @@
|
||||
|
||||
#ifdef XEN
|
||||
#include <xen/symbols.h>
|
||||
#include <xen/mm.h>
|
||||
#endif
|
||||
|
||||
#if defined(IA64_MCA_DEBUG_INFO)
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <xen/lib.h>
|
||||
#include <xen/symbols.h>
|
||||
#include <xen/smp.h>
|
||||
#include <xen/sched.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/ptrace.h>
|
||||
@@ -166,6 +167,7 @@ show_regs (struct pt_regs *regs)
|
||||
printk("r26 : %016lx r27 : %016lx r28 : %016lx\n", regs->r26, regs->r27, regs->r28);
|
||||
printk("r29 : %016lx r30 : %016lx r31 : %016lx\n", regs->r29, regs->r30, regs->r31);
|
||||
|
||||
#ifndef XEN
|
||||
if (user_mode(regs)) {
|
||||
/* print the stacked registers */
|
||||
unsigned long val, *bsp, ndirty;
|
||||
@@ -180,6 +182,7 @@ show_regs (struct pt_regs *regs)
|
||||
((i == sof - 1) || (i % 3) == 2) ? "\n" : " ");
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
show_stack(NULL, NULL);
|
||||
}
|
||||
|
||||
@@ -807,6 +810,7 @@ get_wchan (struct task_struct *p)
|
||||
} while (count++ < 16);
|
||||
return 0;
|
||||
}
|
||||
#endif // !XEN
|
||||
|
||||
void
|
||||
cpu_halt (void)
|
||||
@@ -831,6 +835,7 @@ cpu_halt (void)
|
||||
ia64_pal_halt(min_power_state);
|
||||
}
|
||||
|
||||
#ifndef XEN
|
||||
void
|
||||
machine_restart (char *restart_cmd)
|
||||
{
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
#include <asm/unistd.h>
|
||||
#include <asm/mca.h>
|
||||
#ifdef XEN
|
||||
#include <xen/errno.h>
|
||||
#include <asm/vhpt.h>
|
||||
#include <asm/hw_irq.h>
|
||||
#endif
|
||||
@@ -146,6 +147,9 @@ handle_IPI (int irq, void *dev_id, struct pt_regs *regs)
|
||||
unsigned long *pending_ipis = &__ia64_per_cpu_var(ipi_operation);
|
||||
unsigned long ops;
|
||||
|
||||
#ifdef XEN
|
||||
perfc_incrc(ipis);
|
||||
#endif
|
||||
mb(); /* Order interrupt and bit testing. */
|
||||
while ((ops = xchg(pending_ipis, 0)) != 0) {
|
||||
mb(); /* Order bit clearing and data access. */
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <xen/sched.h>
|
||||
#include <xen/xmalloc.h>
|
||||
#include <xen/spinlock.h>
|
||||
#include <xen/errno.h>
|
||||
|
||||
// work around
|
||||
#ifdef CONFIG_SMP
|
||||
@@ -2315,6 +2316,7 @@ unw_init (void)
|
||||
__start_unwind, __end_unwind);
|
||||
}
|
||||
|
||||
#ifndef XEN
|
||||
/*
|
||||
* DEPRECATED DEPRECATED DEPRECATED DEPRECATED DEPRECATED DEPRECATED DEPRECATED
|
||||
*
|
||||
@@ -2353,3 +2355,4 @@ sys_getunwind (void __user *buf, size_t buf_size)
|
||||
return -EFAULT;
|
||||
return unw.gate_table_size;
|
||||
}
|
||||
#endif
|
||||
@@ -1,5 +1,5 @@
|
||||
obj-y += hvm_vioapic.o
|
||||
obj-y += mm.o
|
||||
#obj-y += mm.o
|
||||
obj-y += mmio.o
|
||||
obj-y += pal_emul.o
|
||||
obj-y += vlsapic.o
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/sched.h>
|
||||
#include <xen/mm.h>
|
||||
#include <asm/tlb.h>
|
||||
#include <asm/vmx_mm_def.h>
|
||||
#include <asm/gcc_intrin.h>
|
||||
@@ -30,7 +31,6 @@
|
||||
#include <asm/bundle.h>
|
||||
#include <asm/types.h>
|
||||
#include <public/hvm/ioreq.h>
|
||||
#include <asm/mm.h>
|
||||
#include <asm/vmx.h>
|
||||
#include <public/event_channel.h>
|
||||
#include <public/xen.h>
|
||||
@@ -155,10 +155,9 @@ static void low_mmio_access(VCPU *vcpu, u64 pa, u64 *val, size_t s, int dir)
|
||||
p->type = 1;
|
||||
p->df = 0;
|
||||
|
||||
set_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags);
|
||||
p->state = STATE_IOREQ_READY;
|
||||
evtchn_send(iopacket_port(v));
|
||||
vmx_wait_io();
|
||||
p->io_count++;
|
||||
|
||||
vmx_send_assist_req(v);
|
||||
if(dir==IOREQ_READ){ //read
|
||||
*val=p->u.data;
|
||||
}
|
||||
@@ -187,11 +186,9 @@ static void legacy_io_access(VCPU *vcpu, u64 pa, u64 *val, size_t s, int dir)
|
||||
p->type = 0;
|
||||
p->df = 0;
|
||||
|
||||
set_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags);
|
||||
p->state = STATE_IOREQ_READY;
|
||||
evtchn_send(iopacket_port(v));
|
||||
p->io_count++;
|
||||
|
||||
vmx_wait_io();
|
||||
vmx_send_assist_req(v);
|
||||
if(dir==IOREQ_READ){ //read
|
||||
*val=p->u.data;
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <asm/kregs.h>
|
||||
#include <asm/vcpu.h>
|
||||
#include <xen/irq.h>
|
||||
#include <xen/errno.h>
|
||||
|
||||
/*
|
||||
* Get the machine page frame number in 16KB unit
|
||||
|
||||
@@ -59,21 +59,23 @@ do_hvm_op(unsigned long op, XEN_GUEST_HANDLE(void) arg)
|
||||
}
|
||||
else if (IS_PRIV(current->domain)) {
|
||||
d = find_domain_by_id(a.domid);
|
||||
if (!d)
|
||||
if (d == NULL)
|
||||
return -ESRCH;
|
||||
}
|
||||
else
|
||||
return -EPERM;
|
||||
|
||||
if (op == HVMOP_set_param) {
|
||||
rc = 0;
|
||||
d->arch.hvm_domain.params[a.index] = a.value;
|
||||
rc = 0;
|
||||
}
|
||||
else {
|
||||
a.value = d->arch.hvm_domain.params[a.index];
|
||||
rc = copy_to_guest(arg, &a, 1) ? -EFAULT : 0;
|
||||
}
|
||||
else
|
||||
rc = d->arch.hvm_domain.params[a.index];
|
||||
|
||||
put_domain(d);
|
||||
return rc;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
|
||||
@@ -206,7 +206,7 @@ vmx_create_vp(struct vcpu *v)
|
||||
u64 ret;
|
||||
vpd_t *vpd = (vpd_t *)v->arch.privregs;
|
||||
u64 ivt_base;
|
||||
extern char vmx_ia64_ivt;
|
||||
extern char vmx_ia64_ivt;
|
||||
/* ia64_ivt is function pointer, so need this tranlation */
|
||||
ivt_base = (u64) &vmx_ia64_ivt;
|
||||
printk("ivt_base: 0x%lx\n", ivt_base);
|
||||
@@ -265,6 +265,29 @@ vmx_load_state(struct vcpu *v)
|
||||
* anchored in vcpu */
|
||||
}
|
||||
|
||||
static void vmx_create_event_channels(struct vcpu *v)
|
||||
{
|
||||
vcpu_iodata_t *p;
|
||||
struct vcpu *o;
|
||||
|
||||
if (v->vcpu_id == 0) {
|
||||
/* Ugly: create event channels for every vcpu when vcpu 0
|
||||
starts, so that they're available for ioemu to bind to. */
|
||||
for_each_vcpu(v->domain, o) {
|
||||
p = get_vio(v->domain, o->vcpu_id);
|
||||
o->arch.arch_vmx.xen_port = p->vp_eport =
|
||||
alloc_unbound_xen_event_channel(o, 0);
|
||||
DPRINTK("Allocated port %d for hvm.\n",
|
||||
o->arch.arch_vmx.xen_port);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void vmx_release_assist_channel(struct vcpu *v)
|
||||
{
|
||||
free_xen_event_channel(v, v->arch.arch_vmx.xen_port);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize VMX envirenment for guest. Only the 1st vp/vcpu
|
||||
* is registered here.
|
||||
@@ -286,6 +309,8 @@ vmx_final_setup_guest(struct vcpu *v)
|
||||
#ifndef HASH_VHPT
|
||||
init_domain_tlb(v);
|
||||
#endif
|
||||
vmx_create_event_channels(v);
|
||||
|
||||
/* v->arch.schedule_tail = arch_vmx_do_launch; */
|
||||
vmx_create_vp(v);
|
||||
|
||||
@@ -303,6 +328,15 @@ vmx_final_setup_guest(struct vcpu *v)
|
||||
set_bit(ARCH_VMX_DOMAIN, &v->arch.arch_vmx.flags);
|
||||
}
|
||||
|
||||
void
|
||||
vmx_relinquish_guest_resources(struct domain *d)
|
||||
{
|
||||
struct vcpu *v;
|
||||
|
||||
for_each_vcpu(d, v)
|
||||
vmx_release_assist_channel(v);
|
||||
}
|
||||
|
||||
void
|
||||
vmx_relinquish_vcpu_resources(struct vcpu *v)
|
||||
{
|
||||
@@ -411,6 +445,9 @@ void vmx_setup_platform(struct domain *d)
|
||||
memset(&d->shared_info->evtchn_mask[0], 0xff,
|
||||
sizeof(d->shared_info->evtchn_mask));
|
||||
|
||||
/* initiate spinlock for pass virq */
|
||||
spin_lock_init(&d->arch.arch_vmx.virq_assist_lock);
|
||||
|
||||
/* Initialize the virtual interrupt lines */
|
||||
vmx_virq_line_init(d);
|
||||
|
||||
@@ -420,13 +457,5 @@ void vmx_setup_platform(struct domain *d)
|
||||
|
||||
void vmx_do_launch(struct vcpu *v)
|
||||
{
|
||||
if (evtchn_bind_vcpu(iopacket_port(v), v->vcpu_id) < 0) {
|
||||
printk("VMX domain bind port %d to vcpu %d failed!\n",
|
||||
iopacket_port(v), v->vcpu_id);
|
||||
domain_crash_synchronous();
|
||||
}
|
||||
|
||||
clear_bit(iopacket_port(v), &v->domain->shared_info->evtchn_mask[0]);
|
||||
|
||||
vmx_load_all_rr(v);
|
||||
}
|
||||
@@ -195,7 +195,8 @@ vmx_load_all_rr(VCPU *vcpu)
|
||||
(void *)vcpu->domain->shared_info,
|
||||
(void *)vcpu->arch.privregs,
|
||||
(void *)vcpu->arch.vhpt.hash, pal_vaddr );
|
||||
ia64_set_pta(vcpu->arch.arch_vmx.mpta);
|
||||
ia64_set_pta(VMX(vcpu, mpta));
|
||||
ia64_set_dcr(VMX(vcpu, mdcr));
|
||||
|
||||
ia64_srlz_d();
|
||||
ia64_set_psr(psr);
|
||||
|
||||
@@ -186,6 +186,7 @@ void leave_hypervisor_tail(struct pt_regs *regs)
|
||||
{
|
||||
struct domain *d = current->domain;
|
||||
struct vcpu *v = current;
|
||||
int callback_irq;
|
||||
// FIXME: Will this work properly if doing an RFI???
|
||||
if (!is_idle_domain(d) ) { // always comes from guest
|
||||
// struct pt_regs *user_regs = vcpu_regs(current);
|
||||
@@ -213,6 +214,13 @@ void leave_hypervisor_tail(struct pt_regs *regs)
|
||||
// v->arch.irq_new_pending = 1;
|
||||
// }
|
||||
|
||||
callback_irq = d->arch.hvm_domain.params[HVM_PARAM_CALLBACK_IRQ];
|
||||
if (callback_irq != 0 && local_events_need_delivery()) {
|
||||
/*inject para-device call back irq*/
|
||||
v->vcpu_info->evtchn_upcall_mask = 1;
|
||||
vmx_vcpu_pend_interrupt(v, callback_irq);
|
||||
}
|
||||
|
||||
if ( v->arch.irq_new_pending ) {
|
||||
v->arch.irq_new_pending = 0;
|
||||
v->arch.irq_new_condition = 0;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
/* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */
|
||||
/*
|
||||
* vmx_support.c: vmx specific support interface.
|
||||
@@ -22,46 +21,12 @@
|
||||
#include <xen/config.h>
|
||||
#include <xen/sched.h>
|
||||
#include <xen/hypercall.h>
|
||||
#include <xen/event.h>
|
||||
#include <public/sched.h>
|
||||
#include <public/hvm/ioreq.h>
|
||||
#include <asm/vmx.h>
|
||||
#include <asm/vmx_vcpu.h>
|
||||
|
||||
/*
|
||||
* I/O emulation should be atomic from domain point of view. However,
|
||||
* when emulation code is waiting for I/O completion by blocking,
|
||||
* other events like DM interrupt, VBD, etc. may come and unblock
|
||||
* current exection flow. So we have to prepare for re-block if unblocked
|
||||
* by non I/O completion event. After io emulation is done, re-enable
|
||||
* pending indicaion if other ports are pending
|
||||
*/
|
||||
void vmx_wait_io(void)
|
||||
{
|
||||
struct vcpu *v = current;
|
||||
struct domain *d = v->domain;
|
||||
int port = iopacket_port(v);
|
||||
|
||||
for (;;) {
|
||||
if (test_and_clear_bit(0, &v->vcpu_info->evtchn_upcall_pending) &&
|
||||
test_and_clear_bit(port / BITS_PER_LONG,
|
||||
&v->vcpu_info->evtchn_pending_sel) &&
|
||||
test_and_clear_bit(port, &d->shared_info->evtchn_pending[0]))
|
||||
vmx_io_assist(v);
|
||||
|
||||
if (!test_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags))
|
||||
break;
|
||||
|
||||
do_sched_op_compat(SCHEDOP_block, 0);
|
||||
}
|
||||
|
||||
/* re-enable indication if other pending events */
|
||||
if (d->shared_info->evtchn_pending[port / BITS_PER_LONG])
|
||||
set_bit(port / BITS_PER_LONG, &v->vcpu_info->evtchn_pending_sel);
|
||||
|
||||
if (v->vcpu_info->evtchn_pending_sel)
|
||||
set_bit(0, &v->vcpu_info->evtchn_upcall_pending);
|
||||
}
|
||||
|
||||
/*
|
||||
* Only place to call vmx_io_assist is mmio/legacy_io emulation.
|
||||
* Since I/O emulation is synchronous, it shouldn't be called in
|
||||
@@ -83,17 +48,15 @@ void vmx_io_assist(struct vcpu *v)
|
||||
|
||||
p = &vio->vp_ioreq;
|
||||
|
||||
if (test_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags)) {
|
||||
if (p->state != STATE_IORESP_READY) {
|
||||
/* Can't block here, for the same reason as other places to
|
||||
* use vmx_wait_io. Simple return is safe since vmx_wait_io will
|
||||
* try to block again
|
||||
*/
|
||||
return;
|
||||
} else
|
||||
p->state = STATE_INVALID;
|
||||
|
||||
clear_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags);
|
||||
if (p->state == STATE_IORESP_READY) {
|
||||
p->state = STATE_INVALID;
|
||||
}
|
||||
else {
|
||||
/* Can't block here, for the same reason as other places to
|
||||
* use vmx_wait_io. Simple return is safe since vmx_wait_io will
|
||||
* try to block again
|
||||
*/
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,35 +71,62 @@ void vmx_io_assist(struct vcpu *v)
|
||||
*/
|
||||
void vmx_intr_assist(struct vcpu *v)
|
||||
{
|
||||
vcpu_iodata_t *vio;
|
||||
struct domain *d = v->domain;
|
||||
extern void vmx_vcpu_pend_batch_interrupt(VCPU *vcpu,
|
||||
unsigned long *pend_irr);
|
||||
int port = iopacket_port(v);
|
||||
|
||||
if (test_bit(port, &d->shared_info->evtchn_pending[0]) ||
|
||||
test_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags))
|
||||
vmx_wait_io();
|
||||
|
||||
/* I/O emulation is atomic, so it's impossible to see execution flow
|
||||
* out of vmx_wait_io, when guest is still waiting for response.
|
||||
*/
|
||||
if (test_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags))
|
||||
panic_domain(vcpu_regs(v),"!!!Bad resume to guest before I/O emulation is done.\n");
|
||||
|
||||
/* Even without event pending, we still need to sync pending bits
|
||||
* between DM and vlsapic. The reason is that interrupt delivery
|
||||
* shares same event channel as I/O emulation, with corresponding
|
||||
* indicator possibly cleared when vmx_wait_io().
|
||||
*/
|
||||
vio = get_vio(v->domain, v->vcpu_id);
|
||||
if (!vio)
|
||||
panic_domain(vcpu_regs(v),"Corruption: bad shared page: %lx\n", (unsigned long)vio);
|
||||
|
||||
#ifdef V_IOSAPIC_READY
|
||||
/* Confirm virtual interrupt line signals, and set pending bits in vpd */
|
||||
if(v->vcpu_id==0)
|
||||
if (spin_trylock(&v->domain->arch.arch_vmx.virq_assist_lock)) {
|
||||
vmx_virq_line_assist(v);
|
||||
spin_unlock(&v->domain->arch.arch_vmx.virq_assist_lock);
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
void vmx_send_assist_req(struct vcpu *v)
|
||||
{
|
||||
ioreq_t *p;
|
||||
|
||||
p = &get_vio(v->domain, v->vcpu_id)->vp_ioreq;
|
||||
if (unlikely(p->state != STATE_INVALID)) {
|
||||
/* This indicates a bug in the device model. Crash the
|
||||
domain. */
|
||||
printk("Device model set bad IO state %d.\n", p->state);
|
||||
domain_crash(v->domain);
|
||||
return;
|
||||
}
|
||||
wmb();
|
||||
p->state = STATE_IOREQ_READY;
|
||||
notify_via_xen_event_channel(v->arch.arch_vmx.xen_port);
|
||||
|
||||
/*
|
||||
* Waiting for MMIO completion
|
||||
* like the wait_on_xen_event_channel() macro like...
|
||||
* but, we can't call do_softirq() at this point..
|
||||
*/
|
||||
for (;;) {
|
||||
if (p->state != STATE_IOREQ_READY &&
|
||||
p->state != STATE_IOREQ_INPROCESS)
|
||||
break;
|
||||
|
||||
set_bit(_VCPUF_blocked_in_xen, ¤t->vcpu_flags);
|
||||
mb(); /* set blocked status /then/ re-evaluate condition */
|
||||
if (p->state != STATE_IOREQ_READY &&
|
||||
p->state != STATE_IOREQ_INPROCESS)
|
||||
{
|
||||
clear_bit(_VCPUF_blocked_in_xen, ¤t->vcpu_flags);
|
||||
break;
|
||||
}
|
||||
|
||||
/* I want to call __enter_scheduler() only */
|
||||
do_sched_op_compat(SCHEDOP_yield, 0);
|
||||
mb();
|
||||
}
|
||||
|
||||
/* the code under this line is completer phase... */
|
||||
vmx_io_assist(v);
|
||||
}
|
||||
|
||||
/* Wake up a vcpu whihc is waiting for interrupts to come in */
|
||||
void vmx_prod_vcpu(struct vcpu *v)
|
||||
{
|
||||
vcpu_unblock(v);
|
||||
}
|
||||
+54
-47
@@ -23,7 +23,7 @@
|
||||
|
||||
#include <linux/sched.h>
|
||||
#include <asm/tlb.h>
|
||||
#include <asm/mm.h>
|
||||
#include <xen/mm.h>
|
||||
#include <asm/vmx_mm_def.h>
|
||||
#include <asm/gcc_intrin.h>
|
||||
#include <linux/interrupt.h>
|
||||
@@ -148,13 +148,17 @@ static void vmx_vhpt_insert(thash_cb_t *hcb, u64 pte, u64 itir, u64 ifa)
|
||||
rr.rrval = ia64_get_rr(ifa);
|
||||
head = (thash_data_t *)ia64_thash(ifa);
|
||||
tag = ia64_ttag(ifa);
|
||||
if( INVALID_VHPT(head) ) {
|
||||
len = head->len;
|
||||
head->page_flags = pte;
|
||||
head->len = len;
|
||||
head->itir = rr.ps << 2;
|
||||
head->etag = tag;
|
||||
return;
|
||||
cch = head;
|
||||
while (cch) {
|
||||
if (INVALID_VHPT(cch)) {
|
||||
len = cch->len;
|
||||
cch->page_flags = pte;
|
||||
cch->len = len;
|
||||
cch->itir = rr.ps << 2;
|
||||
cch->etag = tag;
|
||||
return;
|
||||
}
|
||||
cch = cch->next;
|
||||
}
|
||||
|
||||
if(head->len>=MAX_CCN_DEPTH){
|
||||
@@ -214,12 +218,22 @@ u64 guest_vhpt_lookup(u64 iha, u64 *pte)
|
||||
{
|
||||
u64 ret;
|
||||
thash_data_t * data;
|
||||
PTA vpta;
|
||||
|
||||
data = vhpt_lookup(iha);
|
||||
if (data == NULL) {
|
||||
data = vtlb_lookup(current, iha, DSIDE_TLB);
|
||||
if (data != NULL)
|
||||
thash_vhpt_insert(current, data->page_flags, data->itir ,iha);
|
||||
}
|
||||
|
||||
/* VHPT long format is not read. */
|
||||
vmx_vcpu_get_pta(current, &vpta.val);
|
||||
if (vpta.vf == 1) {
|
||||
*pte = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
asm volatile ("rsm psr.ic|psr.i;;"
|
||||
"srlz.d;;"
|
||||
"ld8.s r9=[%1];;"
|
||||
@@ -231,11 +245,10 @@ u64 guest_vhpt_lookup(u64 iha, u64 *pte)
|
||||
"ssm psr.ic;;"
|
||||
"srlz.d;;"
|
||||
"ssm psr.i;;"
|
||||
: "=r"(ret) : "r"(iha), "r"(pte):"memory");
|
||||
: "=r"(ret) : "r"(iha), "r"(pte):"memory");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* purge software guest tlb
|
||||
*/
|
||||
@@ -243,28 +256,29 @@ u64 guest_vhpt_lookup(u64 iha, u64 *pte)
|
||||
void vtlb_purge(VCPU *v, u64 va, u64 ps)
|
||||
{
|
||||
thash_data_t *cur;
|
||||
u64 start, end, curadr, size, psbits, tag, def_size;
|
||||
u64 start, curadr, size, psbits, tag, rr_ps, num;
|
||||
ia64_rr vrr;
|
||||
thash_cb_t *hcb = &v->arch.vtlb;
|
||||
|
||||
vcpu_get_rr(v, va, &vrr.rrval);
|
||||
psbits = VMX(v, psbits[(va >> 61)]);
|
||||
size = PSIZE(ps);
|
||||
start = va & (-size);
|
||||
end = start + size;
|
||||
start = va & ~((1UL << ps) - 1);
|
||||
while (psbits) {
|
||||
curadr = start;
|
||||
ps = __ffs(psbits);
|
||||
psbits &= ~(1UL << ps);
|
||||
def_size = PSIZE(ps);
|
||||
vrr.ps = ps;
|
||||
while (curadr < end) {
|
||||
rr_ps = __ffs(psbits);
|
||||
psbits &= ~(1UL << rr_ps);
|
||||
num = 1UL << ((ps < rr_ps) ? 0 : (ps - rr_ps));
|
||||
size = PSIZE(rr_ps);
|
||||
vrr.ps = rr_ps;
|
||||
while (num) {
|
||||
cur = vsa_thash(hcb->pta, curadr, vrr.rrval, &tag);
|
||||
while (cur) {
|
||||
if (cur->etag == tag && cur->ps == ps)
|
||||
if (cur->etag == tag && cur->ps == rr_ps)
|
||||
cur->etag = 1UL << 63;
|
||||
cur = cur->next;
|
||||
}
|
||||
curadr += def_size;
|
||||
curadr += size;
|
||||
num--;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -277,14 +291,14 @@ static void vhpt_purge(VCPU *v, u64 va, u64 ps)
|
||||
{
|
||||
//thash_cb_t *hcb = &v->arch.vhpt;
|
||||
thash_data_t *cur;
|
||||
u64 start, end, size, tag;
|
||||
u64 start, size, tag, num;
|
||||
ia64_rr rr;
|
||||
size = PSIZE(ps);
|
||||
start = va & (-size);
|
||||
end = start + size;
|
||||
rr.rrval = ia64_get_rr(va);
|
||||
size = PSIZE(rr.ps);
|
||||
while(start < end){
|
||||
|
||||
start = va & ~((1UL << ps) - 1);
|
||||
rr.rrval = ia64_get_rr(va);
|
||||
size = PSIZE(rr.ps);
|
||||
num = 1UL << ((ps < rr.ps) ? 0 : (ps - rr.ps));
|
||||
while (num) {
|
||||
cur = (thash_data_t *)ia64_thash(start);
|
||||
tag = ia64_ttag(start);
|
||||
while (cur) {
|
||||
@@ -293,6 +307,7 @@ static void vhpt_purge(VCPU *v, u64 va, u64 ps)
|
||||
cur = cur->next;
|
||||
}
|
||||
start += size;
|
||||
num--;
|
||||
}
|
||||
machine_tlb_purge(va, ps);
|
||||
}
|
||||
@@ -347,24 +362,20 @@ void vtlb_insert(VCPU *v, u64 pte, u64 itir, u64 va)
|
||||
u64 tag, len;
|
||||
thash_cb_t *hcb = &v->arch.vtlb;
|
||||
vcpu_get_rr(v, va, &vrr.rrval);
|
||||
#ifdef VTLB_DEBUG
|
||||
if (vrr.ps != itir_ps(itir)) {
|
||||
// machine_tlb_insert(hcb->vcpu, entry);
|
||||
panic_domain(NULL, "not preferred ps with va: 0x%lx vrr.ps=%d ps=%ld\n",
|
||||
va, vrr.ps, itir_ps(itir));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
vrr.ps = itir_ps(itir);
|
||||
VMX(v, psbits[va >> 61]) |= (1UL << vrr.ps);
|
||||
hash_table = vsa_thash(hcb->pta, va, vrr.rrval, &tag);
|
||||
if( INVALID_TLB(hash_table) ) {
|
||||
len = hash_table->len;
|
||||
hash_table->page_flags = pte;
|
||||
hash_table->len = len;
|
||||
hash_table->itir=itir;
|
||||
hash_table->etag=tag;
|
||||
return;
|
||||
cch = hash_table;
|
||||
while (cch) {
|
||||
if (INVALID_TLB(cch)) {
|
||||
len = cch->len;
|
||||
cch->page_flags = pte;
|
||||
cch->len = len;
|
||||
cch->itir=itir;
|
||||
cch->etag=tag;
|
||||
return;
|
||||
}
|
||||
cch = cch->next;
|
||||
}
|
||||
if (hash_table->len>=MAX_CCN_DEPTH){
|
||||
thash_recycle_cch(hcb, hash_table);
|
||||
@@ -458,10 +469,6 @@ void thash_purge_and_insert(VCPU *v, u64 pte, u64 itir, u64 ifa, int type)
|
||||
ps = itir_ps(itir);
|
||||
vcpu_get_rr(current, ifa, &vrr.rrval);
|
||||
mrr.rrval = ia64_get_rr(ifa);
|
||||
// if (vrr.ps != itir_ps(itir)) {
|
||||
// printf("not preferred ps with va: 0x%lx vrr.ps=%d ps=%ld\n",
|
||||
// ifa, vrr.ps, itir_ps(itir));
|
||||
// }
|
||||
if(VMX_DOMAIN(v)){
|
||||
/* Ensure WB attribute if pte is related to a normal mem page,
|
||||
* which is required by vga acceleration since qemu maps shared
|
||||
|
||||
@@ -51,6 +51,9 @@
|
||||
#include <asm/numa.h>
|
||||
#include <asm/sal.h>
|
||||
#include <asm/hw_irq.h>
|
||||
#ifdef XEN
|
||||
#include <xen/errno.h>
|
||||
#endif
|
||||
|
||||
#define BAD_MADT_ENTRY(entry, end) ( \
|
||||
(!entry) || (unsigned long)entry + sizeof(*entry) > end || \
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <asm/vmx.h>
|
||||
#include <asm/dom_fw.h>
|
||||
#include <xen/iocap.h>
|
||||
#include <xen/errno.h>
|
||||
|
||||
void build_physmap_table(struct domain *d);
|
||||
|
||||
@@ -39,8 +40,8 @@ long arch_do_domctl(xen_domctl_t *op, XEN_GUEST_HANDLE(xen_domctl_t) u_domctl)
|
||||
{
|
||||
unsigned long i;
|
||||
struct domain *d = find_domain_by_id(op->domain);
|
||||
unsigned long start_page = op->u.getmemlist.max_pfns >> 32;
|
||||
unsigned long nr_pages = op->u.getmemlist.max_pfns & 0xffffffff;
|
||||
unsigned long start_page = op->u.getmemlist.start_pfn;
|
||||
unsigned long nr_pages = op->u.getmemlist.max_pfns;
|
||||
unsigned long mfn;
|
||||
|
||||
if ( d == NULL ) {
|
||||
|
||||
+451
-464
File diff suppressed because it is too large.
Load diff
@@ -46,7 +46,6 @@
|
||||
#include <asm/regionreg.h>
|
||||
#include <asm/dom_fw.h>
|
||||
#include <asm/shadow.h>
|
||||
#include <asm/privop_stat.h>
|
||||
|
||||
unsigned long dom0_size = 512*1024*1024;
|
||||
unsigned long dom0_align = 64*1024*1024;
|
||||
@@ -111,6 +110,8 @@ void schedule_tail(struct vcpu *prev)
|
||||
|
||||
if (VMX_DOMAIN(current)) {
|
||||
vmx_do_launch(current);
|
||||
migrate_timer(¤t->arch.arch_vmx.vtm.vtm_timer,
|
||||
current->processor);
|
||||
} else {
|
||||
ia64_set_iva(&ia64_ivt);
|
||||
ia64_set_pta(VHPT_ADDR | (1 << 8) | (VHPT_SIZE_LOG2 << 2) |
|
||||
@@ -121,6 +122,7 @@ void schedule_tail(struct vcpu *prev)
|
||||
shared_info->vcpu_info[current->vcpu_id].evtchn_upcall_mask;
|
||||
__ia64_per_cpu_var(current_psr_ic_addr) = (int *)
|
||||
(current->domain->arch.shared_info_va + XSI_PSR_IC_OFS);
|
||||
migrate_timer(¤t->arch.hlt_timer, current->processor);
|
||||
}
|
||||
flush_vtlb_for_context_switch(current);
|
||||
}
|
||||
@@ -134,10 +136,18 @@ void context_switch(struct vcpu *prev, struct vcpu *next)
|
||||
|
||||
__ia64_save_fpu(prev->arch._thread.fph);
|
||||
__ia64_load_fpu(next->arch._thread.fph);
|
||||
if (VMX_DOMAIN(prev))
|
||||
vmx_save_state(prev);
|
||||
if (VMX_DOMAIN(prev)) {
|
||||
vmx_save_state(prev);
|
||||
if (!VMX_DOMAIN(next)) {
|
||||
/* VMX domains can change the physical cr.dcr.
|
||||
* Restore default to prevent leakage. */
|
||||
ia64_setreg(_IA64_REG_CR_DCR, (IA64_DCR_DP | IA64_DCR_DK
|
||||
| IA64_DCR_DX | IA64_DCR_DR | IA64_DCR_PP
|
||||
| IA64_DCR_DA | IA64_DCR_DD | IA64_DCR_LC));
|
||||
}
|
||||
}
|
||||
if (VMX_DOMAIN(next))
|
||||
vmx_load_state(next);
|
||||
vmx_load_state(next);
|
||||
/*ia64_psr(ia64_task_regs(next))->dfh = !ia64_is_local_fpu_owner(next);*/
|
||||
prev = ia64_switch_to(next);
|
||||
|
||||
@@ -147,6 +157,8 @@ void context_switch(struct vcpu *prev, struct vcpu *next)
|
||||
|
||||
if (VMX_DOMAIN(current)){
|
||||
vmx_load_all_rr(current);
|
||||
migrate_timer(¤t->arch.arch_vmx.vtm.vtm_timer,
|
||||
current->processor);
|
||||
} else {
|
||||
struct domain *nd;
|
||||
extern char ia64_ivt;
|
||||
@@ -228,6 +240,12 @@ void startup_cpu_idle_loop(void)
|
||||
# error "XMAPPEDREGS_SHIFT doesn't match sizeof(mapped_regs_t)."
|
||||
#endif
|
||||
|
||||
void hlt_timer_fn(void *data)
|
||||
{
|
||||
struct vcpu *v = data;
|
||||
vcpu_unblock(v);
|
||||
}
|
||||
|
||||
struct vcpu *alloc_vcpu_struct(struct domain *d, unsigned int vcpu_id)
|
||||
{
|
||||
struct vcpu *v;
|
||||
@@ -287,6 +305,10 @@ struct vcpu *alloc_vcpu_struct(struct domain *d, unsigned int vcpu_id)
|
||||
v->arch.breakimm = d->arch.breakimm;
|
||||
v->arch.last_processor = INVALID_PROCESSOR;
|
||||
}
|
||||
if (!VMX_DOMAIN(v)){
|
||||
init_timer(&v->arch.hlt_timer, hlt_timer_fn, v,
|
||||
first_cpu(cpu_online_map));
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
@@ -298,6 +320,7 @@ void relinquish_vcpu_resources(struct vcpu *v)
|
||||
get_order_from_shift(XMAPPEDREGS_SHIFT));
|
||||
v->arch.privregs = NULL;
|
||||
}
|
||||
kill_timer(&v->arch.hlt_timer);
|
||||
}
|
||||
|
||||
void free_vcpu_struct(struct vcpu *v)
|
||||
@@ -532,6 +555,9 @@ void domain_relinquish_resources(struct domain *d)
|
||||
// relase page traversing d->arch.mm.
|
||||
relinquish_mm(d);
|
||||
|
||||
if (d->vcpu[0] && VMX_DOMAIN(d->vcpu[0]))
|
||||
vmx_relinquish_guest_resources(d);
|
||||
|
||||
relinquish_memory(d, &d->xenpage_list);
|
||||
relinquish_memory(d, &d->page_list);
|
||||
|
||||
@@ -591,7 +617,7 @@ domain_set_shared_info_va (unsigned long va)
|
||||
/* Transfer and clear the shadow bitmap in 1kB chunks for L1 cache. */
|
||||
#define SHADOW_COPY_CHUNK (1024 / sizeof (unsigned long))
|
||||
|
||||
int shadow_mode_control(struct domain *d, xen_domctl_shadow_ops_t *sc)
|
||||
int shadow_mode_control(struct domain *d, xen_domctl_shadow_op_t *sc)
|
||||
{
|
||||
unsigned int op = sc->op;
|
||||
int rc = 0;
|
||||
@@ -716,6 +742,15 @@ int shadow_mode_control(struct domain *d, xen_domctl_shadow_ops_t *sc)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case XEN_DOMCTL_SHADOW_OP_GET_ALLOCATION:
|
||||
sc->mb = 0;
|
||||
break;
|
||||
case XEN_DOMCTL_SHADOW_OP_SET_ALLOCATION:
|
||||
if (sc->mb > 0) {
|
||||
BUG();
|
||||
rc = -ENOMEM;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
@@ -1082,13 +1117,15 @@ void machine_restart(char * __unused)
|
||||
while(1);
|
||||
}
|
||||
|
||||
extern void cpu_halt(void);
|
||||
|
||||
void machine_halt(void)
|
||||
{
|
||||
console_start_sync();
|
||||
if (running_on_sim)
|
||||
printf ("machine_halt called. spinning...\n");
|
||||
else
|
||||
(*efi.reset_system)(EFI_RESET_SHUTDOWN,0,0,NULL);
|
||||
cpu_halt();
|
||||
while(1);
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
#include <xen/smp.h>
|
||||
#include <asm/ptrace.h>
|
||||
#include <xen/delay.h>
|
||||
#include <xen/perfc.h>
|
||||
#include <xen/mm.h>
|
||||
|
||||
#include <asm/system.h>
|
||||
#include <asm/processor.h>
|
||||
@@ -26,9 +28,9 @@
|
||||
#include <asm/debugger.h>
|
||||
#include <asm/fpswa.h>
|
||||
#include <asm/bundle.h>
|
||||
#include <asm/privop_stat.h>
|
||||
#include <asm/asm-xsi-offsets.h>
|
||||
#include <asm/shadow.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
extern void die_if_kernel(char *str, struct pt_regs *regs, long err);
|
||||
/* FIXME: where these declarations shold be there ? */
|
||||
@@ -516,7 +518,8 @@ ia64_handle_break (unsigned long ifa, struct pt_regs *regs, unsigned long isr, u
|
||||
debugger_trap_fatal(0 /* don't care */, regs);
|
||||
}
|
||||
#endif
|
||||
else if (iim == d->arch.breakimm) {
|
||||
else if (iim == d->arch.breakimm &&
|
||||
ia64_get_cpl(regs->cr_ipsr) == 2) {
|
||||
/* by default, do not continue */
|
||||
v->arch.hypercall_continuation = 0;
|
||||
|
||||
|
||||
@@ -16,8 +16,9 @@
|
||||
*
|
||||
* Flush cache.
|
||||
*
|
||||
* Must deal with range from start to end-1 but nothing else (need to
|
||||
* be careful not to touch addresses that may be unmapped).
|
||||
* Must deal with range from start to end-1 but nothing else
|
||||
* (need to be careful not to touch addresses that may be
|
||||
* unmapped).
|
||||
*
|
||||
* Note: "in0" and "in1" are preserved for debugging purposes.
|
||||
*/
|
||||
@@ -37,7 +38,8 @@ GLOBAL_ENTRY(flush_dcache_range)
|
||||
;;
|
||||
sub r8=r22,r23 // number of strides - 1
|
||||
shl r24=r23,r20 // r24: addresses for "fc" =
|
||||
// "start" rounded down to stride boundary
|
||||
// "start" rounded down to stride
|
||||
// boundary
|
||||
.save ar.lc,r3
|
||||
mov r3=ar.lc // save ar.lc
|
||||
;;
|
||||
@@ -49,7 +51,8 @@ GLOBAL_ENTRY(flush_dcache_range)
|
||||
* 32 byte aligned loop, even number of (actually 2) bundles
|
||||
*/
|
||||
.Loop: fc r24 // issuable on M0 only
|
||||
add r24=r21,r24 // we flush "stride size" bytes per iteration
|
||||
add r24=r21,r24 // we flush "stride size" bytes per
|
||||
// iteration
|
||||
nop.i 0
|
||||
br.cloop.sptk.few .Loop
|
||||
;;
|
||||
|
||||
+161
-4
@@ -28,6 +28,7 @@
|
||||
#include "hpsim_ssc.h"
|
||||
#include <asm/vcpu.h>
|
||||
#include <asm/dom_fw.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
extern unsigned long running_on_sim;
|
||||
|
||||
@@ -419,6 +420,141 @@ efi_emulate_get_time(
|
||||
return status;
|
||||
}
|
||||
|
||||
static efi_status_t
|
||||
efi_emulate_get_variable(
|
||||
unsigned long name_addr, unsigned long vendor_addr,
|
||||
unsigned long attr_addr, unsigned long data_size_addr,
|
||||
unsigned long data_addr, IA64FAULT *fault)
|
||||
{
|
||||
unsigned long name, vendor, attr = 0, data_size, data;
|
||||
struct page_info *name_page = NULL, *vendor_page = NULL,
|
||||
*attr_page = NULL, *data_size_page = NULL,
|
||||
*data_page = NULL;
|
||||
efi_status_t status = 0;
|
||||
|
||||
if (current->domain != dom0)
|
||||
return EFI_UNSUPPORTED;
|
||||
|
||||
name = efi_translate_domain_addr(name_addr, fault, &name_page);
|
||||
if (*fault != IA64_NO_FAULT)
|
||||
goto errout;
|
||||
vendor = efi_translate_domain_addr(vendor_addr, fault, &vendor_page);
|
||||
if (*fault != IA64_NO_FAULT)
|
||||
goto errout;
|
||||
data_size = efi_translate_domain_addr(data_size_addr, fault,
|
||||
&data_size_page);
|
||||
if (*fault != IA64_NO_FAULT)
|
||||
goto errout;
|
||||
data = efi_translate_domain_addr(data_addr, fault, &data_page);
|
||||
if (*fault != IA64_NO_FAULT)
|
||||
goto errout;
|
||||
if (attr_addr) {
|
||||
attr = efi_translate_domain_addr(attr_addr, fault, &attr_page);
|
||||
if (*fault != IA64_NO_FAULT)
|
||||
goto errout;
|
||||
}
|
||||
|
||||
status = (*efi.get_variable)((efi_char16_t *)name,
|
||||
(efi_guid_t *)vendor,
|
||||
(u32 *)attr,
|
||||
(unsigned long *)data_size,
|
||||
(void *)data);
|
||||
|
||||
errout:
|
||||
if (name_page != NULL)
|
||||
put_page(name_page);
|
||||
if (vendor_page != NULL)
|
||||
put_page(vendor_page);
|
||||
if (attr_page != NULL)
|
||||
put_page(attr_page);
|
||||
if (data_size_page != NULL)
|
||||
put_page(data_size_page);
|
||||
if (data_page != NULL)
|
||||
put_page(data_page);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static efi_status_t
|
||||
efi_emulate_get_next_variable(
|
||||
unsigned long name_size_addr, unsigned long name_addr,
|
||||
unsigned long vendor_addr, IA64FAULT *fault)
|
||||
{
|
||||
unsigned long name_size, name, vendor;
|
||||
struct page_info *name_size_page = NULL, *name_page = NULL,
|
||||
*vendor_page = NULL;
|
||||
efi_status_t status = 0;
|
||||
|
||||
if (current->domain != dom0)
|
||||
return EFI_UNSUPPORTED;
|
||||
|
||||
name_size = efi_translate_domain_addr(name_size_addr, fault,
|
||||
&name_size_page);
|
||||
if (*fault != IA64_NO_FAULT)
|
||||
goto errout;
|
||||
name = efi_translate_domain_addr(name_addr, fault, &name_page);
|
||||
if (*fault != IA64_NO_FAULT)
|
||||
goto errout;
|
||||
vendor = efi_translate_domain_addr(vendor_addr, fault, &vendor_page);
|
||||
if (*fault != IA64_NO_FAULT)
|
||||
goto errout;
|
||||
|
||||
status = (*efi.get_next_variable)((unsigned long *)name_size,
|
||||
(efi_char16_t *)name,
|
||||
(efi_guid_t *)vendor);
|
||||
|
||||
errout:
|
||||
if (name_size_page != NULL)
|
||||
put_page(name_size_page);
|
||||
if (name_page != NULL)
|
||||
put_page(name_page);
|
||||
if (vendor_page != NULL)
|
||||
put_page(vendor_page);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static efi_status_t
|
||||
efi_emulate_set_variable(
|
||||
unsigned long name_addr, unsigned long vendor_addr,
|
||||
unsigned long attr, unsigned long data_size,
|
||||
unsigned long data_addr, IA64FAULT *fault)
|
||||
{
|
||||
unsigned long name, vendor, data;
|
||||
struct page_info *name_page = NULL, *vendor_page = NULL,
|
||||
*data_page = NULL;
|
||||
efi_status_t status = 0;
|
||||
|
||||
if (current->domain != dom0)
|
||||
return EFI_UNSUPPORTED;
|
||||
|
||||
name = efi_translate_domain_addr(name_addr, fault, &name_page);
|
||||
if (*fault != IA64_NO_FAULT)
|
||||
goto errout;
|
||||
vendor = efi_translate_domain_addr(vendor_addr, fault, &vendor_page);
|
||||
if (*fault != IA64_NO_FAULT)
|
||||
goto errout;
|
||||
data = efi_translate_domain_addr(data_addr, fault, &data_page);
|
||||
if (*fault != IA64_NO_FAULT)
|
||||
goto errout;
|
||||
|
||||
status = (*efi.set_variable)((efi_char16_t *)name,
|
||||
(efi_guid_t *)vendor,
|
||||
attr,
|
||||
data_size,
|
||||
(void *)data);
|
||||
|
||||
errout:
|
||||
if (name_page != NULL)
|
||||
put_page(name_page);
|
||||
if (vendor_page != NULL)
|
||||
put_page(vendor_page);
|
||||
if (data_page != NULL)
|
||||
put_page(data_page);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static efi_status_t
|
||||
efi_emulate_set_virtual_address_map(
|
||||
unsigned long memory_map_size, unsigned long descriptor_size,
|
||||
@@ -527,6 +663,31 @@ efi_emulator (struct pt_regs *regs, IA64FAULT *fault)
|
||||
vcpu_get_gr(v,33),
|
||||
fault);
|
||||
break;
|
||||
case FW_HYPERCALL_EFI_GET_VARIABLE:
|
||||
status = efi_emulate_get_variable (
|
||||
vcpu_get_gr(v,32),
|
||||
vcpu_get_gr(v,33),
|
||||
vcpu_get_gr(v,34),
|
||||
vcpu_get_gr(v,35),
|
||||
vcpu_get_gr(v,36),
|
||||
fault);
|
||||
break;
|
||||
case FW_HYPERCALL_EFI_GET_NEXT_VARIABLE:
|
||||
status = efi_emulate_get_next_variable (
|
||||
vcpu_get_gr(v,32),
|
||||
vcpu_get_gr(v,33),
|
||||
vcpu_get_gr(v,34),
|
||||
fault);
|
||||
break;
|
||||
case FW_HYPERCALL_EFI_SET_VARIABLE:
|
||||
status = efi_emulate_set_variable (
|
||||
vcpu_get_gr(v,32),
|
||||
vcpu_get_gr(v,33),
|
||||
vcpu_get_gr(v,34),
|
||||
vcpu_get_gr(v,35),
|
||||
vcpu_get_gr(v,36),
|
||||
fault);
|
||||
break;
|
||||
case FW_HYPERCALL_EFI_SET_VIRTUAL_ADDRESS_MAP:
|
||||
status = efi_emulate_set_virtual_address_map (
|
||||
vcpu_get_gr(v,32),
|
||||
@@ -538,10 +699,6 @@ efi_emulator (struct pt_regs *regs, IA64FAULT *fault)
|
||||
case FW_HYPERCALL_EFI_GET_WAKEUP_TIME:
|
||||
case FW_HYPERCALL_EFI_SET_WAKEUP_TIME:
|
||||
// FIXME: need fixes in efi.h from 2.6.9
|
||||
case FW_HYPERCALL_EFI_GET_VARIABLE:
|
||||
// FIXME: need fixes in efi.h from 2.6.9
|
||||
case FW_HYPERCALL_EFI_GET_NEXT_VARIABLE:
|
||||
case FW_HYPERCALL_EFI_SET_VARIABLE:
|
||||
case FW_HYPERCALL_EFI_GET_NEXT_HIGH_MONO_COUNT:
|
||||
// FIXME: need fixes in efi.h from 2.6.9
|
||||
status = EFI_UNSUPPORTED;
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <xen/hypercall.h>
|
||||
#include <xen/multicall.h>
|
||||
#include <xen/guest_access.h>
|
||||
#include <xen/mm.h>
|
||||
|
||||
#include <linux/efi.h> /* FOR EFI_UNIMPLEMENTED */
|
||||
#include <asm/sal.h> /* FOR struct ia64_sal_retval */
|
||||
@@ -29,45 +30,45 @@
|
||||
#include <xen/domain.h>
|
||||
#include <public/callback.h>
|
||||
#include <xen/event.h>
|
||||
#include <asm/privop_stat.h>
|
||||
#include <xen/perfc.h>
|
||||
|
||||
static long do_physdev_op_compat(XEN_GUEST_HANDLE(physdev_op_t) uop);
|
||||
static long do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg);
|
||||
static long do_callback_op(int cmd, XEN_GUEST_HANDLE(void) arg);
|
||||
|
||||
hypercall_t ia64_hypercall_table[] =
|
||||
{
|
||||
(hypercall_t)do_ni_hypercall, /* do_set_trap_table */ /* 0 */
|
||||
const hypercall_t ia64_hypercall_table[NR_hypercalls] =
|
||||
{
|
||||
(hypercall_t)do_ni_hypercall, /* do_set_trap_table *//* 0 */
|
||||
(hypercall_t)do_ni_hypercall, /* do_mmu_update */
|
||||
(hypercall_t)do_ni_hypercall, /* do_set_gdt */
|
||||
(hypercall_t)do_ni_hypercall, /* do_stack_switch */
|
||||
(hypercall_t)do_ni_hypercall, /* do_set_callbacks */
|
||||
(hypercall_t)do_ni_hypercall, /* do_fpu_taskswitch */ /* 5 */
|
||||
(hypercall_t)do_ni_hypercall, /* do_fpu_taskswitch *//* 5 */
|
||||
(hypercall_t)do_sched_op_compat,
|
||||
(hypercall_t)do_ni_hypercall,
|
||||
(hypercall_t)do_ni_hypercall, /* do_set_debugreg */
|
||||
(hypercall_t)do_ni_hypercall, /* do_get_debugreg */
|
||||
(hypercall_t)do_ni_hypercall, /* do_update_descriptor */ /* 10 */
|
||||
(hypercall_t)do_ni_hypercall, /* do_update_descriptor * 10 */
|
||||
(hypercall_t)do_ni_hypercall, /* do_ni_hypercall */
|
||||
(hypercall_t)do_memory_op,
|
||||
(hypercall_t)do_multicall,
|
||||
(hypercall_t)do_ni_hypercall, /* do_update_va_mapping */
|
||||
(hypercall_t)do_ni_hypercall, /* do_set_timer_op */ /* 15 */
|
||||
(hypercall_t)do_ni_hypercall, /* do_set_timer_op */ /* 15 */
|
||||
(hypercall_t)do_event_channel_op_compat,
|
||||
(hypercall_t)do_xen_version,
|
||||
(hypercall_t)do_console_io,
|
||||
(hypercall_t)do_physdev_op_compat,
|
||||
(hypercall_t)do_grant_table_op, /* 20 */
|
||||
(hypercall_t)do_grant_table_op, /* 20 */
|
||||
(hypercall_t)do_ni_hypercall, /* do_vm_assist */
|
||||
(hypercall_t)do_ni_hypercall, /* do_update_va_mapping_otherdomain */
|
||||
(hypercall_t)do_ni_hypercall, /* do_update_va_mapping_othe */
|
||||
(hypercall_t)do_ni_hypercall, /* (x86 only) */
|
||||
(hypercall_t)do_ni_hypercall, /* do_vcpu_op */
|
||||
(hypercall_t)do_ni_hypercall, /* (x86_64 only) */ /* 25 */
|
||||
(hypercall_t)do_ni_hypercall, /* (x86_64 only) */ /* 25 */
|
||||
(hypercall_t)do_ni_hypercall, /* do_mmuext_op */
|
||||
(hypercall_t)do_ni_hypercall, /* do_acm_op */
|
||||
(hypercall_t)do_ni_hypercall, /* do_nmi_op */
|
||||
(hypercall_t)do_sched_op,
|
||||
(hypercall_t)do_callback_op, /* */ /* 30 */
|
||||
(hypercall_t)do_callback_op, /* */ /* 30 */
|
||||
(hypercall_t)do_ni_hypercall, /* */
|
||||
(hypercall_t)do_event_channel_op,
|
||||
(hypercall_t)do_physdev_op,
|
||||
@@ -77,33 +78,52 @@ hypercall_t ia64_hypercall_table[] =
|
||||
(hypercall_t)do_ni_hypercall, /* */
|
||||
(hypercall_t)do_ni_hypercall, /* */
|
||||
(hypercall_t)do_ni_hypercall, /* */
|
||||
(hypercall_t)do_ni_hypercall, /* */ /* 40 */
|
||||
(hypercall_t)do_ni_hypercall, /* */ /* 40 */
|
||||
(hypercall_t)do_ni_hypercall, /* */
|
||||
(hypercall_t)do_ni_hypercall, /* */
|
||||
(hypercall_t)do_ni_hypercall, /* */
|
||||
(hypercall_t)do_ni_hypercall, /* */
|
||||
(hypercall_t)do_ni_hypercall, /* */ /* 45 */
|
||||
(hypercall_t)do_ni_hypercall, /* */ /* 45 */
|
||||
(hypercall_t)do_ni_hypercall, /* */
|
||||
(hypercall_t)do_ni_hypercall, /* */
|
||||
(hypercall_t)do_dom0vp_op, /* dom0vp_op */
|
||||
(hypercall_t)do_dom0vp_op, /* dom0vp_op */
|
||||
(hypercall_t)do_ni_hypercall, /* arch_1 */
|
||||
(hypercall_t)do_ni_hypercall, /* arch_2 */ /* 50 */
|
||||
(hypercall_t)do_ni_hypercall, /* arch_2 */ /* 50 */
|
||||
(hypercall_t)do_ni_hypercall, /* arch_3 */
|
||||
(hypercall_t)do_ni_hypercall, /* arch_4 */
|
||||
(hypercall_t)do_ni_hypercall, /* arch_5 */
|
||||
(hypercall_t)do_ni_hypercall, /* arch_6 */
|
||||
(hypercall_t)do_ni_hypercall /* arch_7 */ /* 55 */
|
||||
};
|
||||
|
||||
uint32_t nr_hypercalls =
|
||||
sizeof(ia64_hypercall_table) / sizeof(hypercall_t);
|
||||
(hypercall_t)do_ni_hypercall, /* arch_7 */ /* 55 */
|
||||
(hypercall_t)do_ni_hypercall,
|
||||
(hypercall_t)do_ni_hypercall,
|
||||
(hypercall_t)do_ni_hypercall,
|
||||
(hypercall_t)do_ni_hypercall,
|
||||
(hypercall_t)do_ni_hypercall, /* 60 */
|
||||
(hypercall_t)do_ni_hypercall,
|
||||
(hypercall_t)do_ni_hypercall,
|
||||
(hypercall_t)do_ni_hypercall
|
||||
};
|
||||
|
||||
static IA64FAULT
|
||||
xen_hypercall (struct pt_regs *regs)
|
||||
{
|
||||
uint32_t cmd = (uint32_t)regs->r2;
|
||||
struct vcpu *v = current;
|
||||
|
||||
if (cmd < nr_hypercalls)
|
||||
if (cmd == __HYPERVISOR_grant_table_op) {
|
||||
XEN_GUEST_HANDLE(void) uop;
|
||||
|
||||
v->arch.hypercall_param.va = regs->r15;
|
||||
v->arch.hypercall_param.pa1 = regs->r17;
|
||||
v->arch.hypercall_param.pa2 = regs->r18;
|
||||
set_xen_guest_handle(uop, (void *)regs->r15);
|
||||
regs->r8 = do_grant_table_op(regs->r14, uop, regs->r16);
|
||||
v->arch.hypercall_param.va = 0;
|
||||
return IA64_NO_FAULT;
|
||||
}
|
||||
|
||||
if (cmd < NR_hypercalls) {
|
||||
perfc_incra(hypercalls, cmd);
|
||||
regs->r8 = (*ia64_hypercall_table[cmd])(
|
||||
regs->r14,
|
||||
regs->r15,
|
||||
@@ -111,13 +131,12 @@ xen_hypercall (struct pt_regs *regs)
|
||||
regs->r17,
|
||||
regs->r18,
|
||||
regs->r19);
|
||||
else
|
||||
} else
|
||||
regs->r8 = -ENOSYS;
|
||||
|
||||
return IA64_NO_FAULT;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
fw_hypercall_ipi (struct pt_regs *regs)
|
||||
{
|
||||
@@ -153,7 +172,7 @@ fw_hypercall_ipi (struct pt_regs *regs)
|
||||
vcpu_init_regs (targ);
|
||||
vcpu_regs (targ)->cr_iip = d->arch.sal_data->boot_rdv_ip;
|
||||
vcpu_regs (targ)->r1 = d->arch.sal_data->boot_rdv_r1;
|
||||
vcpu_regs (targ)->b0 = d->arch.sal_return_addr;
|
||||
vcpu_regs (targ)->b0 = FW_HYPERCALL_SAL_RETURN_PADDR;
|
||||
|
||||
if (test_and_clear_bit(_VCPUF_down,
|
||||
&targ->vcpu_flags)) {
|
||||
@@ -217,7 +236,12 @@ fw_hypercall (struct pt_regs *regs)
|
||||
}
|
||||
else {
|
||||
perfc_incrc(pal_halt_light);
|
||||
do_sched_op_compat(SCHEDOP_yield, 0);
|
||||
migrate_timer(&v->arch.hlt_timer,
|
||||
v->processor);
|
||||
set_timer(&v->arch.hlt_timer,
|
||||
vcpu_get_next_timer_ns(v));
|
||||
do_sched_op_compat(SCHEDOP_block, 0);
|
||||
stop_timer(&v->arch.hlt_timer);
|
||||
}
|
||||
regs->r8 = 0;
|
||||
regs->r9 = 0;
|
||||
@@ -276,52 +300,10 @@ fw_hypercall (struct pt_regs *regs)
|
||||
return IA64_NO_FAULT;
|
||||
}
|
||||
|
||||
/* opt_unsafe_hypercall: If true, unsafe debugging hypercalls are allowed.
|
||||
These can create security hole. */
|
||||
static int opt_unsafe_hypercall = 0;
|
||||
boolean_param("unsafe_hypercall", opt_unsafe_hypercall);
|
||||
|
||||
IA64FAULT
|
||||
ia64_hypercall (struct pt_regs *regs)
|
||||
{
|
||||
struct vcpu *v = current;
|
||||
unsigned long index = regs->r2;
|
||||
int privlvl = (regs->cr_ipsr & IA64_PSR_CPL) >> IA64_PSR_CPL0_BIT;
|
||||
|
||||
if (index >= FW_HYPERCALL_FIRST_USER) {
|
||||
/* Note: user hypercalls are not safe, since Xen doesn't
|
||||
check memory access privilege: Xen does not deny reading
|
||||
or writing to kernel memory. */
|
||||
if (!opt_unsafe_hypercall) {
|
||||
printf("user xen/ia64 hypercalls disabled\n");
|
||||
regs->r8 = -1;
|
||||
}
|
||||
else switch (index) {
|
||||
case 0xffff:
|
||||
regs->r8 = dump_privop_counts_to_user(
|
||||
(char *) vcpu_get_gr(v,32),
|
||||
(int) vcpu_get_gr(v,33));
|
||||
break;
|
||||
case 0xfffe:
|
||||
regs->r8 = zero_privop_counts_to_user(
|
||||
(char *) vcpu_get_gr(v,32),
|
||||
(int) vcpu_get_gr(v,33));
|
||||
break;
|
||||
default:
|
||||
printf("unknown user xen/ia64 hypercall %lx\n", index);
|
||||
regs->r8 = do_ni_hypercall();
|
||||
}
|
||||
return IA64_NO_FAULT;
|
||||
}
|
||||
|
||||
/* Hypercalls are only allowed by kernel.
|
||||
Kernel checks memory accesses. */
|
||||
if (VMX_DOMAIN(v) ? (privlvl != 0) : (privlvl != 2)) {
|
||||
/* FIXME: Return a better error value ?
|
||||
Reflection ? Illegal operation ? */
|
||||
regs->r8 = -1;
|
||||
return IA64_NO_FAULT;
|
||||
}
|
||||
|
||||
if (index >= FW_HYPERCALL_FIRST_ARCH)
|
||||
return fw_hypercall (regs);
|
||||
|
||||
@@ -18,7 +18,8 @@
|
||||
|
||||
|
||||
#define _PAGE_PPN_MASK 0x0003fffffffff000 //asm/pgtable.h doesn't do assembly
|
||||
#define PAGE_PHYS 0x0010000000000761 //__pgprot(__DIRTY_BITS|_PAGE_PL_2|_PAGE_AR_RWX)
|
||||
#define PAGE_PHYS 0x0010000000000761 //__pgprot(__DIRTY_BITS|
|
||||
// _PAGE_PL_2|_PAGE_AR_RWX)
|
||||
#define _PAGE_PL_2 (2<<7)
|
||||
|
||||
#if 1 // change to 0 to turn off all fast paths
|
||||
@@ -32,10 +33,10 @@
|
||||
|
||||
//#define FAST_TICK // mostly working (unat problems) but default off for now
|
||||
//#define FAST_TLB_MISS_REFLECT // mostly working but default off for now
|
||||
# undef FAST_ITC //XXX TODO fast_itc doesn't suport dom0 vp yet.
|
||||
# undef FAST_ITC //XXX TODO fast_itc doesn't support dom0 vp yet
|
||||
# define FAST_BREAK
|
||||
# undef FAST_ACCESS_REFLECT //XXX TODO fast_access_reflect
|
||||
// doesn't support dom0 vp yet.
|
||||
# undef FAST_ACCESS_REFLECT //XXX TODO fast_access_reflect
|
||||
// doesn't support dom0 vp yet.
|
||||
# define FAST_RFI
|
||||
# define FAST_SSM_I
|
||||
# define FAST_PTC_GA
|
||||
@@ -104,79 +105,100 @@ GLOBAL_ENTRY(fast_hyperprivop)
|
||||
1: // when we get to here r20=~=interrupts pending
|
||||
// Check pending event indication
|
||||
(p7) movl r20=THIS_CPU(current_psr_i_addr);;
|
||||
(p7) ld8 r20=[r20];;
|
||||
(p7) adds r20=-1,r20;; /* evtchn_upcall_pending */
|
||||
(p7) ld1 r20=[r20];;
|
||||
(p7) ld8 r20=[r20]
|
||||
;;
|
||||
(p7) adds r20=-1,r20 // evtchn_upcall_pending
|
||||
;;
|
||||
(p7) ld1 r20=[r20]
|
||||
;;
|
||||
|
||||
// HYPERPRIVOP_RFI?
|
||||
cmp.eq p7,p6=HYPERPRIVOP_RFI,r17
|
||||
(p7) br.sptk.many hyper_rfi;;
|
||||
(p7) br.sptk.many hyper_rfi
|
||||
;;
|
||||
|
||||
// HYPERPRIVOP_GET_IVR?
|
||||
cmp.eq p7,p6=HYPERPRIVOP_GET_IVR,r17
|
||||
(p7) br.sptk.many hyper_get_ivr;;
|
||||
(p7) br.sptk.many hyper_get_ivr
|
||||
;;
|
||||
|
||||
cmp.ne p7,p0=r20,r0
|
||||
(p7) br.spnt.many dispatch_break_fault ;;
|
||||
(p7) br.spnt.many dispatch_break_fault
|
||||
;;
|
||||
|
||||
// HYPERPRIVOP_COVER?
|
||||
cmp.eq p7,p6=HYPERPRIVOP_COVER,r17
|
||||
(p7) br.sptk.many hyper_cover;;
|
||||
(p7) br.sptk.many hyper_cover
|
||||
;;
|
||||
|
||||
// HYPERPRIVOP_SSM_DT?
|
||||
cmp.eq p7,p6=HYPERPRIVOP_SSM_DT,r17
|
||||
(p7) br.sptk.many hyper_ssm_dt;;
|
||||
(p7) br.sptk.many hyper_ssm_dt
|
||||
;;
|
||||
|
||||
// HYPERPRIVOP_RSM_DT?
|
||||
cmp.eq p7,p6=HYPERPRIVOP_RSM_DT,r17
|
||||
(p7) br.sptk.many hyper_rsm_dt;;
|
||||
(p7) br.sptk.many hyper_rsm_dt
|
||||
;;
|
||||
|
||||
// HYPERPRIVOP_GET_TPR?
|
||||
cmp.eq p7,p6=HYPERPRIVOP_GET_TPR,r17
|
||||
(p7) br.sptk.many hyper_get_tpr;;
|
||||
(p7) br.sptk.many hyper_get_tpr
|
||||
;;
|
||||
|
||||
// HYPERPRIVOP_SET_TPR?
|
||||
cmp.eq p7,p6=HYPERPRIVOP_SET_TPR,r17
|
||||
(p7) br.sptk.many hyper_set_tpr;;
|
||||
(p7) br.sptk.many hyper_set_tpr
|
||||
;;
|
||||
|
||||
// HYPERPRIVOP_EOI?
|
||||
cmp.eq p7,p6=HYPERPRIVOP_EOI,r17
|
||||
(p7) br.sptk.many hyper_eoi;;
|
||||
(p7) br.sptk.many hyper_eoi
|
||||
;;
|
||||
|
||||
// HYPERPRIVOP_SET_ITM?
|
||||
cmp.eq p7,p6=HYPERPRIVOP_SET_ITM,r17
|
||||
(p7) br.sptk.many hyper_set_itm;;
|
||||
(p7) br.sptk.many hyper_set_itm
|
||||
;;
|
||||
|
||||
// HYPERPRIVOP_SET_RR?
|
||||
cmp.eq p7,p6=HYPERPRIVOP_SET_RR,r17
|
||||
(p7) br.sptk.many hyper_set_rr;;
|
||||
(p7) br.sptk.many hyper_set_rr
|
||||
;;
|
||||
|
||||
// HYPERPRIVOP_GET_RR?
|
||||
cmp.eq p7,p6=HYPERPRIVOP_GET_RR,r17
|
||||
(p7) br.sptk.many hyper_get_rr;;
|
||||
(p7) br.sptk.many hyper_get_rr
|
||||
;;
|
||||
|
||||
// HYPERPRIVOP_PTC_GA?
|
||||
cmp.eq p7,p6=HYPERPRIVOP_PTC_GA,r17
|
||||
(p7) br.sptk.many hyper_ptc_ga;;
|
||||
(p7) br.sptk.many hyper_ptc_ga
|
||||
;;
|
||||
|
||||
// HYPERPRIVOP_ITC_D?
|
||||
cmp.eq p7,p6=HYPERPRIVOP_ITC_D,r17
|
||||
(p7) br.sptk.many hyper_itc_d;;
|
||||
(p7) br.sptk.many hyper_itc_d
|
||||
;;
|
||||
|
||||
// HYPERPRIVOP_ITC_I?
|
||||
cmp.eq p7,p6=HYPERPRIVOP_ITC_I,r17
|
||||
(p7) br.sptk.many hyper_itc_i;;
|
||||
(p7) br.sptk.many hyper_itc_i
|
||||
;;
|
||||
|
||||
// HYPERPRIVOP_THASH?
|
||||
cmp.eq p7,p6=HYPERPRIVOP_THASH,r17
|
||||
(p7) br.sptk.many hyper_thash;;
|
||||
(p7) br.sptk.many hyper_thash
|
||||
;;
|
||||
|
||||
// HYPERPRIVOP_SET_KR?
|
||||
cmp.eq p7,p6=HYPERPRIVOP_SET_KR,r17
|
||||
(p7) br.sptk.many hyper_set_kr;;
|
||||
(p7) br.sptk.many hyper_set_kr
|
||||
;;
|
||||
|
||||
// if not one of the above, give up for now and do it the slow way
|
||||
br.sptk.many dispatch_break_fault ;;
|
||||
br.sptk.many dispatch_break_fault
|
||||
;;
|
||||
END(fast_hyperprivop)
|
||||
|
||||
// give up for now if: ipsr.be==1, ipsr.pp==1
|
||||
@@ -701,9 +723,9 @@ ENTRY(fast_reflect)
|
||||
.mem.offset 0,0; st8.spill [r2]=r30,16;
|
||||
.mem.offset 8,0; st8.spill [r3]=r31,16 ;;
|
||||
#ifdef HANDLE_AR_UNAT
|
||||
// r16~r23 are preserved regsin bank0 regs, we need to restore them,
|
||||
// r24~r31 are scratch regs, we don't need to handle NaT bit,
|
||||
// because OS handler must assign it before access it
|
||||
// r16~r23 are preserved regs in bank0 regs, we need to restore them,
|
||||
// r24~r31 are scratch regs, we don't need to handle NaT bit,
|
||||
// because OS handler must assign it before access it
|
||||
ld8 r16=[r2],16;
|
||||
ld8 r17=[r3],16;;
|
||||
ld8 r18=[r2],16;
|
||||
@@ -1114,7 +1136,8 @@ just_do_rfi:
|
||||
(p7) st4 [r18]=r19;;
|
||||
(p6) st4 [r18]=r0;;
|
||||
// force on psr.ic, i, dt, rt, it, bn
|
||||
movl r20=(IA64_PSR_I|IA64_PSR_IC|IA64_PSR_DT|IA64_PSR_RT|IA64_PSR_IT|IA64_PSR_BN)
|
||||
movl r20=(IA64_PSR_I|IA64_PSR_IC|IA64_PSR_DT|IA64_PSR_RT| \
|
||||
IA64_PSR_IT|IA64_PSR_BN)
|
||||
;;
|
||||
or r21=r21,r20
|
||||
;;
|
||||
|
||||
@@ -40,7 +40,6 @@
|
||||
#include <asm/smp.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/bitops.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/pgalloc.h>
|
||||
#include <asm/delay.h>
|
||||
#include <xen/irq.h>
|
||||
@@ -236,9 +235,6 @@ int setup_vector(unsigned int irq, struct irqaction * new)
|
||||
struct irqaction *old, **p;
|
||||
irq_desc_t *desc = irq_descp(irq);
|
||||
|
||||
printf ("setup_vector(%d): handler=%p, flags=%x\n",
|
||||
irq, desc->handler, desc->status);
|
||||
|
||||
/*
|
||||
* The following block of code has to be executed atomically
|
||||
*/
|
||||
|
||||
+510
-419
File diff suppressed because it is too large.
Load diff
@@ -166,7 +166,8 @@
|
||||
#include <xen/sched.h>
|
||||
#include <xen/domain.h>
|
||||
#include <asm/xentypes.h>
|
||||
#include <asm/mm.h>
|
||||
#include <xen/mm.h>
|
||||
#include <xen/errno.h>
|
||||
#include <asm/pgalloc.h>
|
||||
#include <asm/vhpt.h>
|
||||
#include <asm/vcpu.h>
|
||||
@@ -948,8 +949,6 @@ efi_mmio(unsigned long physaddr, unsigned long size)
|
||||
return 1;
|
||||
}
|
||||
|
||||
DPRINTK("%s:%d physaddr 0x%lx size = 0x%lx\n",
|
||||
__func__, __LINE__, physaddr, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -970,8 +969,10 @@ assign_domain_mmio_page(struct domain *d,
|
||||
__func__, d, mpaddr, size);
|
||||
}
|
||||
if (!efi_mmio(mpaddr, size)) {
|
||||
#ifndef NDEBUG
|
||||
DPRINTK("%s:%d domain %p mpaddr 0x%lx size = 0x%lx\n",
|
||||
__func__, __LINE__, d, mpaddr, size);
|
||||
#endif
|
||||
return -EINVAL;
|
||||
}
|
||||
assign_domain_same_page(d, mpaddr, size, ASSIGN_writable | ASSIGN_nocache);
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#ifdef XEN
|
||||
#include <linux/efi.h>
|
||||
#include <linux/errno.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/iosapic.h>
|
||||
#include <asm/system.h>
|
||||
#include <acpi/acpi.h>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include <asm/dom_fw.h>
|
||||
#include <asm/vhpt.h>
|
||||
#include <asm/bundle.h>
|
||||
#include <asm/privop_stat.h>
|
||||
#include <xen/perfc.h>
|
||||
|
||||
long priv_verbose=0;
|
||||
unsigned long privop_trace = 0;
|
||||
@@ -682,7 +682,7 @@ priv_emulate(VCPU *vcpu, REGS *regs, UINT64 isr)
|
||||
return IA64_ILLOP_FAULT;
|
||||
}
|
||||
//if (isrcode != 1 && isrcode != 2) return 0;
|
||||
privlvl = (ipsr & IA64_PSR_CPL) >> IA64_PSR_CPL0_BIT;
|
||||
privlvl = ia64_get_cpl(ipsr);
|
||||
// its OK for a privified-cover to be executed in user-land
|
||||
fault = priv_handle_op(vcpu,regs,privlvl);
|
||||
if ((fault == IA64_NO_FAULT) || (fault == IA64_EXTINT_VECTOR)) { // success!!
|
||||
|
||||
@@ -1,26 +1,55 @@
|
||||
#include <asm/privop_stat.h>
|
||||
#include <asm/vhpt.h>
|
||||
#include <xen/lib.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <public/xen.h>
|
||||
#include <xen/perfc.h>
|
||||
#include <asm/atomic.h>
|
||||
#include <asm/privop_stat.h>
|
||||
|
||||
#ifdef PRIVOP_ADDR_COUNT
|
||||
#define PRIVOP_COUNT_NINSTS 2
|
||||
#define PRIVOP_COUNT_NADDRS 30
|
||||
#ifdef CONFIG_PRIVOP_ADDRS
|
||||
|
||||
struct privop_addr_count {
|
||||
const char *instname;
|
||||
unsigned long addr[PRIVOP_COUNT_NADDRS];
|
||||
unsigned long count[PRIVOP_COUNT_NADDRS];
|
||||
unsigned long overflow;
|
||||
unsigned int count[PRIVOP_COUNT_NADDRS];
|
||||
unsigned int overflow;
|
||||
atomic_t *perfc_addr;
|
||||
atomic_t *perfc_count;
|
||||
atomic_t *perfc_overflow;
|
||||
};
|
||||
|
||||
#undef PERFCOUNTER
|
||||
#define PERFCOUNTER(var, name)
|
||||
|
||||
static struct privop_addr_count privop_addr_counter[PRIVOP_COUNT_NINSTS] = {
|
||||
[_GET_IFA] = { "=ifa", { 0 }, { 0 }, 0 },
|
||||
[_THASH] = { "thash", { 0 }, { 0 }, 0 }
|
||||
#undef PERFCOUNTER_CPU
|
||||
#define PERFCOUNTER_CPU(var, name)
|
||||
|
||||
#undef PERFCOUNTER_ARRAY
|
||||
#define PERFCOUNTER_ARRAY(var, name, size)
|
||||
|
||||
#undef PERFSTATUS
|
||||
#define PERFSTATUS(var, name)
|
||||
|
||||
#undef PERFSTATUS_CPU
|
||||
#define PERFSTATUS_CPU(var, name)
|
||||
|
||||
#undef PERFSTATUS_ARRAY
|
||||
#define PERFSTATUS_ARRAY(var, name, size)
|
||||
|
||||
#undef PERFPRIVOPADDR
|
||||
#define PERFPRIVOPADDR(name) \
|
||||
{ \
|
||||
{ 0 }, { 0 }, 0, \
|
||||
perfcounters.privop_addr_##name##_addr, \
|
||||
perfcounters.privop_addr_##name##_count, \
|
||||
perfcounters.privop_addr_##name##_overflow \
|
||||
},
|
||||
|
||||
static struct privop_addr_count privop_addr_counter[] = {
|
||||
#include <asm/perfc_defn.h>
|
||||
};
|
||||
|
||||
void privop_count_addr(unsigned long iip, int inst)
|
||||
#define PRIVOP_COUNT_NINSTS \
|
||||
(sizeof(privop_addr_counter) / sizeof(privop_addr_counter[0]))
|
||||
|
||||
void privop_count_addr(unsigned long iip, enum privop_inst inst)
|
||||
{
|
||||
struct privop_addr_count *v = &privop_addr_counter[inst];
|
||||
int i;
|
||||
@@ -41,29 +70,28 @@ void privop_count_addr(unsigned long iip, int inst)
|
||||
v->overflow++;;
|
||||
}
|
||||
|
||||
static int dump_privop_addrs(char *buf)
|
||||
void gather_privop_addrs(void)
|
||||
{
|
||||
int i, j;
|
||||
char *s = buf;
|
||||
s += sprintf(s, "Privop addresses:\n");
|
||||
atomic_t *v;
|
||||
for (i = 0; i < PRIVOP_COUNT_NINSTS; i++) {
|
||||
struct privop_addr_count *v = &privop_addr_counter[i];
|
||||
s += sprintf(s, "%s:\n", v->instname);
|
||||
for (j = 0; j < PRIVOP_COUNT_NADDRS; j++) {
|
||||
if (!v->addr[j])
|
||||
break;
|
||||
s += sprintf(s, " at 0x%lx #%ld\n",
|
||||
v->addr[j], v->count[j]);
|
||||
}
|
||||
if (v->overflow)
|
||||
s += sprintf(s, " other #%ld\n", v->overflow);
|
||||
/* Note: addresses are truncated! */
|
||||
v = privop_addr_counter[i].perfc_addr;
|
||||
for (j = 0; j < PRIVOP_COUNT_NADDRS; j++)
|
||||
atomic_set(&v[j], privop_addr_counter[i].addr[j]);
|
||||
|
||||
v = privop_addr_counter[i].perfc_count;
|
||||
for (j = 0; j < PRIVOP_COUNT_NADDRS; j++)
|
||||
atomic_set(&v[j], privop_addr_counter[i].count[j]);
|
||||
|
||||
atomic_set(privop_addr_counter[i].perfc_overflow,
|
||||
privop_addr_counter[i].overflow);
|
||||
}
|
||||
return s - buf;
|
||||
}
|
||||
|
||||
static void zero_privop_addrs(void)
|
||||
void reset_privop_addrs(void)
|
||||
{
|
||||
int i,j;
|
||||
int i, j;
|
||||
for (i = 0; i < PRIVOP_COUNT_NINSTS; i++) {
|
||||
struct privop_addr_count *v = &privop_addr_counter[i];
|
||||
for (j = 0; j < PRIVOP_COUNT_NADDRS; j++)
|
||||
@@ -119,30 +147,3 @@ static const char * const hyperpriv_str[HYPERPRIVOP_MAX+1] = {
|
||||
"=rr", "rr=", "kr=", "fc", "=cpuid", "=pmd", "=ar.eflg", "ar.eflg="
|
||||
};
|
||||
#endif
|
||||
|
||||
#define TMPBUFLEN 8*1024
|
||||
int dump_privop_counts_to_user(char __user *ubuf, int len)
|
||||
{
|
||||
char buf[TMPBUFLEN];
|
||||
int n;
|
||||
|
||||
if (len < TMPBUFLEN)
|
||||
return -1;
|
||||
|
||||
n = 0;
|
||||
#ifdef PRIVOP_ADDR_COUNT
|
||||
n += dump_privop_addrs(buf + n);
|
||||
#endif
|
||||
n += dump_vhpt_stats(buf + n);
|
||||
if (__copy_to_user(ubuf,buf,n))
|
||||
return -1;
|
||||
return n;
|
||||
}
|
||||
|
||||
int zero_privop_counts_to_user(char __user *ubuf, int len)
|
||||
{
|
||||
#ifdef PRIVOP_ADDR_COUNT
|
||||
zero_privop_addrs();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <linux/sched.h>
|
||||
#include <public/xen.h>
|
||||
#include <xen/mm.h>
|
||||
#include <asm/ia64_int.h>
|
||||
#include <asm/vcpu.h>
|
||||
#include <asm/regionreg.h>
|
||||
@@ -22,6 +23,7 @@
|
||||
#include <asm/vmx_phy_mode.h>
|
||||
#include <asm/bundle.h>
|
||||
#include <asm/privop_stat.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
/* FIXME: where these declarations should be there ? */
|
||||
extern void getreg(unsigned long regnum, unsigned long *val, int *nat, struct pt_regs *regs);
|
||||
@@ -473,7 +475,7 @@ IA64FAULT vcpu_get_iip(VCPU *vcpu, UINT64 *pval)
|
||||
|
||||
IA64FAULT vcpu_get_ifa(VCPU *vcpu, UINT64 *pval)
|
||||
{
|
||||
PRIVOP_COUNT_ADDR(vcpu_regs(vcpu),_GET_IFA);
|
||||
PRIVOP_COUNT_ADDR(vcpu_regs(vcpu), privop_inst_get_ifa);
|
||||
*pval = PSCB(vcpu,ifa);
|
||||
return (IA64_NO_FAULT);
|
||||
}
|
||||
@@ -540,7 +542,7 @@ IA64FAULT vcpu_get_iim(VCPU *vcpu, UINT64 *pval)
|
||||
|
||||
IA64FAULT vcpu_get_iha(VCPU *vcpu, UINT64 *pval)
|
||||
{
|
||||
PRIVOP_COUNT_ADDR(vcpu_regs(vcpu),_THASH);
|
||||
PRIVOP_COUNT_ADDR(vcpu_regs(vcpu), privop_inst_thash);
|
||||
*pval = PSCB(vcpu,iha);
|
||||
return (IA64_NO_FAULT);
|
||||
}
|
||||
@@ -2215,3 +2217,28 @@ IA64FAULT vcpu_ptr_i(VCPU *vcpu,UINT64 vadr,UINT64 log_range)
|
||||
|
||||
return IA64_NO_FAULT;
|
||||
}
|
||||
|
||||
int ia64_map_hypercall_param(void)
|
||||
{
|
||||
struct vcpu *v = current;
|
||||
struct domain *d = current->domain;
|
||||
u64 vaddr = v->arch.hypercall_param.va & PAGE_MASK;
|
||||
volatile pte_t* pte;
|
||||
|
||||
if (v->arch.hypercall_param.va == 0)
|
||||
return FALSE;
|
||||
pte = lookup_noalloc_domain_pte(d, v->arch.hypercall_param.pa1);
|
||||
if (!pte || !pte_present(*pte))
|
||||
return FALSE;
|
||||
vcpu_itc_no_srlz(v, 2, vaddr, pte_val(*pte), -1UL, PAGE_SHIFT);
|
||||
if (v->arch.hypercall_param.pa2) {
|
||||
vaddr += PAGE_SIZE;
|
||||
pte = lookup_noalloc_domain_pte(d, v->arch.hypercall_param.pa2);
|
||||
if (pte && pte_present(*pte)) {
|
||||
vcpu_itc_no_srlz(v, 2, vaddr, pte_val(*pte),
|
||||
-1UL, PAGE_SHIFT);
|
||||
}
|
||||
}
|
||||
ia64_srlz_d();
|
||||
return TRUE;
|
||||
}
|
||||
@@ -261,13 +261,12 @@ void flush_tlb_mask(cpumask_t mask)
|
||||
(cpu, (void (*)(void *))flush_tlb_vhpt_all, NULL, 1, 1);
|
||||
}
|
||||
|
||||
int dump_vhpt_stats(char *buf)
|
||||
#ifdef PERF_COUNTERS
|
||||
void gather_vhpt_stats(void)
|
||||
{
|
||||
int i, cpu;
|
||||
char *s = buf;
|
||||
|
||||
s += sprintf(s,"VHPT usage (%ld entries):\n",
|
||||
(unsigned long) VHPT_NUM_ENTRIES);
|
||||
perfc_set(vhpt_nbr_entries, VHPT_NUM_ENTRIES);
|
||||
|
||||
for_each_present_cpu (cpu) {
|
||||
struct vhpt_lf_entry *v = __va(per_cpu(vhpt_paddr, cpu));
|
||||
@@ -276,8 +275,7 @@ int dump_vhpt_stats(char *buf)
|
||||
for (i = 0; i < VHPT_NUM_ENTRIES; i++, v++)
|
||||
if (!(v->ti_tag & INVALID_TI_TAG))
|
||||
vhpt_valid++;
|
||||
s += sprintf(s," cpu %d: %ld\n", cpu, vhpt_valid);
|
||||
perfc_seta(vhpt_valid_entries, cpu, vhpt_valid);
|
||||
}
|
||||
|
||||
return s - buf;
|
||||
}
|
||||
#endif
|
||||
@@ -169,7 +169,9 @@ SECTIONS
|
||||
*(.data.gate)
|
||||
__stop_gate_section = .;
|
||||
}
|
||||
. = ALIGN(PAGE_SIZE); /* make sure the gate page doesn't expose kernel data */
|
||||
. = ALIGN(PAGE_SIZE); /* make sure the gate page doesn't expose
|
||||
* kernel data
|
||||
*/
|
||||
|
||||
.data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET)
|
||||
{ *(.data.cacheline_aligned) }
|
||||
@@ -184,7 +186,9 @@ SECTIONS
|
||||
*(.data.percpu)
|
||||
__per_cpu_end = .;
|
||||
}
|
||||
. = __phys_per_cpu_start + PERCPU_PAGE_SIZE; /* ensure percpu data fits into percpu page size */
|
||||
. = __phys_per_cpu_start + PERCPU_PAGE_SIZE; /* ensure percpu data fits
|
||||
* into percpu page size
|
||||
*/
|
||||
|
||||
data : { } :data
|
||||
.data : AT(ADDR(.data) - LOAD_OFFSET)
|
||||
|
||||
+12
-10
@@ -31,7 +31,7 @@
|
||||
// loc0=rp, loc1=ar.pfs, loc2=percpu_paddr, loc3=psr, loc4=ar.rse
|
||||
// loc5=pal_vaddr, loc6=xen_paddr, loc7=shared_archinfo_paddr,
|
||||
GLOBAL_ENTRY(ia64_new_rr7)
|
||||
// not sure this unwind statement is correct...
|
||||
// FIXME? not sure this unwind statement is correct...
|
||||
.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(1)
|
||||
alloc loc1 = ar.pfs, 5, 8, 0, 0
|
||||
movl loc2=PERCPU_ADDR
|
||||
@@ -162,7 +162,7 @@ GLOBAL_ENTRY(ia64_new_rr7)
|
||||
dep r25=0,loc5,60,4 // convert pal vaddr to paddr
|
||||
;;
|
||||
ptr.i loc5,r23
|
||||
or r25=r25,r26 // construct PA | page properties
|
||||
or r25=r25,r26 // construct PA | page properties
|
||||
mov cr.itir=r23
|
||||
mov cr.ifa=loc5
|
||||
;;
|
||||
@@ -191,10 +191,10 @@ GLOBAL_ENTRY(ia64_prepare_handle_privop)
|
||||
*/
|
||||
mov r16=r0
|
||||
DO_SAVE_SWITCH_STACK
|
||||
br.call.sptk.many rp=ia64_handle_privop // stack frame setup in ivt
|
||||
br.call.sptk.many rp=ia64_handle_privop // stack frame setup in ivt
|
||||
.ret22: .body
|
||||
DO_LOAD_SWITCH_STACK
|
||||
br.cond.sptk.many rp // goes to ia64_leave_kernel
|
||||
br.cond.sptk.many rp // goes to ia64_leave_kernel
|
||||
END(ia64_prepare_handle_privop)
|
||||
|
||||
GLOBAL_ENTRY(ia64_prepare_handle_break)
|
||||
@@ -217,7 +217,7 @@ GLOBAL_ENTRY(ia64_prepare_handle_reflection)
|
||||
*/
|
||||
mov r16=r0
|
||||
DO_SAVE_SWITCH_STACK
|
||||
br.call.sptk.many rp=ia64_handle_reflection // stack frame setup in ivt
|
||||
br.call.sptk.many rp=ia64_handle_reflection // stack frame setup in ivt
|
||||
.ret24: .body
|
||||
DO_LOAD_SWITCH_STACK
|
||||
br.cond.sptk.many rp // goes to ia64_leave_kernel
|
||||
@@ -301,7 +301,7 @@ static: cmp.eq p7,p8=6,r32 /* PAL_PTCE_INFO */
|
||||
(p8) br.cond.sptk.few 1f
|
||||
#if 0
|
||||
mov r9=ar.lc
|
||||
movl r8=524288 /* flush 512k million cache lines (16MB) */
|
||||
movl r8=524288 /* flush 512k million cache lines (16MB) */
|
||||
;;
|
||||
mov ar.lc=r8
|
||||
movl r8=0xe000000000000000
|
||||
@@ -319,7 +319,9 @@ static: cmp.eq p7,p8=6,r32 /* PAL_PTCE_INFO */
|
||||
1: cmp.eq p7,p8=15,r32 /* PAL_PERF_MON_INFO */
|
||||
(p8) br.cond.sptk.few 1f
|
||||
mov r8=0 /* status = 0 */
|
||||
movl r9 =0x08122f04 /* generic=4 width=47 retired=8 cycles=18 */
|
||||
movl r9 =0x08122f04 /* generic=4 width=47 retired=8
|
||||
* cycles=18
|
||||
*/
|
||||
mov r10=0 /* reserved */
|
||||
mov r11=0 /* reserved */
|
||||
mov r16=0xffff /* implemented PMC */
|
||||
@@ -361,8 +363,8 @@ stacked:
|
||||
END(pal_emulator_static)
|
||||
|
||||
// These instructions are copied in the domains.
|
||||
// This is the virtual PAL, which simply does an hypercall.
|
||||
// The size is 2 bunldes (32 Bytes). It handles both static and stacked
|
||||
// This is the virtual PAL, which simply does a hypercall.
|
||||
// The size is 2 bundles (32 Bytes). It handles both static and stacked
|
||||
// convention.
|
||||
// If you modify this code, you have to modify dom_fw.h (for the size) and
|
||||
// dom_fw_pal_hypercall_patch.
|
||||
@@ -376,7 +378,7 @@ GLOBAL_ENTRY(pal_call_stub)
|
||||
}
|
||||
{
|
||||
.mbb
|
||||
break 0x1000 // Hypercall vector (Value is patched).
|
||||
break 0x1000 // Hypercall vector (Value is patched).
|
||||
(p7) br.cond.sptk.few rp
|
||||
(p8) br.ret.sptk.few rp
|
||||
}
|
||||
|
||||
@@ -26,11 +26,6 @@
|
||||
#include <linux/efi.h>
|
||||
#include <asm/iosapic.h>
|
||||
|
||||
/* Be sure the struct shared_info size is <= XSI_SIZE. */
|
||||
#if SHARED_INFO_SIZE > XSI_SIZE
|
||||
#error "struct shared_info bigger than XSI_SIZE"
|
||||
#endif
|
||||
|
||||
unsigned long xenheap_phys_end, total_pages;
|
||||
|
||||
char saved_command_line[COMMAND_LINE_SIZE];
|
||||
@@ -258,6 +253,9 @@ void start_kernel(void)
|
||||
int i;
|
||||
#endif
|
||||
|
||||
/* Be sure the struct shared_info size is <= XSI_SIZE. */
|
||||
BUILD_BUG_ON(sizeof(struct shared_info) > XSI_SIZE);
|
||||
|
||||
running_on_sim = is_platform_hp_ski();
|
||||
/* Kernel may be relocated by EFI loader */
|
||||
xen_pstart = ia64_tpa(KERNEL_START);
|
||||
@@ -289,6 +287,7 @@ void start_kernel(void)
|
||||
ia64_boot_param->initrd_size = 0;
|
||||
}
|
||||
|
||||
printk("Xen command line: %s\n", saved_command_line);
|
||||
/* xenheap should be in same TR-covered range with xen image */
|
||||
xenheap_phys_end = xen_pstart + xenheap_size;
|
||||
printk("xen image pstart: 0x%lx, xenheap pend: 0x%lx\n",
|
||||
@@ -518,9 +517,6 @@ printk("num_online_cpus=%d, max_cpus=%d\n",num_online_cpus(),max_cpus);
|
||||
0) != 0)
|
||||
panic("Could not set up DOM0 guest OS\n");
|
||||
|
||||
/* PIN domain0 on CPU 0. */
|
||||
dom0->vcpu[0]->cpu_affinity = cpumask_of_cpu(0);
|
||||
|
||||
if (!running_on_sim) // slow on ski and pages are pre-initialized to zero
|
||||
scrub_heap_pages();
|
||||
|
||||
|
||||
@@ -109,6 +109,7 @@ void
|
||||
xen_timer_interrupt (int irq, void *dev_id, struct pt_regs *regs)
|
||||
{
|
||||
unsigned long new_itm, old_itc;
|
||||
int f_setitm = 0;
|
||||
|
||||
#if 0
|
||||
#define HEARTBEAT_FREQ 16 // period in seconds
|
||||
@@ -129,11 +130,12 @@ xen_timer_interrupt (int irq, void *dev_id, struct pt_regs *regs)
|
||||
vcpu_pend_timer(current);
|
||||
// ensure another timer interrupt happens even if domain doesn't
|
||||
vcpu_set_next_timer(current);
|
||||
f_setitm = 1;
|
||||
}
|
||||
|
||||
new_itm = local_cpu_data->itm_next;
|
||||
|
||||
if (!VMX_DOMAIN(current) && !time_after(ia64_get_itc(), new_itm))
|
||||
if (f_setitm && !time_after(ia64_get_itc(), new_itm))
|
||||
return;
|
||||
|
||||
while (1) {
|
||||
|
||||
@@ -96,10 +96,11 @@ long do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg)
|
||||
if ( !IS_PRIV(current->domain) )
|
||||
break;
|
||||
|
||||
irq = irq_op.irq;
|
||||
ret = -EINVAL;
|
||||
if ( (irq = irq_op.irq) >= NR_IRQS )
|
||||
if ( (irq < 0) || (irq >= NR_IRQS) )
|
||||
break;
|
||||
|
||||
|
||||
irq_op.vector = assign_irq_vector(irq);
|
||||
ret = copy_to_guest(arg, &irq_op, 1) ? -EFAULT : 0;
|
||||
break;
|
||||
|
||||
@@ -37,6 +37,12 @@
|
||||
|
||||
#define MAX_DMADOM_PFN (0x7FFFFFFFUL >> PAGE_SHIFT) /* 31 addressable bits */
|
||||
|
||||
/* If PERFC is used, include privop maps. */
|
||||
#ifdef PERF_COUNTERS
|
||||
#define CONFIG_PRIVOP_ADDRS
|
||||
#define PRIVOP_COUNT_NADDRS 30
|
||||
#endif
|
||||
|
||||
#define CONFIG_VGA 1
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
@@ -7,20 +7,33 @@
|
||||
|
||||
#include <linux/efi.h>
|
||||
|
||||
#ifndef MB
|
||||
#define MB (1024*1024)
|
||||
#endif
|
||||
/* Portion of guest physical memory space reserved for PAL/SAL/EFI/ACPI
|
||||
data and code. */
|
||||
#define FW_BASE_PADDR 0x0000UL
|
||||
#define FW_END_PADDR 0x3000UL
|
||||
|
||||
/* This is used to determined the portion of a domain's metaphysical memory
|
||||
space reserved for the hypercall patch table. */
|
||||
//FIXME: experiment with smaller sizes
|
||||
#define HYPERCALL_START 1UL*MB
|
||||
#define HYPERCALL_END 2UL*MB
|
||||
|
||||
#define FW_HYPERCALL_BASE_PADDR HYPERCALL_START
|
||||
#define FW_HYPERCALL_END_PADDR HYPERCALL_END
|
||||
/* Map:
|
||||
Index Addr
|
||||
0x0000-0x000f 0x0000-0x00ff : unused
|
||||
0x0010-0x001f 0x0100-0x01ff : EFI
|
||||
0x0080-0x008f 0x0800-0x08ff : PAL/SAL
|
||||
0x0090-0x009f 0x0900-0x09ff : FPSWA
|
||||
*/
|
||||
#define FW_HYPERCALL_BASE_PADDR 0x0000UL
|
||||
#define FW_HYPERCALL_END_PADDR 0X1000UL
|
||||
#define FW_HYPERCALL_PADDR(index) (FW_HYPERCALL_BASE_PADDR + (16UL * index))
|
||||
|
||||
/* Base and end guest physical address of ACPI tables. */
|
||||
#define FW_ACPI_BASE_PADDR 0x1000UL
|
||||
#define FW_ACPI_END_PADDR 0x2000UL
|
||||
|
||||
/* Base and end guest physical address of EFI and SAL (non-ACPI) tables. */
|
||||
#define FW_TABLES_BASE_PADDR 0x2000UL
|
||||
#define FW_TABLES_END_PADDR 0x3000UL
|
||||
|
||||
|
||||
/* Hypercalls number have a low part and a high part.
|
||||
The high part is the class (xen/pal/sal/efi). */
|
||||
#define FW_HYPERCALL_NUM_MASK_HIGH ~0xffUL
|
||||
@@ -91,16 +104,16 @@
|
||||
*/
|
||||
|
||||
/* these are indexes into the runtime services table */
|
||||
#define FW_HYPERCALL_EFI_GET_TIME_INDEX 0UL
|
||||
#define FW_HYPERCALL_EFI_SET_TIME_INDEX 1UL
|
||||
#define FW_HYPERCALL_EFI_GET_WAKEUP_TIME_INDEX 2UL
|
||||
#define FW_HYPERCALL_EFI_SET_WAKEUP_TIME_INDEX 3UL
|
||||
#define FW_HYPERCALL_EFI_SET_VIRTUAL_ADDRESS_MAP_INDEX 4UL
|
||||
#define FW_HYPERCALL_EFI_GET_VARIABLE_INDEX 5UL
|
||||
#define FW_HYPERCALL_EFI_GET_NEXT_VARIABLE_INDEX 6UL
|
||||
#define FW_HYPERCALL_EFI_SET_VARIABLE_INDEX 7UL
|
||||
#define FW_HYPERCALL_EFI_GET_NEXT_HIGH_MONO_COUNT_INDEX 8UL
|
||||
#define FW_HYPERCALL_EFI_RESET_SYSTEM_INDEX 9UL
|
||||
#define FW_HYPERCALL_EFI_GET_TIME_INDEX 0x10UL
|
||||
#define FW_HYPERCALL_EFI_SET_TIME_INDEX 0x11UL
|
||||
#define FW_HYPERCALL_EFI_GET_WAKEUP_TIME_INDEX 0x12UL
|
||||
#define FW_HYPERCALL_EFI_SET_WAKEUP_TIME_INDEX 0x13UL
|
||||
#define FW_HYPERCALL_EFI_SET_VIRTUAL_ADDRESS_MAP_INDEX 0x14UL
|
||||
#define FW_HYPERCALL_EFI_GET_VARIABLE_INDEX 0x15UL
|
||||
#define FW_HYPERCALL_EFI_GET_NEXT_VARIABLE_INDEX 0x16UL
|
||||
#define FW_HYPERCALL_EFI_SET_VARIABLE_INDEX 0x17UL
|
||||
#define FW_HYPERCALL_EFI_GET_NEXT_HIGH_MONO_COUNT_INDEX 0x18UL
|
||||
#define FW_HYPERCALL_EFI_RESET_SYSTEM_INDEX 0x19UL
|
||||
|
||||
/* these are hypercall numbers */
|
||||
#define FW_HYPERCALL_EFI_CALL 0x300UL
|
||||
@@ -150,14 +163,11 @@
|
||||
|
||||
/* Hypercalls index bellow _FIRST_ARCH are reserved by Xen, while those above
|
||||
are for the architecture.
|
||||
Note: this limit was defined by Xen/ia64 (and not by Xen).²
|
||||
Note: this limit was defined by Xen/ia64 (and not by Xen).
|
||||
This can be renumbered safely.
|
||||
*/
|
||||
#define FW_HYPERCALL_FIRST_ARCH 0x300UL
|
||||
|
||||
/* Xen/ia64 user hypercalls. Only used for debugging. */
|
||||
#define FW_HYPERCALL_FIRST_USER 0xff00UL
|
||||
|
||||
/* Interrupt vector used for os boot rendez vous. */
|
||||
#define XEN_SAL_BOOT_RENDEZ_VEC 0xF3
|
||||
|
||||
|
||||
@@ -118,8 +118,6 @@ struct arch_domain {
|
||||
|
||||
/* Address of SAL emulator data */
|
||||
struct xen_sal_data *sal_data;
|
||||
/* SAL return point. */
|
||||
unsigned long sal_return_addr;
|
||||
|
||||
/* Address of efi_runtime_services_t (placed in domain memory) */
|
||||
void *efi_runtime;
|
||||
@@ -137,11 +135,19 @@ struct arch_domain {
|
||||
atomic64_t shadow_fault_count;
|
||||
|
||||
struct last_vcpu last_vcpu[NR_CPUS];
|
||||
|
||||
struct arch_vmx_domain arch_vmx; /* Virtual Machine Extensions */
|
||||
};
|
||||
#define INT_ENABLE_OFFSET(v) \
|
||||
(sizeof(vcpu_info_t) * (v)->vcpu_id + \
|
||||
offsetof(vcpu_info_t, evtchn_upcall_mask))
|
||||
|
||||
struct hypercall_param {
|
||||
unsigned long va;
|
||||
unsigned long pa1;
|
||||
unsigned long pa2;
|
||||
};
|
||||
|
||||
struct arch_vcpu {
|
||||
/* Save the state of vcpu.
|
||||
This is the first entry to speed up accesses. */
|
||||
@@ -185,10 +191,14 @@ struct arch_vcpu {
|
||||
char irq_new_pending;
|
||||
char irq_new_condition; // vpsr.i/vtpr change, check for pending VHPI
|
||||
char hypercall_continuation;
|
||||
|
||||
struct hypercall_param hypercall_param; // used to remap a hypercall param
|
||||
|
||||
//for phycial emulation
|
||||
unsigned long old_rsc;
|
||||
int mode_flags;
|
||||
fpswa_ret_t fpswa_ret; /* save return values of FPSWA emulation */
|
||||
struct timer hlt_timer;
|
||||
struct arch_vmx_struct arch_vmx; /* Virtual Machine Extensions */
|
||||
|
||||
#define INVALID_PROCESSOR INT_MAX
|
||||
|
||||
@@ -35,7 +35,7 @@ void guest_physmap_add_page(struct domain *d, unsigned long gpfn, unsigned long
|
||||
gnttab_shared_maddr((d), (t), (i))); \
|
||||
(IA64_GRANT_TABLE_PADDR >> PAGE_SHIFT) + (i);})
|
||||
|
||||
#define gnttab_log_dirty(d, f) ((void)0)
|
||||
#define gnttab_mark_dirty(d, f) ((void)f)
|
||||
|
||||
static inline void gnttab_clear_flag(unsigned long nr, uint16_t *addr)
|
||||
{
|
||||
|
||||
@@ -717,6 +717,14 @@ prefetchw (const void *x)
|
||||
|
||||
extern unsigned long boot_option_idle_override;
|
||||
|
||||
#ifdef XEN
|
||||
static inline unsigned int
|
||||
ia64_get_cpl(unsigned long psr)
|
||||
{
|
||||
return (psr & IA64_PSR_CPL) >> IA64_PSR_CPL0_BIT;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#endif /* _ASM_IA64_PROCESSOR_H */
|
||||
@@ -293,10 +293,6 @@ extern void *efi_get_pal_addr (void);
|
||||
extern void efi_map_pal_code (void);
|
||||
extern void efi_map_memmap(void);
|
||||
extern void efi_memmap_walk (efi_freemem_callback_t callback, void *arg);
|
||||
#ifdef XEN
|
||||
typedef int (*efi_walk_type_callback_t)(efi_memory_desc_t *md, void *arg);
|
||||
extern void efi_memmap_walk_type(u32 type, efi_walk_type_callback_t callback, void *arg);
|
||||
#endif
|
||||
extern void efi_gettimeofday (struct timespec *ts);
|
||||
extern void efi_enter_virtual_mode (void); /* switch EFI to virtual mode, if possible */
|
||||
extern u64 efi_get_iobase (void);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define __ASM_IA64_MULTICALL_H__
|
||||
|
||||
#include <public/xen.h>
|
||||
#include <xen/errno.h>
|
||||
|
||||
typedef unsigned long (*hypercall_t)(
|
||||
unsigned long arg0,
|
||||
@@ -11,17 +12,20 @@ typedef unsigned long (*hypercall_t)(
|
||||
unsigned long arg4,
|
||||
unsigned long arg5);
|
||||
|
||||
extern hypercall_t ia64_hypercall_table[];
|
||||
extern const hypercall_t ia64_hypercall_table[];
|
||||
|
||||
static inline void do_multicall_call(multicall_entry_t *call)
|
||||
{
|
||||
call->result = (*ia64_hypercall_table[call->op])(
|
||||
if (call->op < NR_hypercalls)
|
||||
call->result = (*ia64_hypercall_table[call->op])(
|
||||
call->args[0],
|
||||
call->args[1],
|
||||
call->args[2],
|
||||
call->args[3],
|
||||
call->args[4],
|
||||
call->args[5]);
|
||||
else
|
||||
call->result = -ENOSYS;
|
||||
}
|
||||
|
||||
#endif /* __ASM_IA64_MULTICALL_H__ */
|
||||
@@ -1,16 +1,22 @@
|
||||
#ifndef __ASM_PERFC_H__
|
||||
#define __ASM_PERFC_H__
|
||||
|
||||
static inline void arch_perfc_printall (void)
|
||||
#include <asm/vhpt.h>
|
||||
#include <asm/privop_stat.h>
|
||||
|
||||
static inline void arch_perfc_printall(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void arch_perfc_reset (void)
|
||||
static inline void arch_perfc_reset(void)
|
||||
{
|
||||
reset_privop_addrs();
|
||||
}
|
||||
|
||||
static inline void arch_perfc_gather (void)
|
||||
static inline void arch_perfc_gather(void)
|
||||
{
|
||||
gather_vhpt_stats();
|
||||
gather_privop_addrs();
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -40,3 +40,20 @@ PERFCOUNTER_ARRAY(fast_hyperprivop, "fast hyperprivops", HYPERPRIVOP_MAX + 1)
|
||||
|
||||
PERFCOUNTER_ARRAY(slow_reflect, "slow reflection", 0x80)
|
||||
PERFCOUNTER_ARRAY(fast_reflect, "fast reflection", 0x80)
|
||||
|
||||
PERFSTATUS(vhpt_nbr_entries, "nbr of entries per VHPT")
|
||||
PERFSTATUS_CPU(vhpt_valid_entries, "nbr of valid entries in VHPT")
|
||||
|
||||
#ifdef CONFIG_PRIVOP_ADDRS
|
||||
#ifndef PERFPRIVOPADDR
|
||||
#define PERFPRIVOPADDR(name) \
|
||||
PERFSTATUS_ARRAY(privop_addr_##name##_addr, "privop-addrs addr " #name, \
|
||||
PRIVOP_COUNT_NADDRS) \
|
||||
PERFSTATUS_ARRAY(privop_addr_##name##_count, "privop-addrs count " #name, \
|
||||
PRIVOP_COUNT_NADDRS) \
|
||||
PERFSTATUS(privop_addr_##name##_overflow, "privop-addrs overflow " #name)
|
||||
#endif
|
||||
|
||||
PERFPRIVOPADDR(get_ifa)
|
||||
PERFPRIVOPADDR(thash)
|
||||
#endif
|
||||
@@ -1,23 +1,48 @@
|
||||
#ifndef _XEN_UA64_PRIVOP_STAT_H
|
||||
#define _XEN_UA64_PRIVOP_STAT_H
|
||||
#include <asm/config.h>
|
||||
#include <xen/types.h>
|
||||
#include <public/xen.h>
|
||||
|
||||
extern int dump_privop_counts_to_user(char *, int);
|
||||
extern int zero_privop_counts_to_user(char *, int);
|
||||
#ifdef CONFIG_PRIVOP_ADDRS
|
||||
|
||||
#define PRIVOP_ADDR_COUNT
|
||||
extern void gather_privop_addrs(void);
|
||||
extern void reset_privop_addrs(void);
|
||||
|
||||
#ifdef PRIVOP_ADDR_COUNT
|
||||
#undef PERFCOUNTER
|
||||
#define PERFCOUNTER(var, name)
|
||||
|
||||
#undef PERFCOUNTER_CPU
|
||||
#define PERFCOUNTER_CPU(var, name)
|
||||
|
||||
#undef PERFCOUNTER_ARRAY
|
||||
#define PERFCOUNTER_ARRAY(var, name, size)
|
||||
|
||||
#undef PERFSTATUS
|
||||
#define PERFSTATUS(var, name)
|
||||
|
||||
#undef PERFSTATUS_CPU
|
||||
#define PERFSTATUS_CPU(var, name)
|
||||
|
||||
#undef PERFSTATUS_ARRAY
|
||||
#define PERFSTATUS_ARRAY(var, name, size)
|
||||
|
||||
#undef PERFPRIVOPADDR
|
||||
#define PERFPRIVOPADDR(name) privop_inst_##name,
|
||||
|
||||
enum privop_inst {
|
||||
#include <asm/perfc_defn.h>
|
||||
};
|
||||
|
||||
#undef PERFPRIVOPADDR
|
||||
|
||||
/* INST argument of PRIVOP_COUNT_ADDR. */
|
||||
#define _GET_IFA 0
|
||||
#define _THASH 1
|
||||
#define PRIVOP_COUNT_ADDR(regs,inst) privop_count_addr(regs->cr_iip,inst)
|
||||
extern void privop_count_addr(unsigned long addr, int inst);
|
||||
extern void privop_count_addr(unsigned long addr, enum privop_inst inst);
|
||||
|
||||
#else
|
||||
#define PRIVOP_COUNT_ADDR(x,y) do {} while (0)
|
||||
#define PRIVOP_COUNT_ADDR(x,y) do {} while (0)
|
||||
#define gather_privop_addrs() do {} while (0)
|
||||
#define reset_privop_addrs() do {} while (0)
|
||||
#endif
|
||||
|
||||
#endif /* _XEN_UA64_PRIVOP_STAT_H */
|
||||
@@ -211,16 +211,30 @@ extern void __put_user_unknown (void);
|
||||
extern unsigned long __must_check __copy_user (void __user *to, const void __user *from,
|
||||
unsigned long count);
|
||||
|
||||
extern int ia64_map_hypercall_param(void);
|
||||
|
||||
static inline unsigned long
|
||||
__copy_to_user (void __user *to, const void *from, unsigned long count)
|
||||
{
|
||||
return __copy_user(to, (void __user *) from, count);
|
||||
unsigned long len;
|
||||
len = __copy_user(to, (void __user *)from, count);
|
||||
if (len == 0)
|
||||
return 0;
|
||||
if (ia64_map_hypercall_param())
|
||||
len = __copy_user(to, (void __user *)from, count); /* retry */
|
||||
return len;
|
||||
}
|
||||
|
||||
static inline unsigned long
|
||||
__copy_from_user (void *to, const void __user *from, unsigned long count)
|
||||
{
|
||||
return __copy_user((void __user *) to, from, count);
|
||||
unsigned long len;
|
||||
len = __copy_user((void __user *)to, from, count);
|
||||
if (len == 0)
|
||||
return 0;
|
||||
if (ia64_map_hypercall_param())
|
||||
len = __copy_user((void __user *) to, from, count); /* retry */
|
||||
return len;
|
||||
}
|
||||
|
||||
#define __copy_to_user_inatomic __copy_to_user
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
// TODO: Many (or perhaps most) of these should eventually be
|
||||
// static inline functions
|
||||
|
||||
#include <asm/delay.h>
|
||||
#include <asm/fpu.h>
|
||||
#include <asm/tlb.h>
|
||||
#include <asm/ia64_int.h>
|
||||
@@ -15,6 +16,7 @@ typedef int BOOLEAN;
|
||||
struct vcpu;
|
||||
typedef struct vcpu VCPU;
|
||||
typedef cpu_user_regs_t REGS;
|
||||
extern u64 cycle_to_ns(u64 cycle);
|
||||
|
||||
/* Note: PSCB stands for Privilegied State Communication Block. */
|
||||
#define VCPU(_v,_x) (_v->arch.privregs->_x)
|
||||
@@ -183,6 +185,21 @@ itir_mask(UINT64 itir)
|
||||
return (~((1UL << itir_ps(itir)) - 1));
|
||||
}
|
||||
|
||||
static inline s64
|
||||
vcpu_get_next_timer_ns(VCPU *vcpu)
|
||||
{
|
||||
s64 vcpu_get_next_timer_ns;
|
||||
u64 d = PSCBX(vcpu, domain_itm);
|
||||
u64 now = ia64_get_itc();
|
||||
|
||||
if (d > now)
|
||||
vcpu_get_next_timer_ns = cycle_to_ns(d - now) + NOW();
|
||||
else
|
||||
vcpu_get_next_timer_ns = cycle_to_ns(local_cpu_data->itm_delta) + NOW();
|
||||
|
||||
return vcpu_get_next_timer_ns;
|
||||
}
|
||||
|
||||
#define verbose(a...) do {if (vcpu_verbose) printf(a);} while(0)
|
||||
|
||||
//#define vcpu_quick_region_check(_tr_regions,_ifa) 1
|
||||
|
||||
@@ -32,7 +32,7 @@ struct vhpt_lf_entry {
|
||||
#define INVALID_TI_TAG 0x8000000000000000L
|
||||
|
||||
extern void vhpt_init (void);
|
||||
extern int dump_vhpt_stats(char *buf);
|
||||
extern void gather_vhpt_stats(void);
|
||||
extern void vhpt_multiple_insert(unsigned long vaddr, unsigned long pte,
|
||||
unsigned long logps);
|
||||
extern void vhpt_insert (unsigned long vadr, unsigned long pte,
|
||||
|
||||
@@ -35,7 +35,6 @@ extern void vmx_final_setup_guest(struct vcpu *v);
|
||||
extern void vmx_save_state(struct vcpu *v);
|
||||
extern void vmx_load_state(struct vcpu *v);
|
||||
extern void vmx_setup_platform(struct domain *d);
|
||||
extern void vmx_wait_io(void);
|
||||
extern void vmx_io_assist(struct vcpu *v);
|
||||
extern int ia64_hypercall (struct pt_regs *regs);
|
||||
extern void vmx_save_state(struct vcpu *v);
|
||||
@@ -53,19 +52,16 @@ extern void inject_guest_interruption(struct vcpu *vcpu, u64 vec);
|
||||
extern void vmx_intr_assist(struct vcpu *v);
|
||||
extern void set_illegal_op_isr (struct vcpu *vcpu);
|
||||
extern void illegal_op (struct vcpu *vcpu);
|
||||
extern void vmx_relinquish_guest_resources(struct domain *d);
|
||||
extern void vmx_relinquish_vcpu_resources(struct vcpu *v);
|
||||
extern void vmx_die_if_kernel(char *str, struct pt_regs *regs, long err);
|
||||
extern void vmx_send_assist_req(struct vcpu *v);
|
||||
|
||||
static inline vcpu_iodata_t *get_vio(struct domain *d, unsigned long cpu)
|
||||
{
|
||||
return &((shared_iopage_t *)d->arch.vmx_platform.shared_page_va)->vcpu_iodata[cpu];
|
||||
}
|
||||
|
||||
static inline int iopacket_port(struct vcpu *v)
|
||||
{
|
||||
return get_vio(v->domain, v->vcpu_id)->vp_eport;
|
||||
}
|
||||
|
||||
static inline shared_iopage_t *get_sp(struct domain *d)
|
||||
{
|
||||
return (shared_iopage_t *)d->arch.vmx_platform.shared_page_va;
|
||||
|
||||
@@ -239,12 +239,13 @@ vmx_vcpu_set_dcr(VCPU *vcpu, u64 val)
|
||||
{
|
||||
u64 mdcr, mask;
|
||||
VCPU(vcpu,dcr)=val;
|
||||
/* All vDCR bits will go to mDCR, except for be/pp bit */
|
||||
/* All vDCR bits will go to mDCR, except for be/pp/dm bits */
|
||||
mdcr = ia64_get_dcr();
|
||||
mask = IA64_DCR_BE | IA64_DCR_PP;
|
||||
/* Machine dcr.dm masked to handle guest ld.s on tr mapped page */
|
||||
mask = IA64_DCR_BE | IA64_DCR_PP | IA64_DCR_DM;
|
||||
mdcr = ( mdcr & mask ) | ( val & (~mask) );
|
||||
ia64_set_dcr( mdcr);
|
||||
|
||||
VMX(vcpu, mdcr) = mdcr;
|
||||
return IA64_NO_FAULT;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <asm/vtm.h>
|
||||
#include <asm/vmx_platform.h>
|
||||
#include <public/xen.h>
|
||||
#include <xen/spinlock.h>
|
||||
|
||||
#define VPD_SHIFT 17 /* 128K requirement */
|
||||
#define VPD_SIZE (1 << VPD_SHIFT)
|
||||
@@ -72,6 +73,11 @@ struct ivt_debug{
|
||||
};
|
||||
#define IVT_DEBUG_MAX 128
|
||||
#endif
|
||||
|
||||
struct arch_vmx_domain {
|
||||
spinlock_t virq_assist_lock; /* spinlock for pass virq */
|
||||
};
|
||||
|
||||
struct arch_vmx_struct {
|
||||
// vpd_t *vpd;
|
||||
vtime_t vtm;
|
||||
@@ -89,13 +95,15 @@ struct arch_vmx_struct {
|
||||
// unsigned long mrr5;
|
||||
// unsigned long mrr6;
|
||||
// unsigned long mrr7;
|
||||
unsigned long mdcr;
|
||||
unsigned long mpta;
|
||||
// unsigned long rfi_pfs;
|
||||
// unsigned long rfi_iip;
|
||||
// unsigned long rfi_ipsr;
|
||||
// unsigned long rfi_ifs;
|
||||
// unsigned long in_service[4]; // vLsapic inservice IRQ bits
|
||||
unsigned long flags;
|
||||
unsigned long flags;
|
||||
unsigned long xen_port;
|
||||
#ifdef VTI_DEBUG
|
||||
unsigned long ivt_current;
|
||||
struct ivt_debug ivt_debug[IVT_DEBUG_MAX];
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
#include "xen.h"
|
||||
|
||||
#define XEN_DOMCTL_INTERFACE_VERSION 0x00000001
|
||||
#define XEN_DOMCTL_INTERFACE_VERSION 0x00000002
|
||||
|
||||
#define uint64_t uint64_aligned_t
|
||||
|
||||
@@ -72,8 +72,11 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_getdomaininfo_t);
|
||||
#define XEN_DOMCTL_getmemlist 6
|
||||
struct xen_domctl_getmemlist {
|
||||
/* IN variables. */
|
||||
/* Max entries to write to output buffer. */
|
||||
uint64_t max_pfns;
|
||||
XEN_GUEST_HANDLE_64(ulong) buffer;
|
||||
/* Start index in guest's page list. */
|
||||
uint64_t start_pfn;
|
||||
XEN_GUEST_HANDLE_64(xen_pfn_t) buffer;
|
||||
/* OUT variables. */
|
||||
uint64_t num_pfns;
|
||||
};
|
||||
|
||||
@@ -63,6 +63,7 @@
|
||||
#define __HYPERVISOR_hvm_op 34
|
||||
#define __HYPERVISOR_sysctl 35
|
||||
#define __HYPERVISOR_domctl 36
|
||||
#define __HYPERVISOR_kexec_op 37
|
||||
|
||||
/* Architecture-specific hypercall definitions. */
|
||||
#define __HYPERVISOR_arch_0 48
|
||||
|
||||