Signed-off-by: Isaku Yamahata <yamahata@xxxxxxxxxxxxx> --- arch/ia64/xen/hypervisor.c | 228 +++++++++++++++++++++++++++++++++++++ include/asm-ia64/xen/hypervisor.h | 194 +++++++++++++++++++++++++++++++ 2 files changed, 422 insertions(+), 0 deletions(-) create mode 100644 arch/ia64/xen/hypervisor.c diff --git a/arch/ia64/xen/hypervisor.c b/arch/ia64/xen/hypervisor.c new file mode 100644 index 0000000..4e5791d --- /dev/null +++ b/arch/ia64/xen/hypervisor.c @@ -0,0 +1,228 @@ +/****************************************************************************** + * include/asm-ia64/shadow.h + * + * Copyright (c) 2006 Isaku Yamahata <yamahata at valinux co jp> + * VA Linux Systems Japan K.K. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <linux/spinlock.h> +#include <linux/bootmem.h> +#include <linux/module.h> +#include <linux/vmalloc.h> +#include <linux/efi.h> +#include <asm/page.h> +#include <asm/pgalloc.h> +#include <asm/meminit.h> +#include <asm/xen/hypervisor.h> +#include <asm/xen/hypercall.h> +#include <xen/interface/memory.h> + +struct shared_info *HYPERVISOR_shared_info __read_mostly = + (struct shared_info *)XSI_BASE; +EXPORT_SYMBOL(HYPERVISOR_shared_info); + +DEFINE_PER_CPU(struct vcpu_info *, xen_vcpu); +#ifdef notyet +DEFINE_PER_CPU(struct vcpu_info, xen_vcpu_info); +#endif + +struct start_info *xen_start_info; +EXPORT_SYMBOL(xen_start_info); + +EXPORT_SYMBOL(running_on_xen); + +EXPORT_SYMBOL(__hypercall); + +/* Stolen from arch/x86/xen/enlighten.c */ +/* + * Flag to determine whether vcpu info placement is available on all + * VCPUs. We assume it is to start with, and then set it to zero on + * the first failure. This is because it can succeed on some VCPUs + * and not others, since it can involve hypervisor memory allocation, + * or because the guest failed to guarantee all the appropriate + * constraints on all VCPUs (ie buffer can't cross a page boundary). + * + * Note that any particular CPU may be using a placed vcpu structure, + * but we can only optimise if the all are. + * + * 0: not available, 1: available + */ +#ifdef notyet +static int have_vcpu_info_placement; +#endif + +static void __init xen_vcpu_setup(int cpu) +{ +/* on Xen/IA64 VCPUOP_register_vcpu_info isn't supported */ +#ifdef notyet + struct vcpu_register_vcpu_info info; + int err; + struct vcpu_info *vcpup; +#endif + + per_cpu(xen_vcpu, cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu]; + +#ifdef notyet + if (!have_vcpu_info_placement) + return; /* already tested, not available */ + + vcpup = &per_cpu(xen_vcpu_info, cpu); + + info.mfn = virt_to_mfn(vcpup); + info.offset = offset_in_page(vcpup); + + printk(KERN_DEBUG + "trying to map vcpu_info %d at %p, mfn %llx, offset %d\n", + cpu, vcpup, info.mfn, info.offset); + + /* Check to see if the hypervisor will put the vcpu_info + structure where we want it, which allows direct access via + a percpu-variable. */ + err = HYPERVISOR_vcpu_op(VCPUOP_register_vcpu_info, cpu, &info); + + if (err) { + printk(KERN_DEBUG "register_vcpu_info failed: err=%d\n", err); + have_vcpu_info_placement = 0; + } else { + /* This cpu is using the registered vcpu info, even if + later ones fail to. */ + per_cpu(xen_vcpu, cpu) = vcpup; + + printk(KERN_DEBUG "cpu %d using vcpu_info at %p\n", + cpu, vcpup); + } +#endif +} + +void __init xen_setup_vcpu_info_placement(void) +{ + int cpu; + + for_each_possible_cpu(cpu) + xen_vcpu_setup(cpu); +} + +void __init +xen_setup(char **cmdline_p) +{ + extern void dig_setup(char **cmdline_p); + + if (ia64_platform_is("xen")) + dig_setup(cmdline_p); +} + +void __cpuinit +xen_cpu_init(void) +{ + extern void xen_smp_intr_init(void); + xen_smp_intr_init(); +} + +/**************************************************************************** + * grant table hack + * cmd: GNTTABOP_xxx + */ + +#include <linux/mm.h> +#include <xen/interface/xen.h> +#include <xen/grant_table.h> + +int arch_gnttab_map_shared(unsigned long *frames, unsigned long nr_gframes, + unsigned long max_nr_gframes, + struct grant_entry **__shared) +{ + *__shared = __va(frames[0] << PAGE_SHIFT); + return 0; +} + +void arch_gnttab_unmap_shared(struct grant_entry *shared, + unsigned long nr_gframes) +{ + /* nothing */ +} + +static void +gnttab_map_grant_ref_pre(struct gnttab_map_grant_ref *uop) +{ + uint32_t flags; + + flags = uop->flags; + + if (flags & GNTMAP_host_map) { + if (flags & GNTMAP_application_map) { + printk(KERN_DEBUG + "GNTMAP_application_map is not supported yet: " + "flags 0x%x\n", flags); + BUG(); + } + if (flags & GNTMAP_contains_pte) { + printk(KERN_DEBUG + "GNTMAP_contains_pte is not supported yet: " + "flags 0x%x\n", flags); + BUG(); + } + } else if (flags & GNTMAP_device_map) { + printk("GNTMAP_device_map is not supported yet 0x%x\n", flags); + BUG(); /* XXX not yet. actually this flag is not used. */ + } else { + BUG(); + } +} + +int +HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count) +{ + if (cmd == GNTTABOP_map_grant_ref) { + unsigned int i; + for (i = 0; i < count; i++) { + gnttab_map_grant_ref_pre( + (struct gnttab_map_grant_ref *)uop + i); + } + } + return xencomm_hypercall_grant_table_op(cmd, uop, count); +} +EXPORT_SYMBOL(HYPERVISOR_grant_table_op); + +/************************************************************************** + * opt feature + */ +void +xen_ia64_enable_opt_feature(void) +{ + /* Enable region 7 identity map optimizations in Xen */ + struct xen_ia64_opt_feature optf; + + optf.cmd = XEN_IA64_OPTF_IDENT_MAP_REG7; + optf.on = XEN_IA64_OPTF_ON; + optf.pgprot = pgprot_val(PAGE_KERNEL); + optf.key = 0; /* No key on linux. */ + HYPERVISOR_opt_feature(&optf); +} + +/************************************************************************** + * suspend/resume + */ +void +xen_post_suspend(int suspend_cancelled) +{ + if (suspend_cancelled) + return; + + xen_ia64_enable_opt_feature(); + /* add more if necessary */ +} diff --git a/include/asm-ia64/xen/hypervisor.h b/include/asm-ia64/xen/hypervisor.h index 4ee50c9..c8ae8e8 100644 --- a/include/asm-ia64/xen/hypervisor.h +++ b/include/asm-ia64/xen/hypervisor.h @@ -42,9 +42,203 @@ extern const int running_on_xen; # define is_running_on_xen() (1) # else /* CONFIG_VMX_GUEST */ # define is_running_on_xen() (0) +# define HYPERVISOR_ioremap(offset, size) (offset) # endif /* CONFIG_VMX_GUEST */ #endif /* CONFIG_XEN */ +#if defined(CONFIG_XEN) || defined(CONFIG_VMX_GUEST) +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/version.h> +#include <linux/errno.h> +#include <linux/init.h> +#include <xen/interface/xen.h> +#include <xen/interface/version.h> /* to compile feature.c */ +#include <xen/interface/event_channel.h> +#include <xen/interface/physdev.h> +#include <xen/interface/sched.h> +#include <asm/ptrace.h> +#include <asm/page.h> +#include <asm/percpu.h> +#ifdef CONFIG_XEN +#include <asm/xen/hypercall.h> +#endif + +extern struct shared_info *HYPERVISOR_shared_info; +extern struct start_info *xen_start_info; + +DECLARE_PER_CPU(struct vcpu_info *, xen_vcpu); +void __init xen_setup_vcpu_info_placement(void); +void force_evtchn_callback(void); + +struct vm_struct *xen_alloc_vm_area(unsigned long size); +void xen_free_vm_area(struct vm_struct *area); + +/* Turn jiffies into Xen system time. XXX Implement me. */ +#define jiffies_to_st(j) 0 + +static inline int +HYPERVISOR_yield( + void) +{ + int rc = HYPERVISOR_sched_op(SCHEDOP_yield, NULL); + + return rc; +} + +static inline int +HYPERVISOR_block( + void) +{ + int rc = HYPERVISOR_sched_op(SCHEDOP_block, NULL); + + return rc; +} + +static inline int +HYPERVISOR_shutdown( + unsigned int reason) +{ + struct sched_shutdown sched_shutdown = { + .reason = reason + }; + + int rc = HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown); + + return rc; +} + +static inline int +HYPERVISOR_poll( + evtchn_port_t *ports, unsigned int nr_ports, u64 timeout) +{ + struct sched_poll sched_poll = { + .nr_ports = nr_ports, + .timeout = jiffies_to_st(timeout) + }; + + int rc; + + set_xen_guest_handle(sched_poll.ports, ports); + rc = HYPERVISOR_sched_op(SCHEDOP_poll, &sched_poll); + + return rc; +} + +#ifndef CONFIG_VMX_GUEST +/* for drivers/xen/privcmd/privcmd.c */ +#define machine_to_phys_mapping 0 +struct vm_area_struct; +int direct_remap_pfn_range(struct vm_area_struct *vma, + unsigned long address, + unsigned long mfn, + unsigned long size, + pgprot_t prot, + domid_t domid); +struct file; +int privcmd_enforce_singleshot_mapping(struct vm_area_struct *vma); +int privcmd_mmap(struct file *file, struct vm_area_struct *vma); +#define HAVE_ARCH_PRIVCMD_MMAP + +/* for drivers/xen/balloon/balloon.c */ +#ifdef CONFIG_XEN_SCRUB_PAGES +#define scrub_pages(_p, _n) memset((void *)(_p), 0, (_n) << PAGE_SHIFT) +#else +#define scrub_pages(_p, _n) ((void)0) +#endif +#define pte_mfn(_x) pte_pfn(_x) +#define phys_to_machine_mapping_valid(_x) (1) + +void xen_contiguous_bitmap_init(unsigned long end_pfn); +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, + unsigned int order, unsigned int address_bits) +{ + int ret = 0; + if (is_running_on_xen()) { + ret = __xen_create_contiguous_region(vstart, order, + address_bits); + } + return ret; +} + +void __xen_destroy_contiguous_region(unsigned long vstart, unsigned int order); +static inline void +xen_destroy_contiguous_region(unsigned long vstart, unsigned int order) +{ + if (is_running_on_xen()) + __xen_destroy_contiguous_region(vstart, order); +} + +struct page; + +int xen_limit_pages_to_max_mfn(struct page *pages, unsigned int order, + unsigned int address_bits); + +/* For drivers/xen/core/machine_reboot.c */ +#define HAVE_XEN_POST_SUSPEND +void xen_post_suspend(int suspend_cancelled); + +/* For setup_arch() in arch/ia64/kernel/setup.c */ +void xen_ia64_enable_opt_feature(void); +#endif /* !CONFIG_VMX_GUEST */ + +#define __pte_ma(_x) ((pte_t) {(_x)}) /* unmodified use */ +#define mfn_pte(_x, _y) __pte_ma(0) /* unmodified use */ + +/* for netfront.c, netback.c */ +#define MULTI_UVMFLAGS_INDEX 0 /* XXX any value */ + +static inline void +MULTI_update_va_mapping( + struct multicall_entry *mcl, unsigned long va, + pte_t new_val, unsigned long flags) +{ + mcl->op = __HYPERVISOR_update_va_mapping; + mcl->result = 0; +} + +static inline void +MULTI_grant_table_op(struct multicall_entry *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; +} + +static inline void +MULTI_mmu_update(struct multicall_entry *mcl, struct mmu_update *req, + int count, int *success_count, domid_t domid) +{ + mcl->op = __HYPERVISOR_mmu_update; + mcl->args[0] = (unsigned long)req; + mcl->args[1] = count; + mcl->args[2] = (unsigned long)success_count; + mcl->args[3] = domid; +} + +/* + * for blktap.c + * int create_lookup_pte_addr(struct mm_struct *mm, + * unsigned long address, + * uint64_t *ptep); + */ +#define create_lookup_pte_addr(mm, address, ptep) \ + ({ \ + printk(KERN_EMERG \ + "%s:%d " \ + "create_lookup_pte_addr() isn't supported.\n", \ + __func__, __LINE__); \ + BUG(); \ + (-ENOSYS); \ + }) + +#endif /* CONFIG_XEN || CONFIG_VMX_GUEST */ + #ifdef CONFIG_XEN_PRIVILEGED_GUEST #define is_initial_xendomain() \ (is_running_on_xen() ? xen_start_info->flags & SIF_INITDOMAIN : 0) -- 1.5.3 - To unsubscribe from this list: send the line "unsubscribe linux-ia64" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html
![]() |