You can subscribe to this list here.
2008 |
Jan
(41) |
Feb
(101) |
Mar
(164) |
Apr
(94) |
May
(27) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
---|
From: <yam...@va...> - 2008-02-21 22:31:49
|
Signed-off-by: Isaku Yamahata <yam...@va...> --- 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 -- yamahata |
From: <yam...@va...> - 2008-02-21 22:31:49
|
Signed-off-by: Isaku Yamahata <yam...@va...> --- arch/ia64/kernel/entry.S | 41 +- arch/ia64/xen/xenentry.S | 798 +++++++++++++++ arch/ia64/xen/xenivt.S | 2204 +++++++++++++++++++++++++++++++++++++++++ arch/ia64/xen/xenminstate.h | 320 ++++++ include/asm-ia64/privop.h | 26 + include/asm-ia64/xen/privop.h | 22 + 6 files changed, 3399 insertions(+), 12 deletions(-) create mode 100644 arch/ia64/xen/xenentry.S create mode 100644 arch/ia64/xen/xenivt.S create mode 100644 arch/ia64/xen/xenminstate.h create mode 100644 include/asm-ia64/privop.h diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index 3c331c4..39bb7d5 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S @@ -180,7 +180,7 @@ END(sys_clone) * called. The code starting at .map relies on this. The rest of the code * doesn't care about the interrupt masking status. */ -GLOBAL_ENTRY(ia64_switch_to) +GLOBAL_ENTRY(__ia64_switch_to) .prologue alloc r16=ar.pfs,1,0,0,0 DO_SAVE_SWITCH_STACK @@ -234,7 +234,7 @@ GLOBAL_ENTRY(ia64_switch_to) ;; srlz.d br.cond.sptk .done -END(ia64_switch_to) +END(__ia64_switch_to) /* * Note that interrupts are enabled during save_switch_stack and load_switch_stack. This @@ -375,7 +375,7 @@ END(save_switch_stack) * - b7 holds address to return to * - must not touch r8-r11 */ -ENTRY(load_switch_stack) +GLOBAL_ENTRY(load_switch_stack) .prologue .altrp b7 @@ -635,8 +635,16 @@ GLOBAL_ENTRY(ia64_ret_from_syscall) adds r2=PT(R8)+16,sp // r2 = &pt_regs.r8 mov r10=r0 // clear error indication in r10 (p7) br.cond.spnt handle_syscall_error // handle potential syscall failure +#ifdef CONFIG_PARAVIRT_GUEST + ;; + // don't fall through, ia64_leave_syscall may be #define'd + br.cond.sptk.few ia64_leave_syscall + ;; +#endif END(ia64_ret_from_syscall) +#ifndef CONFIG_PARAVIRT_GUEST // fall through +#endif /* * ia64_leave_syscall(): Same as ia64_leave_kernel, except that it doesn't * need to switch to bank 0 and doesn't restore the scratch registers. @@ -681,7 +689,7 @@ END(ia64_ret_from_syscall) * ar.csd: cleared * ar.ssd: cleared */ -ENTRY(ia64_leave_syscall) +GLOBAL_ENTRY(__ia64_leave_syscall) PT_REGS_UNWIND_INFO(0) /* * work.need_resched etc. mustn't get changed by this CPU before it returns to @@ -691,7 +699,7 @@ ENTRY(ia64_leave_syscall) * extra work. We always check for extra work when returning to user-level. * With CONFIG_PREEMPT, we also check for extra work when the preempt_count * is 0. After extra work processing has been completed, execution - * resumes at .work_processed_syscall with p6 set to 1 if the extra-work-check + * resumes at ia64_work_processed_syscall with p6 set to 1 if the extra-work-check * needs to be redone. */ #ifdef CONFIG_PREEMPT @@ -709,7 +717,8 @@ ENTRY(ia64_leave_syscall) cmp.eq pLvSys,p0=r0,r0 // pLvSys=1: leave from syscall (pUStk) cmp.eq.unc p6,p0=r0,r0 // p6 <- pUStk #endif -.work_processed_syscall: +.global __ia64_work_processed_syscall; +__ia64_work_processed_syscall: adds r2=PT(LOADRS)+16,r12 adds r3=PT(AR_BSPSTORE)+16,r12 adds r18=TI_FLAGS+IA64_TASK_SIZE,r13 @@ -788,7 +797,7 @@ ENTRY(ia64_leave_syscall) mov.m ar.ssd=r0 // M2 clear ar.ssd mov f11=f0 // F clear f11 br.cond.sptk.many rbs_switch // B -END(ia64_leave_syscall) +END(__ia64_leave_syscall) #ifdef CONFIG_IA32_SUPPORT GLOBAL_ENTRY(ia64_ret_from_ia32_execve) @@ -800,10 +809,18 @@ GLOBAL_ENTRY(ia64_ret_from_ia32_execve) st8.spill [r2]=r8 // store return value in slot for r8 and set unat bit .mem.offset 8,0 st8.spill [r3]=r0 // clear error indication in slot for r10 and set unat bit +#ifdef CONFIG_PARAVIRT_GUEST + ;; + // don't fall through, ia64_leave_kernel may be #define'd + br.cond.sptk.few ia64_leave_kernel + ;; +#endif END(ia64_ret_from_ia32_execve) +#ifndef CONFIG_PARAVIRT_GUEST // fall through +#endif #endif /* CONFIG_IA32_SUPPORT */ -GLOBAL_ENTRY(ia64_leave_kernel) +GLOBAL_ENTRY(__ia64_leave_kernel) PT_REGS_UNWIND_INFO(0) /* * work.need_resched etc. mustn't get changed by this CPU before it returns to @@ -1130,9 +1147,9 @@ skip_rbs_switch: ;; ld8 r8=[r2] ld8 r10=[r3] - br.cond.sptk.many .work_processed_syscall // re-check + br.cond.sptk.many ia64_work_processed_syscall // re-check -END(ia64_leave_kernel) +END(__ia64_leave_kernel) ENTRY(handle_syscall_error) /* @@ -1172,7 +1189,7 @@ END(ia64_invoke_schedule_tail) * be set up by the caller. We declare 8 input registers so the system call * args get preserved, in case we need to restart a system call. */ -ENTRY(notify_resume_user) +GLOBAL_ENTRY(notify_resume_user) .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8) alloc loc1=ar.pfs,8,2,3,0 // preserve all eight input regs in case of syscall restart! mov r9=ar.unat @@ -1234,7 +1251,7 @@ ENTRY(sys_rt_sigreturn) adds sp=16,sp ;; ld8 r9=[sp] // load new ar.unat - mov.sptk b7=r8,ia64_leave_kernel + mov.sptk b7=r8,__ia64_leave_kernel ;; mov ar.unat=r9 br.many b7 diff --git a/arch/ia64/xen/xenentry.S b/arch/ia64/xen/xenentry.S new file mode 100644 index 0000000..38a509d --- /dev/null +++ b/arch/ia64/xen/xenentry.S @@ -0,0 +1,798 @@ +/* + * ia64/xen/entry.S + * + * Alternate kernel routines for Xen. Heavily leveraged from + * ia64/kernel/entry.S + * + * Copyright (C) 2005 Hewlett-Packard Co + * Dan Magenheimer <dan.magenheimer@.hp.com> + */ + +#include <asm/asmmacro.h> +#include <asm/cache.h> +#include <asm/errno.h> +#include <asm/kregs.h> +#include <asm/asm-offsets.h> +#include <asm/pgtable.h> +#include <asm/percpu.h> +#include <asm/processor.h> +#include <asm/thread_info.h> +#include <asm/unistd.h> + +#ifdef CONFIG_XEN +#include "xenminstate.h" +#include <asm/paravirt_nop.h> +#else +#include "minstate.h" +#endif + +/* + * prev_task <- ia64_switch_to(struct task_struct *next) + * With Ingo's new scheduler, interrupts are disabled when this routine gets + * called. The code starting at .map relies on this. The rest of the code + * doesn't care about the interrupt masking status. + */ +#ifdef CONFIG_XEN +GLOBAL_ENTRY(xen_switch_to) + BR_IF_NATIVE(__ia64_switch_to, r22, p7) +#else +GLOBAL_ENTRY(ia64_switch_to) +#endif + .prologue + alloc r16=ar.pfs,1,0,0,0 + DO_SAVE_SWITCH_STACK + .body + + adds r22=IA64_TASK_THREAD_KSP_OFFSET,r13 + movl r25=init_task + mov r27=IA64_KR(CURRENT_STACK) + adds r21=IA64_TASK_THREAD_KSP_OFFSET,in0 + dep r20=0,in0,61,3 // physical address of "next" + ;; + st8 [r22]=sp // save kernel stack pointer of old task + shr.u r26=r20,IA64_GRANULE_SHIFT + cmp.eq p7,p6=r25,in0 + ;; + /* + * If we've already mapped this task's page, we can skip doing it again. + */ +(p6) cmp.eq p7,p6=r26,r27 +(p6) br.cond.dpnt .map + ;; +.done: + ld8 sp=[r21] // load kernel stack pointer of new task +#ifdef CONFIG_XEN + // update "current" application register + mov r8=IA64_KR_CURRENT + mov r9=in0;; + XEN_HYPER_SET_KR +#else + mov IA64_KR(CURRENT)=in0 // update "current" application register +#endif + mov r8=r13 // return pointer to previously running task + mov r13=in0 // set "current" pointer + ;; + DO_LOAD_SWITCH_STACK + +#ifdef CONFIG_SMP + sync.i // ensure "fc"s done by this CPU are visible on other CPUs +#endif + br.ret.sptk.many rp // boogie on out in new context + +.map: +#ifdef CONFIG_XEN + movl r25=XSI_PSR_IC // clear psr.ic + ;; + st4 [r25]=r0 + ;; +#else + rsm psr.ic // interrupts (psr.i) are already disabled here +#endif + movl r25=PAGE_KERNEL + ;; + srlz.d + or r23=r25,r20 // construct PA | page properties + mov r25=IA64_GRANULE_SHIFT<<2 + ;; +#ifdef CONFIG_XEN + movl r8=XSI_ITIR + ;; + st8 [r8]=r25 + ;; + movl r8=XSI_IFA + ;; + st8 [r8]=in0 // VA of next task... + ;; + mov r25=IA64_TR_CURRENT_STACK + // remember last page we mapped... + mov r8=IA64_KR_CURRENT_STACK + mov r9=r26;; + XEN_HYPER_SET_KR;; +#else + mov cr.itir=r25 + mov cr.ifa=in0 // VA of next task... + ;; + mov r25=IA64_TR_CURRENT_STACK + mov IA64_KR(CURRENT_STACK)=r26 // remember last page we mapped... +#endif + ;; + itr.d dtr[r25]=r23 // wire in new mapping... +#ifdef CONFIG_XEN + ;; + srlz.d + mov r9=1 + movl r8=XSI_PSR_IC + ;; + st4 [r8]=r9 + ;; +#else + ssm psr.ic // reenable the psr.ic bit + ;; + srlz.d +#endif + br.cond.sptk .done +#ifdef CONFIG_XEN +END(xen_switch_to) +#else +END(ia64_switch_to) +#endif + +#ifdef CONFIG_XEN +GLOBAL_ENTRY(xen_work_processed_syscall_with_check) + BR_IF_NATIVE(__ia64_work_processed_syscall, r2, p7) + br.cond.sptk xen_work_processed_syscall +END(xen_work_processed_syscall_with_check) +#endif + +/* + * ia64_leave_syscall(): Same as ia64_leave_kernel, except that it doesn't + * need to switch to bank 0 and doesn't restore the scratch registers. + * To avoid leaking kernel bits, the scratch registers are set to + * the following known-to-be-safe values: + * + * r1: restored (global pointer) + * r2: cleared + * r3: 1 (when returning to user-level) + * r8-r11: restored (syscall return value(s)) + * r12: restored (user-level stack pointer) + * r13: restored (user-level thread pointer) + * r14: set to __kernel_syscall_via_epc + * r15: restored (syscall #) + * r16-r17: cleared + * r18: user-level b6 + * r19: cleared + * r20: user-level ar.fpsr + * r21: user-level b0 + * r22: cleared + * r23: user-level ar.bspstore + * r24: user-level ar.rnat + * r25: user-level ar.unat + * r26: user-level ar.pfs + * r27: user-level ar.rsc + * r28: user-level ip + * r29: user-level psr + * r30: user-level cfm + * r31: user-level pr + * f6-f11: cleared + * pr: restored (user-level pr) + * b0: restored (user-level rp) + * b6: restored + * b7: set to __kernel_syscall_via_epc + * ar.unat: restored (user-level ar.unat) + * ar.pfs: restored (user-level ar.pfs) + * ar.rsc: restored (user-level ar.rsc) + * ar.rnat: restored (user-level ar.rnat) + * ar.bspstore: restored (user-level ar.bspstore) + * ar.fpsr: restored (user-level ar.fpsr) + * ar.ccv: cleared + * ar.csd: cleared + * ar.ssd: cleared + */ +#ifdef CONFIG_XEN +GLOBAL_ENTRY(xen_leave_syscall) + BR_IF_NATIVE(__ia64_leave_syscall, r22, p7) +#else +ENTRY(ia64_leave_syscall) +#endif + PT_REGS_UNWIND_INFO(0) + /* + * work.need_resched etc. mustn't get changed by this CPU before it returns to + * user- or fsys-mode, hence we disable interrupts early on. + * + * p6 controls whether current_thread_info()->flags needs to be check for + * extra work. We always check for extra work when returning to user-level. + * With CONFIG_PREEMPT, we also check for extra work when the preempt_count + * is 0. After extra work processing has been completed, execution + * resumes at .work_processed_syscall with p6 set to 1 if the extra-work-check + * needs to be redone. + */ +#ifdef CONFIG_PREEMPT + rsm psr.i // disable interrupts + cmp.eq pLvSys,p0=r0,r0 // pLvSys=1: leave from syscall +(pKStk) adds r20=TI_PRE_COUNT+IA64_TASK_SIZE,r13 + ;; + .pred.rel.mutex pUStk,pKStk +(pKStk) ld4 r21=[r20] // r21 <- preempt_count +(pUStk) mov r21=0 // r21 <- 0 + ;; + cmp.eq p6,p0=r21,r0 // p6 <- pUStk || (preempt_count == 0) +#else /* !CONFIG_PREEMPT */ +#ifdef CONFIG_XEN + movl r2=XSI_PSR_I_ADDR + mov r18=1 + ;; + ld8 r2=[r2] + ;; +(pUStk) st1 [r2]=r18 +#else +(pUStk) rsm psr.i +#endif + cmp.eq pLvSys,p0=r0,r0 // pLvSys=1: leave from syscall +(pUStk) cmp.eq.unc p6,p0=r0,r0 // p6 <- pUStk +#endif +#ifdef CONFIG_XEN +.global xen_work_processed_syscall; +xen_work_processed_syscall: +#else +.work_processed_syscall: +#endif + adds r2=PT(LOADRS)+16,r12 + adds r3=PT(AR_BSPSTORE)+16,r12 + adds r18=TI_FLAGS+IA64_TASK_SIZE,r13 + ;; +(p6) ld4 r31=[r18] // load current_thread_info()->flags + ld8 r19=[r2],PT(B6)-PT(LOADRS) // load ar.rsc value for "loadrs" + nop.i 0 + ;; + mov r16=ar.bsp // M2 get existing backing store pointer + ld8 r18=[r2],PT(R9)-PT(B6) // load b6 +(p6) and r15=TIF_WORK_MASK,r31 // any work other than TIF_SYSCALL_TRACE? + ;; + ld8 r23=[r3],PT(R11)-PT(AR_BSPSTORE) // load ar.bspstore (may be garbage) +(p6) cmp4.ne.unc p6,p0=r15, r0 // any special work pending? +(p6) br.cond.spnt .work_pending_syscall + ;; + // start restoring the state saved on the kernel stack (struct pt_regs): + ld8 r9=[r2],PT(CR_IPSR)-PT(R9) + ld8 r11=[r3],PT(CR_IIP)-PT(R11) +(pNonSys) break 0 // bug check: we shouldn't be here if pNonSys is TRUE! + ;; + invala // M0|1 invalidate ALAT +#ifdef CONFIG_XEN + movl r28=XSI_PSR_I_ADDR + movl r29=XSI_PSR_IC + ;; + ld8 r28=[r28] + mov r30=1 + ;; + st1 [r28]=r30 + st4 [r29]=r0 // note: clears both vpsr.i and vpsr.ic! + ;; +#else + rsm psr.i | psr.ic // M2 turn off interrupts and interruption collection +#endif + cmp.eq p9,p0=r0,r0 // A set p9 to indicate that we should restore cr.ifs + + ld8 r29=[r2],16 // M0|1 load cr.ipsr + ld8 r28=[r3],16 // M0|1 load cr.iip + mov r22=r0 // A clear r22 + ;; + ld8 r30=[r2],16 // M0|1 load cr.ifs + ld8 r25=[r3],16 // M0|1 load ar.unat +(pUStk) add r14=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13 + ;; + ld8 r26=[r2],PT(B0)-PT(AR_PFS) // M0|1 load ar.pfs +#ifdef CONFIG_XEN +(pKStk) mov r21=r8 +(pKStk) XEN_HYPER_GET_PSR + ;; +(pKStk) mov r22=r8 +(pKStk) mov r8=r21 + ;; +#else +(pKStk) mov r22=psr // M2 read PSR now that interrupts are disabled +#endif + nop 0 + ;; + ld8 r21=[r2],PT(AR_RNAT)-PT(B0) // M0|1 load b0 + ld8 r27=[r3],PT(PR)-PT(AR_RSC) // M0|1 load ar.rsc + mov f6=f0 // F clear f6 + ;; + ld8 r24=[r2],PT(AR_FPSR)-PT(AR_RNAT) // M0|1 load ar.rnat (may be garbage) + ld8 r31=[r3],PT(R1)-PT(PR) // M0|1 load predicates + mov f7=f0 // F clear f7 + ;; + ld8 r20=[r2],PT(R12)-PT(AR_FPSR) // M0|1 load ar.fpsr + ld8.fill r1=[r3],16 // M0|1 load r1 +(pUStk) mov r17=1 // A + ;; +(pUStk) st1 [r14]=r17 // M2|3 + ld8.fill r13=[r3],16 // M0|1 + mov f8=f0 // F clear f8 + ;; + ld8.fill r12=[r2] // M0|1 restore r12 (sp) + ld8.fill r15=[r3] // M0|1 restore r15 + mov b6=r18 // I0 restore b6 + + LOAD_PHYS_STACK_REG_SIZE(r17) + mov f9=f0 // F clear f9 +(pKStk) br.cond.dpnt.many skip_rbs_switch // B + + srlz.d // M0 ensure interruption collection is off (for cover) + shr.u r18=r19,16 // I0|1 get byte size of existing "dirty" partition +#ifdef CONFIG_XEN + XEN_HYPER_COVER; +#else + cover // B add current frame into dirty partition & set cr.ifs +#endif + ;; + mov r19=ar.bsp // M2 get new backing store pointer + mov f10=f0 // F clear f10 + + nop.m 0 + movl r14=__kernel_syscall_via_epc // X + ;; + mov.m ar.csd=r0 // M2 clear ar.csd + mov.m ar.ccv=r0 // M2 clear ar.ccv + mov b7=r14 // I0 clear b7 (hint with __kernel_syscall_via_epc) + + mov.m ar.ssd=r0 // M2 clear ar.ssd + mov f11=f0 // F clear f11 + br.cond.sptk.many rbs_switch // B +#ifdef CONFIG_XEN +END(xen_leave_syscall) +#else +END(ia64_leave_syscall) +#endif + +#ifdef CONFIG_XEN +GLOBAL_ENTRY(xen_leave_kernel) + BR_IF_NATIVE(__ia64_leave_kernel, r22, p7) +#else +GLOBAL_ENTRY(ia64_leave_kernel) +#endif + PT_REGS_UNWIND_INFO(0) + /* + * work.need_resched etc. mustn't get changed by this CPU before it returns to + * user- or fsys-mode, hence we disable interrupts early on. + * + * p6 controls whether current_thread_info()->flags needs to be check for + * extra work. We always check for extra work when returning to user-level. + * With CONFIG_PREEMPT, we also check for extra work when the preempt_count + * is 0. After extra work processing has been completed, execution + * resumes at .work_processed_syscall with p6 set to 1 if the extra-work-check + * needs to be redone. + */ +#ifdef CONFIG_PREEMPT + rsm psr.i // disable interrupts + cmp.eq p0,pLvSys=r0,r0 // pLvSys=0: leave from kernel +(pKStk) adds r20=TI_PRE_COUNT+IA64_TASK_SIZE,r13 + ;; + .pred.rel.mutex pUStk,pKStk +(pKStk) ld4 r21=[r20] // r21 <- preempt_count +(pUStk) mov r21=0 // r21 <- 0 + ;; + cmp.eq p6,p0=r21,r0 // p6 <- pUStk || (preempt_count == 0) +#else +#ifdef CONFIG_XEN +(pUStk) movl r17=XSI_PSR_I_ADDR +(pUStk) mov r31=1 + ;; +(pUStk) ld8 r17=[r17] + ;; +(pUStk) st1 [r17]=r31 + ;; +#else +(pUStk) rsm psr.i +#endif + cmp.eq p0,pLvSys=r0,r0 // pLvSys=0: leave from kernel +(pUStk) cmp.eq.unc p6,p0=r0,r0 // p6 <- pUStk +#endif +.work_processed_kernel: + adds r17=TI_FLAGS+IA64_TASK_SIZE,r13 + ;; +(p6) ld4 r31=[r17] // load current_thread_info()->flags + adds r21=PT(PR)+16,r12 + ;; + + lfetch [r21],PT(CR_IPSR)-PT(PR) + adds r2=PT(B6)+16,r12 + adds r3=PT(R16)+16,r12 + ;; + lfetch [r21] + ld8 r28=[r2],8 // load b6 + adds r29=PT(R24)+16,r12 + + ld8.fill r16=[r3],PT(AR_CSD)-PT(R16) + adds r30=PT(AR_CCV)+16,r12 +(p6) and r19=TIF_WORK_MASK,r31 // any work other than TIF_SYSCALL_TRACE? + ;; + ld8.fill r24=[r29] + ld8 r15=[r30] // load ar.ccv +(p6) cmp4.ne.unc p6,p0=r19, r0 // any special work pending? + ;; + ld8 r29=[r2],16 // load b7 + ld8 r30=[r3],16 // load ar.csd +(p6) br.cond.spnt .work_pending + ;; + ld8 r31=[r2],16 // load ar.ssd + ld8.fill r8=[r3],16 + ;; + ld8.fill r9=[r2],16 + ld8.fill r10=[r3],PT(R17)-PT(R10) + ;; + ld8.fill r11=[r2],PT(R18)-PT(R11) + ld8.fill r17=[r3],16 + ;; + ld8.fill r18=[r2],16 + ld8.fill r19=[r3],16 + ;; + ld8.fill r20=[r2],16 + ld8.fill r21=[r3],16 + mov ar.csd=r30 + mov ar.ssd=r31 + ;; +#ifdef CONFIG_XEN + movl r23=XSI_PSR_I_ADDR + movl r22=XSI_PSR_IC + ;; + ld8 r23=[r23] + mov r25=1 + ;; + st1 [r23]=r25 + st4 [r22]=r0 // note: clears both vpsr.i and vpsr.ic! + ;; +#else + rsm psr.i | psr.ic // initiate turning off of interrupt and interruption collection +#endif + invala // invalidate ALAT + ;; + ld8.fill r22=[r2],24 + ld8.fill r23=[r3],24 + mov b6=r28 + ;; + ld8.fill r25=[r2],16 + ld8.fill r26=[r3],16 + mov b7=r29 + ;; + ld8.fill r27=[r2],16 + ld8.fill r28=[r3],16 + ;; + ld8.fill r29=[r2],16 + ld8.fill r30=[r3],24 + ;; + ld8.fill r31=[r2],PT(F9)-PT(R31) + adds r3=PT(F10)-PT(F6),r3 + ;; + ldf.fill f9=[r2],PT(F6)-PT(F9) + ldf.fill f10=[r3],PT(F8)-PT(F10) + ;; + ldf.fill f6=[r2],PT(F7)-PT(F6) + ;; + ldf.fill f7=[r2],PT(F11)-PT(F7) + ldf.fill f8=[r3],32 + ;; + srlz.d // ensure that inter. collection is off (VHPT is don't care, since text is pinned) + mov ar.ccv=r15 + ;; + ldf.fill f11=[r2] +#ifdef CONFIG_XEN + ;; + // r16-r31 all now hold bank1 values + mov r15=ar.unat + movl r2=XSI_BANK1_R16 + movl r3=XSI_BANK1_R16+8 + ;; +.mem.offset 0,0; st8.spill [r2]=r16,16 +.mem.offset 8,0; st8.spill [r3]=r17,16 + ;; +.mem.offset 0,0; st8.spill [r2]=r18,16 +.mem.offset 8,0; st8.spill [r3]=r19,16 + ;; +.mem.offset 0,0; st8.spill [r2]=r20,16 +.mem.offset 8,0; st8.spill [r3]=r21,16 + ;; +.mem.offset 0,0; st8.spill [r2]=r22,16 +.mem.offset 8,0; st8.spill [r3]=r23,16 + ;; +.mem.offset 0,0; st8.spill [r2]=r24,16 +.mem.offset 8,0; st8.spill [r3]=r25,16 + ;; +.mem.offset 0,0; st8.spill [r2]=r26,16 +.mem.offset 8,0; st8.spill [r3]=r27,16 + ;; +.mem.offset 0,0; st8.spill [r2]=r28,16 +.mem.offset 8,0; st8.spill [r3]=r29,16 + ;; +.mem.offset 0,0; st8.spill [r2]=r30,16 +.mem.offset 8,0; st8.spill [r3]=r31,16 + ;; + mov r3=ar.unat + movl r2=XSI_B1NAT + ;; + st8 [r2]=r3 + mov ar.unat=r15 + movl r2=XSI_BANKNUM;; + st4 [r2]=r0; +#else + bsw.0 // switch back to bank 0 (no stop bit required beforehand...) +#endif + ;; +(pUStk) mov r18=IA64_KR(CURRENT)// M2 (12 cycle read latency) + adds r16=PT(CR_IPSR)+16,r12 + adds r17=PT(CR_IIP)+16,r12 + +#ifdef CONFIG_XEN +(pKStk) mov r29=r8 +(pKStk) XEN_HYPER_GET_PSR + ;; +(pKStk) mov r22=r8 +(pKStk) mov r8=r29 + ;; +#else +(pKStk) mov r22=psr // M2 read PSR now that interrupts are disabled +#endif + nop.i 0 + nop.i 0 + ;; + ld8 r29=[r16],16 // load cr.ipsr + ld8 r28=[r17],16 // load cr.iip + ;; + ld8 r30=[r16],16 // load cr.ifs + ld8 r25=[r17],16 // load ar.unat + ;; + ld8 r26=[r16],16 // load ar.pfs + ld8 r27=[r17],16 // load ar.rsc + cmp.eq p9,p0=r0,r0 // set p9 to indicate that we should restore cr.ifs + ;; + ld8 r24=[r16],16 // load ar.rnat (may be garbage) + ld8 r23=[r17],16 // load ar.bspstore (may be garbage) + ;; + ld8 r31=[r16],16 // load predicates + ld8 r21=[r17],16 // load b0 + ;; + ld8 r19=[r16],16 // load ar.rsc value for "loadrs" + ld8.fill r1=[r17],16 // load r1 + ;; + ld8.fill r12=[r16],16 + ld8.fill r13=[r17],16 +(pUStk) adds r18=IA64_TASK_THREAD_ON_USTACK_OFFSET,r18 + ;; + ld8 r20=[r16],16 // ar.fpsr + ld8.fill r15=[r17],16 + ;; + ld8.fill r14=[r16],16 + ld8.fill r2=[r17] +(pUStk) mov r17=1 + ;; + ld8.fill r3=[r16] +(pUStk) st1 [r18]=r17 // restore current->thread.on_ustack + shr.u r18=r19,16 // get byte size of existing "dirty" partition + ;; + mov r16=ar.bsp // get existing backing store pointer + LOAD_PHYS_STACK_REG_SIZE(r17) +(pKStk) br.cond.dpnt skip_rbs_switch + + /* + * Restore user backing store. + * + * NOTE: alloc, loadrs, and cover can't be predicated. + */ +(pNonSys) br.cond.dpnt dont_preserve_current_frame + +#ifdef CONFIG_XEN + XEN_HYPER_COVER; +#else + cover // add current frame into dirty partition and set cr.ifs +#endif + ;; + mov r19=ar.bsp // get new backing store pointer +rbs_switch: + sub r16=r16,r18 // krbs = old bsp - size of dirty partition + cmp.ne p9,p0=r0,r0 // clear p9 to skip restore of cr.ifs + ;; + sub r19=r19,r16 // calculate total byte size of dirty partition + add r18=64,r18 // don't force in0-in7 into memory... + ;; + shl r19=r19,16 // shift size of dirty partition into loadrs position + ;; +dont_preserve_current_frame: + /* + * To prevent leaking bits between the kernel and user-space, + * we must clear the stacked registers in the "invalid" partition here. + * Not pretty, but at least it's fast (3.34 registers/cycle on Itanium, + * 5 registers/cycle on McKinley). + */ +# define pRecurse p6 +# define pReturn p7 +#ifdef CONFIG_ITANIUM +# define Nregs 10 +#else +# define Nregs 14 +#endif + alloc loc0=ar.pfs,2,Nregs-2,2,0 + shr.u loc1=r18,9 // RNaTslots <= floor(dirtySize / (64*8)) + sub r17=r17,r18 // r17 = (physStackedSize + 8) - dirtySize + ;; + mov ar.rsc=r19 // load ar.rsc to be used for "loadrs" + shladd in0=loc1,3,r17 + mov in1=0 + ;; + TEXT_ALIGN(32) +rse_clear_invalid: +#ifdef CONFIG_ITANIUM + // cycle 0 + { .mii + alloc loc0=ar.pfs,2,Nregs-2,2,0 + cmp.lt pRecurse,p0=Nregs*8,in0 // if more than Nregs regs left to clear, (re)curse + add out0=-Nregs*8,in0 +}{ .mfb + add out1=1,in1 // increment recursion count + nop.f 0 + nop.b 0 // can't do br.call here because of alloc (WAW on CFM) + ;; +}{ .mfi // cycle 1 + mov loc1=0 + nop.f 0 + mov loc2=0 +}{ .mib + mov loc3=0 + mov loc4=0 +(pRecurse) br.call.sptk.many b0=rse_clear_invalid + +}{ .mfi // cycle 2 + mov loc5=0 + nop.f 0 + cmp.ne pReturn,p0=r0,in1 // if recursion count != 0, we need to do a br.ret +}{ .mib + mov loc6=0 + mov loc7=0 +(pReturn) br.ret.sptk.many b0 +} +#else /* !CONFIG_ITANIUM */ + alloc loc0=ar.pfs,2,Nregs-2,2,0 + cmp.lt pRecurse,p0=Nregs*8,in0 // if more than Nregs regs left to clear, (re)curse + add out0=-Nregs*8,in0 + add out1=1,in1 // increment recursion count + mov loc1=0 + mov loc2=0 + ;; + mov loc3=0 + mov loc4=0 + mov loc5=0 + mov loc6=0 + mov loc7=0 +(pRecurse) br.call.dptk.few b0=rse_clear_invalid + ;; + mov loc8=0 + mov loc9=0 + cmp.ne pReturn,p0=r0,in1 // if recursion count != 0, we need to do a br.ret + mov loc10=0 + mov loc11=0 +(pReturn) br.ret.dptk.many b0 +#endif /* !CONFIG_ITANIUM */ +# undef pRecurse +# undef pReturn + ;; + alloc r17=ar.pfs,0,0,0,0 // drop current register frame + ;; + loadrs + ;; +skip_rbs_switch: + mov ar.unat=r25 // M2 +(pKStk) extr.u r22=r22,21,1 // I0 extract current value of psr.pp from r22 +(pLvSys)mov r19=r0 // A clear r19 for leave_syscall, no-op otherwise + ;; +(pUStk) mov ar.bspstore=r23 // M2 +(pKStk) dep r29=r22,r29,21,1 // I0 update ipsr.pp with psr.pp +(pLvSys)mov r16=r0 // A clear r16 for leave_syscall, no-op otherwise + ;; +#ifdef CONFIG_XEN + movl r25=XSI_IPSR + ;; + st8[r25]=r29,XSI_IFS_OFS-XSI_IPSR_OFS + ;; +#else + mov cr.ipsr=r29 // M2 +#endif + mov ar.pfs=r26 // I0 +(pLvSys)mov r17=r0 // A clear r17 for leave_syscall, no-op otherwise + +#ifdef CONFIG_XEN +(p9) st8 [r25]=r30 + ;; + adds r25=XSI_IIP_OFS-XSI_IFS_OFS,r25 + ;; +#else +(p9) mov cr.ifs=r30 // M2 +#endif + mov b0=r21 // I0 +(pLvSys)mov r18=r0 // A clear r18 for leave_syscall, no-op otherwise + + mov ar.fpsr=r20 // M2 +#ifdef CONFIG_XEN + st8 [r25]=r28 +#else + mov cr.iip=r28 // M2 +#endif + nop 0 + ;; +(pUStk) mov ar.rnat=r24 // M2 must happen with RSE in lazy mode + nop 0 +(pLvSys)mov r2=r0 + + mov ar.rsc=r27 // M2 + mov pr=r31,-1 // I0 +#ifdef CONFIG_XEN + ;; + XEN_HYPER_RFI; +#else + rfi // B +#endif + + /* + * On entry: + * r20 = ¤t->thread_info->pre_count (if CONFIG_PREEMPT) + * r31 = current->thread_info->flags + * On exit: + * p6 = TRUE if work-pending-check needs to be redone + */ +.work_pending_syscall: + add r2=-8,r2 + add r3=-8,r3 + ;; + st8 [r2]=r8 + st8 [r3]=r10 +.work_pending: + tbit.z p6,p0=r31,TIF_NEED_RESCHED // current_thread_info()->need_resched==0? +(p6) br.cond.sptk.few .notify +#ifdef CONFIG_PREEMPT +(pKStk) dep r21=-1,r0,PREEMPT_ACTIVE_BIT,1 + ;; +(pKStk) st4 [r20]=r21 + ssm psr.i // enable interrupts +#endif + br.call.spnt.many rp=schedule +.ret9: cmp.eq p6,p0=r0,r0 // p6 <- 1 +#ifdef CONFIG_XEN + movl r2=XSI_PSR_I_ADDR + mov r20=1 + ;; + ld8 r2=[r2] + ;; + st1 [r2]=r20 +#else + rsm psr.i // disable interrupts +#endif + ;; +#ifdef CONFIG_PREEMPT +(pKStk) adds r20=TI_PRE_COUNT+IA64_TASK_SIZE,r13 + ;; +(pKStk) st4 [r20]=r0 // preempt_count() <- 0 +#endif +(pLvSys)br.cond.sptk.few .work_pending_syscall_end + br.cond.sptk.many .work_processed_kernel // re-check + +.notify: +(pUStk) br.call.spnt.many rp=notify_resume_user +.ret10: cmp.ne p6,p0=r0,r0 // p6 <- 0 +(pLvSys)br.cond.sptk.few .work_pending_syscall_end + br.cond.sptk.many .work_processed_kernel // don't re-check + +.work_pending_syscall_end: + adds r2=PT(R8)+16,r12 + adds r3=PT(R10)+16,r12 + ;; + ld8 r8=[r2] + ld8 r10=[r3] +#ifdef CONFIG_XEN + br.cond.sptk.many xen_work_processed_syscall // re-check +#else + br.cond.sptk.many .work_processed_syscall // re-check +#endif + +#ifdef CONFIG_XEN +END(xen_leave_kernel) +#else +END(ia64_leave_kernel) +#endif diff --git a/arch/ia64/xen/xenivt.S b/arch/ia64/xen/xenivt.S new file mode 100644 index 0000000..f2eaa1f --- /dev/null +++ b/arch/ia64/xen/xenivt.S @@ -0,0 +1,2204 @@ +/* + * arch/ia64/xen/ivt.S + * + * Copyright (C) 2005 Hewlett-Packard Co + * Dan Magenheimer <dan...@hp...> + */ +/* + * This file defines the interruption vector table used by the CPU. + * It does not include one entry per possible cause of interruption. + * + * The first 20 entries of the table contain 64 bundles each while the + * remaining 48 entries contain only 16 bundles each. + * + * The 64 bundles are used to allow inlining the whole handler for critical + * interruptions like TLB misses. + * + * For each entry, the comment is as follows: + * + * // 0x1c00 Entry 7 (size 64 bundles) Data Key Miss (12,51) + * entry offset ----/ / / / / + * entry number ---------/ / / / + * size of the entry -------------/ / / + * vector name -------------------------------------/ / + * interruptions triggering this vector ----------------------/ + * + * The table is 32KB in size and must be aligned on 32KB boundary. + * (The CPU ignores the 15 lower bits of the address) + * + * Table is based upon EAS2.6 (Oct 1999) + */ + + +#include <asm/asmmacro.h> +#include <asm/break.h> +#include <asm/ia32.h> +#include <asm/kregs.h> +#include <asm/asm-offsets.h> +#include <asm/pgtable.h> +#include <asm/processor.h> +#include <asm/ptrace.h> +#include <asm/system.h> +#include <asm/thread_info.h> +#include <asm/unistd.h> +#include <asm/errno.h> + +#ifdef CONFIG_XEN +#define ia64_ivt xen_ivt +#endif + +#if 1 +# define PSR_DEFAULT_BITS psr.ac +#else +# define PSR_DEFAULT_BITS 0 +#endif + +#if 0 + /* + * This lets you track the last eight faults that occurred on the CPU. Make sure ar.k2 isn't + * needed for something else before enabling this... + */ +# define DBG_FAULT(i) mov r16=ar.k2;; shl r16=r16,8;; add r16=(i),r16;;mov ar.k2=r16 +#else +# define DBG_FAULT(i) +#endif + +#ifdef CONFIG_XEN +#include "xenminstate.h" +#else +#include "minstate.h" +#endif + +#define FAULT(n) \ + mov r31=pr; \ + mov r19=n;; /* prepare to save predicates */ \ + br.sptk.many dispatch_to_fault_handler + + .section .text.ivt,"ax" + + .align 32768 // align on 32KB boundary + .global ia64_ivt +ia64_ivt: +///////////////////////////////////////////////////////////////////////////////////////// +// 0x0000 Entry 0 (size 64 bundles) VHPT Translation (8,20,47) +ENTRY(vhpt_miss) + DBG_FAULT(0) + /* + * The VHPT vector is invoked when the TLB entry for the virtual page table + * is missing. This happens only as a result of a previous + * (the "original") TLB miss, which may either be caused by an instruction + * fetch or a data access (or non-access). + * + * What we do here is normal TLB miss handing for the _original_ miss, + * followed by inserting the TLB entry for the virtual page table page + * that the VHPT walker was attempting to access. The latter gets + * inserted as long as page table entry above pte level have valid + * mappings for the faulting address. The TLB entry for the original + * miss gets inserted only if the pte entry indicates that the page is + * present. + * + * do_page_fault gets invoked in the following cases: + * - the faulting virtual address uses unimplemented address bits + * - the faulting virtual address has no valid page table mapping + */ +#ifdef CONFIG_XEN + movl r16=XSI_IFA + ;; + ld8 r16=[r16] +#ifdef CONFIG_HUGETLB_PAGE + movl r18=PAGE_SHIFT + movl r25=XSI_ITIR + ;; + ld8 r25=[r25] +#endif +#else + mov r16=cr.ifa // get address that caused the TLB miss +#ifdef CONFIG_HUGETLB_PAGE + movl r18=PAGE_SHIFT + mov r25=cr.itir +#endif +#endif + ;; +#ifdef CONFIG_XEN + XEN_HYPER_RSM_PSR_DT; +#else + rsm psr.dt // use physical addressing for data +#endif + mov r31=pr // save the predicate registers + mov r19=IA64_KR(PT_BASE) // get page table base address + shl r21=r16,3 // shift bit 60 into sign bit + shr.u r17=r16,61 // get the region number into r17 + ;; + shr.u r22=r21,3 +#ifdef CONFIG_HUGETLB_PAGE + extr.u r26=r25,2,6 + ;; + cmp.ne p8,p0=r18,r26 + sub r27=r26,r18 + ;; +(p8) dep r25=r18,r25,2,6 +(p8) shr r22=r22,r27 +#endif + ;; + cmp.eq p6,p7=5,r17 // is IFA pointing into to region 5? + shr.u r18=r22,PGDIR_SHIFT // get bottom portion of pgd index bit + ;; +(p7) dep r17=r17,r19,(PAGE_SHIFT-3),3 // put region number bits in place + + srlz.d + LOAD_PHYSICAL(p6, r19, swapper_pg_dir) // region 5 is rooted at swapper_pg_dir + + .pred.rel "mutex", p6, p7 +(p6) shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT +(p7) shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT-3 + ;; +(p6) dep r17=r18,r19,3,(PAGE_SHIFT-3) // r17=pgd_offset for region 5 +(p7) dep r17=r18,r17,3,(PAGE_SHIFT-6) // r17=pgd_offset for region[0-4] + cmp.eq p7,p6=0,r21 // unused address bits all zeroes? +#ifdef CONFIG_PGTABLE_4 + shr.u r28=r22,PUD_SHIFT // shift pud index into position +#else + shr.u r18=r22,PMD_SHIFT // shift pmd index into position +#endif + ;; + ld8 r17=[r17] // get *pgd (may be 0) + ;; +(p7) cmp.eq p6,p7=r17,r0 // was pgd_present(*pgd) == NULL? +#ifdef CONFIG_PGTABLE_4 + dep r28=r28,r17,3,(PAGE_SHIFT-3) // r28=pud_offset(pgd,addr) + ;; + shr.u r18=r22,PMD_SHIFT // shift pmd index into position +(p7) ld8 r29=[r28] // get *pud (may be 0) + ;; +(p7) cmp.eq.or.andcm p6,p7=r29,r0 // was pud_present(*pud) == NULL? + dep r17=r18,r29,3,(PAGE_SHIFT-3) // r17=pmd_offset(pud,addr) +#else + dep r17=r18,r17,3,(PAGE_SHIFT-3) // r17=pmd_offset(pgd,addr) +#endif + ;; +(p7) ld8 r20=[r17] // get *pmd (may be 0) + shr.u r19=r22,PAGE_SHIFT // shift pte index into position + ;; +(p7) cmp.eq.or.andcm p6,p7=r20,r0 // was pmd_present(*pmd) == NULL? + dep r21=r19,r20,3,(PAGE_SHIFT-3) // r21=pte_offset(pmd,addr) + ;; +(p7) ld8 r18=[r21] // read *pte +#ifdef CONFIG_XEN + movl r19=XSI_ISR + ;; + ld8 r19=[r19] +#else + mov r19=cr.isr // cr.isr bit 32 tells us if this is an insn miss +#endif + ;; +(p7) tbit.z p6,p7=r18,_PAGE_P_BIT // page present bit cleared? +#ifdef CONFIG_XEN + movl r22=XSI_IHA + ;; + ld8 r22=[r22] +#else + mov r22=cr.iha // get the VHPT address that caused the TLB miss +#endif + ;; // avoid RAW on p7 +(p7) tbit.nz.unc p10,p11=r19,32 // is it an instruction TLB miss? + dep r23=0,r20,0,PAGE_SHIFT // clear low bits to get page address + ;; +#ifdef CONFIG_XEN + mov r24=r8 + mov r8=r18 + ;; +(p10) XEN_HYPER_ITC_I + ;; +(p11) XEN_HYPER_ITC_D + ;; + mov r8=r24 + ;; +#else +(p10) itc.i r18 // insert the instruction TLB entry +(p11) itc.d r18 // insert the data TLB entry +#endif +(p6) br.cond.spnt.many page_fault // handle bad address/page not present (page fault) +#ifdef CONFIG_XEN + movl r24=XSI_IFA + ;; + st8 [r24]=r22 + ;; +#ifdef CONFIG_HUGETLB_PAGE +(p8) movl r24=XSI_ITIR + ;; +(p8) st8 [r24]=r25 +#endif +#else + mov cr.ifa=r22 + +#ifdef CONFIG_HUGETLB_PAGE +(p8) mov cr.itir=r25 // change to default page-size for VHPT +#endif +#endif + + /* + * Now compute and insert the TLB entry for the virtual page table. We never + * execute in a page table page so there is no need to set the exception deferral + * bit. + */ + adds r24=__DIRTY_BITS_NO_ED|_PAGE_PL_0|_PAGE_AR_RW,r23 + ;; +#ifdef CONFIG_XEN +(p7) mov r25=r8 +(p7) mov r8=r24 + ;; +(p7) XEN_HYPER_ITC_D + ;; +(p7) mov r8=r25 + ;; +#else +(p7) itc.d r24 +#endif + ;; +#ifdef CONFIG_SMP + /* + * Tell the assemblers dependency-violation checker that the above "itc" instructions + * cannot possibly affect the following loads: + */ + dv_serialize_data + + /* + * Re-check pagetable entry. If they changed, we may have received a ptc.g + * between reading the pagetable and the "itc". If so, flush the entry we + * inserted and retry. At this point, we have: + * + * r28 = equivalent of pud_offset(pgd, ifa) + * r17 = equivalent of pmd_offset(pud, ifa) + * r21 = equivalent of pte_offset(pmd, ifa) + * + * r29 = *pud + * r20 = *pmd + * r18 = *pte + */ + ld8 r25=[r21] // read *pte again + ld8 r26=[r17] // read *pmd again +#ifdef CONFIG_PGTABLE_4 + ld8 r19=[r28] // read *pud again +#endif + cmp.ne p6,p7=r0,r0 + ;; + cmp.ne.or.andcm p6,p7=r26,r20 // did *pmd change +#ifdef CONFIG_PGTABLE_4 + cmp.ne.or.andcm p6,p7=r19,r29 // did *pud change +#endif + mov r27=PAGE_SHIFT<<2 + ;; +(p6) ptc.l r22,r27 // purge PTE page translation +(p7) cmp.ne.or.andcm p6,p7=r25,r18 // did *pte change + ;; +(p6) ptc.l r16,r27 // purge translation +#endif + + mov pr=r31,-1 // restore predicate registers +#ifdef CONFIG_XEN + XEN_HYPER_RFI + dv_serialize_data +#else + rfi +#endif +END(vhpt_miss) + + .org ia64_ivt+0x400 +///////////////////////////////////////////////////////////////////////////////////////// +// 0x0400 Entry 1 (size 64 bundles) ITLB (21) +ENTRY(itlb_miss) + DBG_FAULT(1) + /* + * The ITLB handler accesses the PTE via the virtually mapped linear + * page table. If a nested TLB miss occurs, we switch into physical + * mode, walk the page table, and then re-execute the PTE read and + * go on normally after that. + */ +#ifdef CONFIG_XEN + movl r16=XSI_IFA + ;; + ld8 r16=[r16] +#else + mov r16=cr.ifa // get virtual address +#endif + mov r29=b0 // save b0 + mov r31=pr // save predicates +.itlb_fault: +#ifdef CONFIG_XEN + movl r17=XSI_IHA + ;; + ld8 r17=[r17] // get virtual address of L3 PTE +#else + mov r17=cr.iha // get virtual address of PTE +#endif + movl r30=1f // load nested fault continuation point + ;; +1: ld8 r18=[r17] // read *pte + ;; + mov b0=r29 + tbit.z p6,p0=r18,_PAGE_P_BIT // page present bit cleared? +(p6) br.cond.spnt page_fault + ;; +#ifdef CONFIG_XEN + mov r19=r8 + mov r8=r18 + ;; + XEN_HYPER_ITC_I + ;; + mov r8=r19 +#else + itc.i r18 +#endif + ;; +#ifdef CONFIG_SMP + /* + * Tell the assemblers dependency-violation checker that the above "itc" instructions + * cannot possibly affect the following loads: + */ + dv_serialize_data + + ld8 r19=[r17] // read *pte again and see if same + mov r20=PAGE_SHIFT<<2 // setup page size for purge + ;; + cmp.ne p7,p0=r18,r19 + ;; +(p7) ptc.l r16,r20 +#endif + mov pr=r31,-1 +#ifdef CONFIG_XEN + XEN_HYPER_RFI + dv_serialize_data +#else + rfi +#endif +END(itlb_miss) + + .org ia64_ivt+0x0800 +///////////////////////////////////////////////////////////////////////////////////////// +// 0x0800 Entry 2 (size 64 bundles) DTLB (9,48) +ENTRY(dtlb_miss) + DBG_FAULT(2) + /* + * The DTLB handler accesses the PTE via the virtually mapped linear + * page table. If a nested TLB miss occurs, we switch into physical + * mode, walk the page table, and then re-execute the PTE read and + * go on normally after that. + */ +#ifdef CONFIG_XEN + movl r16=XSI_IFA + ;; + ld8 r16=[r16] +#else + mov r16=cr.ifa // get virtual address +#endif + mov r29=b0 // save b0 + mov r31=pr // save predicates +dtlb_fault: +#ifdef CONFIG_XEN + movl r17=XSI_IHA + ;; + ld8 r17=[r17] // get virtual address of L3 PTE +#else + mov r17=cr.iha // get virtual address of PTE +#endif + movl r30=1f // load nested fault continuation point + ;; +1: ld8 r18=[r17] // read *pte + ;; + mov b0=r29 + tbit.z p6,p0=r18,_PAGE_P_BIT // page present bit cleared? +(p6) br.cond.spnt page_fault + ;; +#ifdef CONFIG_XEN + mov r19=r8 + mov r8=r18 + ;; + XEN_HYPER_ITC_D + ;; + mov r8=r19 + ;; +#else + itc.d r18 +#endif + ;; +#ifdef CONFIG_SMP + /* + * Tell the assemblers dependency-violation checker that the above "itc" instructions + * cannot possibly affect the following loads: + */ + dv_serialize_data + + ld8 r19=[r17] // read *pte again and see if same + mov r20=PAGE_SHIFT<<2 // setup page size for purge + ;; + cmp.ne p7,p0=r18,r19 + ;; +(p7) ptc.l r16,r20 +#endif + mov pr=r31,-1 +#ifdef CONFIG_XEN + XEN_HYPER_RFI + dv_serialize_data +#else + rfi +#endif +END(dtlb_miss) + + .org ia64_ivt+0x0c00 +///////////////////////////////////////////////////////////////////////////////////////// +// 0x0c00 Entry 3 (size 64 bundles) Alt ITLB (19) +ENTRY(alt_itlb_miss) + DBG_FAULT(3) +#ifdef CONFIG_XEN + movl r31=XSI_IPSR + ;; + ld8 r21=[r31],XSI_IFA_OFS-XSI_IPSR_OFS // get ipsr, point to ifa + movl r17=PAGE_KERNEL + ;; + ld8 r16=[r31] // get ifa +#else + mov r16=cr.ifa // get address that caused the TLB miss + movl r17=PAGE_KERNEL + mov r21=cr.ipsr +#endif + movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff) + mov r31=pr + ;; +#ifdef CONFIG_DISABLE_VHPT + shr.u r22=r16,61 // get the region number into r21 + ;; + cmp.gt p8,p0=6,r22 // user mode + ;; +#ifdef CONFIG_XEN + //XXX notyet +#else +(p8) thash r17=r16 + ;; +(p8) mov cr.iha=r17 +#endif +(p8) mov r29=b0 // save b0 +(p8) br.cond.dptk .itlb_fault +#endif + extr.u r23=r21,IA64_PSR_CPL0_BIT,2 // extract psr.cpl + and r19=r19,r16 // clear ed, reserved bits, and PTE control bits + shr.u r18=r16,57 // move address bit 61 to bit 4 + ;; + andcm r18=0x10,r18 // bit 4=~address-bit(61) + cmp.ne p8,p0=r0,r23 // psr.cpl != 0? + or r19=r17,r19 // insert PTE control bits into r19 + ;; + or r19=r19,r18 // set bit 4 (uncached) if the access was to region 6 +(p8) br.cond.spnt page_fault + ;; +#ifdef CONFIG_XEN + mov r18=r8 + mov r8=r19 + ;; + XEN_HYPER_ITC_I + ;; + mov r8=r18 + ;; + mov pr=r31,-1 + ;; + XEN_HYPER_RFI; +#else + itc.i r19 // insert the TLB entry + mov pr=r31,-1 + rfi +#endif +END(alt_itlb_miss) + + .org ia64_ivt+0x1000 +///////////////////////////////////////////////////////////////////////////////////////// +// 0x1000 Entry 4 (size 64 bundles) Alt DTLB (7,46) +ENTRY(alt_dtlb_miss) + DBG_FAULT(4) +#ifdef CONFIG_XEN + movl r31=XSI_IPSR + ;; + ld8 r21=[r31],XSI_ISR_OFS-XSI_IPSR_OFS // get ipsr, point to isr + movl r17=PAGE_KERNEL + ;; + ld8 r20=[r31],XSI_IFA_OFS-XSI_ISR_OFS // get isr, point to ifa + movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff) + ;; + ld8 r16=[r31] // get ifa +#else + mov r16=cr.ifa // get address that caused the TLB miss + movl r17=PAGE_KERNEL + mov r20=cr.isr + movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff) + mov r21=cr.ipsr +#endif + mov r31=pr + mov r24=PERCPU_ADDR + ;; +#ifdef CONFIG_DISABLE_VHPT + shr.u r22=r16,61 // get the region number into r21 + ;; + cmp.gt p8,p0=6,r22 // access to region 0-5 + ;; +#ifdef CONFIG_XEN + //XXX notyet +#else +(p8) thash r17=r16 + ;; +(p8) mov cr.iha=r17 +#endif +(p8) mov r29=b0 // save b0 +(p8) br.cond.dptk dtlb_fault +#endif + cmp.ge p10,p11=r16,r24 // access to per_cpu_data? + tbit.z p12,p0=r16,61 // access to region 6? + mov r25=PERCPU_PAGE_SHIFT << 2 + mov r26=PERCPU_PAGE_SIZE + nop.m 0 + nop.b 0 + ;; +(p10) mov r19=IA64_KR(PER_CPU_DATA) +(p11) and r19=r19,r16 // clear non-ppn fields + extr.u r23=r21,IA64_PSR_CPL0_BIT,2 // extract psr.cpl + and r22=IA64_ISR_CODE_MASK,r20 // get the isr.code field + tbit.nz p6,p7=r20,IA64_ISR_SP_BIT // is speculation bit on? + tbit.nz p9,p0=r20,IA64_ISR_NA_BIT // is non-access bit on? + ;; +(p10) sub r19=r19,r26 +#ifdef CONFIG_XEN +(p10) movl r24=XSI_ITIR + ;; +(p10) st8 [r24]=r25 +#else +(p10) mov cr.itir=r25 +#endif + cmp.ne p8,p0=r0,r23 +(p9) cmp.eq.or.andcm p6,p7=IA64_ISR_CODE_LFETCH,r22 // check isr.code field +(p12) dep r17=-1,r17,4,1 // set ma=UC for region 6 addr +(p8) br.cond.spnt page_fault + + dep r21=-1,r21,IA64_PSR_ED_BIT,1 + ;; + or r19=r19,r17 // insert PTE control bits into r19 +(p6) mov cr.ipsr=r21 + ;; +#ifdef CONFIG_XEN +(p7) mov r18=r8 +(p7) mov r8=r19 + ;; +(p7) XEN_HYPER_ITC_D + ;; +(p7) mov r8=r18 + ;; + mov pr=r31,-1 + ;; + XEN_HYPER_RFI; +#else +(p7) itc.d r19 // insert the TLB entry + mov pr=r31,-1 + rfi +#endif +END(alt_dtlb_miss) + + .org ia64_ivt+0x1400 +///////////////////////////////////////////////////////////////////////////////////////// +// 0x1400 Entry 5 (size 64 bundles) Data nested TLB (6,45) +ENTRY(nested_dtlb_miss) + /* + * In the absence of kernel bugs, we get here when the virtually mapped linear + * page table is accessed non-speculatively (e.g., in the Dirty-bit, Instruction + * Access-bit, or Data Access-bit faults). If the DTLB entry for the virtual page + * table is missing, a nested TLB miss fault is triggered and control is + * transferred to this point. When this happens, we lookup the pte for the + * faulting address by walking the page table in physical mode and return to the + * continuation point passed in register r30 (or call page_fault if the address is + * not mapped). + * + * Input: r16: faulting address + * r29: saved b0 + * r30: continuation address + * r31: saved pr + * + * Output: r17: physical address of PTE of faulting address + * r29: saved b0 + * r30: continuation address + * r31: saved pr + * + * Clobbered: b0, r18, r19, r21, r22, psr.dt (cleared) + */ +#ifdef CONFIG_XEN + XEN_HYPER_RSM_PSR_DT; +#else + rsm psr.dt // switch to using physical data addressing +#endif + mov r19=IA64_KR(PT_BASE) // get the page table base address + shl r21=r16,3 // shift bit 60 into sign bit +#ifdef CONFIG_XEN + movl r18=XSI_ITIR + ;; + ld8 r18=[r18] +#else + mov r18=cr.itir +#endif + ;; + shr.u r17=r16,61 // get the region number into r17 + extr.u r18=r18,2,6 // get the faulting page size + ;; + cmp.eq p6,p7=5,r17 // is faulting address in region 5? + add r22=-PAGE_SHIFT,r18 // adjustment for hugetlb address + add r18=PGDIR_SHIFT-PAGE_SHIFT,r18 + ;; + shr.u r22=r16,r22 + shr.u r18=r16,r18 +(p7) dep r17=r17,r19,(PAGE_SHIFT-3),3 // put region number bits in place + + srlz.d + LOAD_PHYSICAL(p6, r19, swapper_pg_dir) // region 5 is rooted at swapper_pg_dir + + .pred.rel "mutex", p6, p7 +(p6) shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT +(p7) shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT-3 + ;; +(p6) dep r17=r18,r19,3,(PAGE_SHIFT-3) // r17=pgd_offset for region 5 +(p7) dep r17=r18,r17,3,(PAGE_SHIFT-6) // r17=pgd_offset for region[0-4] + cmp.eq p7,p6=0,r21 // unused address bits all zeroes? +#ifdef CONFIG_PGTABLE_4 + shr.u r18=r22,PUD_SHIFT // shift pud index into position +#else + shr.u r18=r22,PMD_SHIFT // shift pmd index into position +#endif + ;; + ld8 r17=[r17] // get *pgd (may be 0) + ;; +(p7) cmp.eq p6,p7=r17,r0 // was pgd_present(*pgd) == NULL? + dep r17=r18,r17,3,(PAGE_SHIFT-3) // r17=p[u|m]d_offset(pgd,addr) + ;; +#ifdef CONFIG_PGTABLE_4 +(p7) ld8 r17=[r17] // get *pud (may be 0) + shr.u r18=r22,PMD_SHIFT // shift pmd index into position + ;; +(p7) cmp.eq.or.andcm p6,p7=r17,r0 // was pud_present(*pud) == NULL? + dep r17=r18,r17,3,(PAGE_SHIFT-3) // r17=pmd_offset(pud,addr) + ;; +#endif +(p7) ld8 r17=[r17] // get *pmd (may be 0) + shr.u r19=r22,PAGE_SHIFT // shift pte index into position + ;; +(p7) cmp.eq.or.andcm p6,p7=r17,r0 // was pmd_present(*pmd) == NULL? + dep r17=r19,r17,3,(PAGE_SHIFT-3) // r17=pte_offset(pmd,addr); +(p6) br.cond.spnt page_fault + mov b0=r30 + br.sptk.many b0 // return to continuation point +END(nested_dtlb_miss) + + .org ia64_ivt+0x1800 +///////////////////////////////////////////////////////////////////////////////////////// +// 0x1800 Entry 6 (size 64 bundles) Instruction Key Miss (24) +ENTRY(ikey_miss) + DBG_FAULT(6) + FAULT(6) +END(ikey_miss) + + //----------------------------------------------------------------------------------- + // call do_page_fault (predicates are in r31, psr.dt may be off, r16 is faulting address) +ENTRY(page_fault) +#ifdef CONFIG_XEN + XEN_HYPER_SSM_PSR_DT +#else + ssm psr.dt + ;; + srlz.i +#endif + ;; + SAVE_MIN_WITH_COVER + alloc r15=ar.pfs,0,0,3,0 +#ifdef CONFIG_XEN + movl r3=XSI_ISR + ;; + ld8 out1=[r3],XSI_IFA_OFS-XSI_ISR_OFS // get vcr.isr, point to ifa + ;; + ld8 out0=[r3] // get vcr.ifa + mov r14=1 + ;; + add r3=XSI_PSR_IC_OFS-XSI_IFA_OFS, r3 // point to vpsr.ic + ;; + st4 [r3]=r14 // vpsr.ic = 1 + adds r3=8,r2 // set up second base pointer + ;; +#else + mov out0=cr.ifa + mov out1=cr.isr + adds r3=8,r2 // set up second base pointer + ;; + ssm psr.ic | PSR_DEFAULT_BITS + ;; + srlz.i // guarantee that interruption collectin is on + ;; +#endif +#ifdef CONFIG_XEN + +#define MASK_TO_PEND_OFS (-1) + +(p15) movl r14=XSI_PSR_I_ADDR + ;; +(p15) ld8 r14=[r14] + ;; +(p15) st1 [r14]=r0,MASK_TO_PEND_OFS // if (p15) vpsr.i = 1 + ;; // if (p15) (vcpu->vcpu_info->evtchn_upcall_mask)=0 +(p15) ld1 r14=[r14] // if (vcpu->vcpu_info->evtchn_upcall_pending) + ;; +(p15) cmp.ne p15,p0=r14,r0 + ;; +(p15) XEN_HYPER_SSM_I +#else +(p15) ssm psr.i // restore psr.i +#endif + movl r14=ia64_leave_kernel + ;; + SAVE_REST + mov rp=r14 + ;; + adds out2=16,r12 // out2 = pointer to pt_regs + br.call.sptk.many b6=ia64_do_page_fault // ignore return address +END(page_fault) + + .org ia64_ivt+0x1c00 +///////////////////////////////////////////////////////////////////////////////////////// +// 0x1c00 Entry 7 (size 64 bundles) Data Key Miss (12,51) +ENTRY(dkey_miss) + DBG_FAULT(7) + FAULT(7) +END(dkey_miss) + + .org ia64_ivt+0x2000 +///////////////////////////////////////////////////////////////////////////////////////// +// 0x2000 Entry 8 (size 64 bundles) Dirty-bit (54) +ENTRY(dirty_bit) + DBG_FAULT(8) + /* + * What we do here is to simply turn on the dirty bit in the PTE. We need to + * update both the page-table and the TLB entry. To efficiently access the PTE, + * we address it through the virtual page table. Most likely, the TLB entry for + * the relevant virtual page table page is still present in the TLB so we can + * normally do this without additional TLB misses. In case the necessary virtual + * page table TLB entry isn't present, we take a nested TLB miss hit where we look + * up the physical address of the L3 PTE and then continue at label 1 below. + */ +#ifdef CONFIG_XEN + movl r16=XSI_IFA + ;; + ld8 r16=[r16] + ;; +#else + mov r16=cr.ifa // get the address that caused the fault +#endif + movl r30=1f // load continuation point in case of nested fault + ;; +#ifdef CONFIG_XEN + mov r18=r8; + mov r8=r16; + XEN_HYPER_THASH;; + mov r17=r8; + mov r8=r18;; +#else + thash r17=r16 // compute virtual address of L3 PTE +#endif + mov r29=b0 // save b0 in case of nested fault + mov r31=pr // save pr +#ifdef CONFIG_SMP + mov r28=ar.ccv // save ar.ccv + ;; +1: ld8 r18=[r17] + ;; // avoid RAW on r18 + mov ar.ccv=r18 // set compare value for cmpxchg + or r25=_PAGE_D|_PAGE_A,r18 // set the dirty and accessed bits + tbit.z p7,p6 = r18,_PAGE_P_BIT // Check present bit + ;; +(p6) cmpxchg8.acq r26=[r17],r25,ar.ccv // Only update if page is present + mov r24=PAGE_SHIFT<<2 + ;; +(p6) cmp.eq p6,p7=r26,r18 // Only compare if page is present + ;; +#ifdef CONFIG_XEN +(p6) mov r18=r8 +(p6) mov r8=r25 + ;; +(p6) XEN_HYPER_ITC_D + ;; +(p6) mov r8=r18 +#else +(p6) itc.d r25 // install updated PTE +#endif + ;; + /* + * Tell the assemblers dependency-violation checker that the above "itc" instructions + * cannot possibly affect the following loads: + */ + dv_serialize_data + + ld8 r18=[r17] // read PTE again + ;; + cmp.eq p6,p7=r18,r25 // is it same as the newly installed + ;; +(p7) ptc.l r16,r24 + mov b0=r29 // restore b0 + mov ar.ccv=r28 +#else + ;; +1: ld8 r18=[r17] + ;; // avoid RAW on r18 + or r18=_PAGE_D|_PAGE_A,r18 // set the dirty and accessed bits + mov b0=r29 // restore b0 + ;; + st8 [r17]=r18 // store back updated PTE + itc.d r18 // install updated PTE +#endif + mov pr=r31,-1 // restore pr +#ifdef CONFIG_XEN + XEN_HYPER_RFI + dv_serialize_data +#else + rfi +#endif +END(dirty_bit) + + .org ia64_ivt+0x2400 +///////////////////////////////////////////////////////////////////////////////////////// +// 0x2400 Entry 9 (size 64 bundles) Instruction Access-bit (27) +ENTRY(iaccess_bit) + DBG_FAULT(9) + // Like Entry 8, except for instruction access +#ifdef CONFIG_XEN + movl r16=XSI_IFA + ;; + ld8 r16=[r16] + ;; +#else + mov r16=cr.ifa // get the address that caused the fault +#endif + movl r30=1f // load continuation point in case of nested fault + mov r31=pr // save predicates +#ifdef CONFIG_ITANIUM + /* + * Erratum 10 (IFA may contain incorrect address) has "NoFix" status. + */ + mov r17=cr.ipsr + ;; + mov r18=cr.iip + tbit.z p6,p0=r17,IA64_PSR_IS_BIT // IA64 instruction set? + ;; +(p6) mov r16=r18 // if so, use cr.iip instead of cr.ifa +#endif /* CONFIG_ITANIUM */ + ;; +#ifdef CONFIG_XEN + mov r18=r8; + mov r8=r16; + XEN_HYPER_THASH;; + mov r17=r8; + mov r8=r18;; +#else + thash r17=r16 // compute virtual address of L3 PTE +#endif + mov r29=b0 // save b0 in case of nested fault) +#ifdef CONFIG_SMP + mov r28=ar.ccv // save ar.ccv + ;; +1: ld8 r18=[r17] + ;; + mov ar.ccv=r18 // set compare value for cmpxchg + or r25=_PAGE_A,r18 // set the accessed bit + tbit.z p7,p6 = r18,_PAGE_P_BIT // Check present bit + ;; +(p6) cmpxchg8.acq r26=[r17],r25,ar.ccv // Only if page present + mov r24=PAGE_SHIFT<<2 + ;; +(p6) cmp.eq p6,p7=r26,r18 // Only if page present + ;; +#ifdef CONFIG_XEN + mov r26=r8 + mov r8=r25 + ;; +(p6) XEN_HYPER_ITC_I + ;; + mov r8=r26 + ;; +#else +(p6) itc.i r25 // install updated PTE +#endif + ;; + /* + * Tell the assemblers dependency-violation checker that the above "itc" instructions + * cannot possibly affect the following loads: + */ + dv_serialize_data + + ld8 r18=[r17] // read PTE again + ;; + cmp.eq p6,p7=r18,r25 // is it same as the newly installed + ;; +(p7) ptc.l r16,r24 + mov b0=r29 // restore b0 + mov ar.ccv=r28 +#else /* !CONFIG_SMP */ + ;; +1: ld8 r18=[r17] + ;; + or r18=_PAGE_A,r18 // set the accessed bit + mov b0=r29 // restore b0 + ;; + st8 [r17]=r18 // store back updated PTE + itc.i r18 // install updated PTE +#endif /* !CONFIG_SMP */ + mov pr=r31,-1 +#ifdef CONFIG_XEN + XEN_HYPER_RFI + dv_serialize_data +#else + rfi +#endif +END(iaccess_bit) + + .org ia64_ivt+0x2800 +///////////////////////////////////////////////////////////////////////////////////////// +// 0x2800 Entry 10 (size 64 bundles) Data Access-bit (15,55) +ENTRY(daccess_bit) + DBG_FAULT(10) + // Like Entry 8, except for data access +#ifdef CONFIG_XEN + movl r16=XSI_IFA + ;; + ld8 r16=[r16] + ;; +#else + mov r16=cr.ifa // get the address that caused the fault +#endif + movl r30=1f // load continuation point in case of nested fault + ;; +#ifdef CONFIG_XEN + mov r18=r8 + mov r8=r16 + XEN_HYPER_THASH + ;; + mov r17=r8 + mov r8=r18 + ;; +#else + thash r17=r16 // compute virtual address of L3 PTE +#endif + mov r31=pr + mov r29=b0 // save b0 in case of nested fault) +#ifdef CONFIG_SMP + mov r28=ar.ccv // save ar.ccv + ;; +1: ld8 r18=[r17] + ;; // avoid RAW on r18 + mov ar.ccv=r18 // set compare value for cmpxchg + or r25=_PAGE_A,r18 // set the dirty bit + tbit.z p7,p6 = r18,_PAGE_P_BIT // Check present bit + ;; +(p6) cmpxchg8.acq r26=[r17],r25,ar.ccv // Only if page is present + mov r24=PAGE_SHIFT<<2 + ;; +(p6) cmp.eq p6,p7=r26,r18 // Only if page is present + ;; +#ifdef CONFIG_XEN + mov r26=r8 + mov r8=r25 + ;; +(p6) XEN_HYPER_ITC_D + ;; + mov r8=r26 + ;; +#else +(p6) itc.d r25 // install updated PTE +#endif + /* + * Tell the assemblers dependency-violation checker that the above "itc" instructions + * cannot possibly affect the following loads: + */ + dv_serialize_data + ;; + ld8 r18=[r17] // read PTE again + ;; + cmp.eq p6,p7=r18,r25 // is it same as the newly installed + ;; +(p7) ptc.l r16,r24 + mov ar.ccv=r28 +#else + ;; +1: ld8 r18=[r17] + ;; // avoid RAW on r18 + or r18=_PAGE_A,r18 // set the accessed bit + ;; + st8 [r17]=r18 // store back updated PTE + itc.d r18 // install updated PTE +#endif + mov b0=r29 // restore b0 + mov pr=r31,-1 +#ifdef CONFIG_XEN + XEN_HYPER_RFI + dv_serialize_data +#else + rfi +#endif +END(daccess_bit) + + .org ia64_ivt+0x2c00 +///////////////////////////////////////////////////////////////////////////////////////// +// 0x2c00 Entry 11 (size 64 bundles) Break instruction (33) +ENTRY(break_fault) + /* + * The streamlined system call entry/exit paths only save/restore the initial part + * of pt_regs. This implies that the callers of system-calls must adhere to the + * normal procedure calling conventions. + * + * Registers to be saved & restored: + * CR registers: cr.ipsr, cr.iip, cr.ifs + * AR registers: ar.unat, ar.pfs, ar.rsc, ar.rnat, ar.bspstore, ar.fpsr + * others: pr, b0, b6, loadrs, r1, r11, r12, r13, r15 + * Registers to be restored only: + * r8-r11: output value from the system call. + * + * During system call exit, scratch registers (including r15) are modified/cleared + * to prevent leaking bits from kernel to user level. + */ + DBG_FAULT(11) + mov.m r16=IA64_KR(CURRENT) // M2 r16 <- current task (12 cyc) +#ifdef CONFIG_XEN + movl r22=XSI_IPSR + ;; + ld8 r29=[r22],XSI_IIM_OFS-XSI_IPSR_OFS // get ipsr, point to iip +#else + mov r29=cr.ipsr // M2 (12 cyc) +#endif + mov r31=pr // I0 (2 cyc) + +#ifdef CONFIG_XEN + ;; + ld8 r17=[r22],XSI_IIP_OFS-XSI_IIM_OFS +#else + mov r17=cr.iim // M2 (2 cyc) +#endif + mov.m r27=ar.rsc // M2 (12 cyc) + mov r18=__IA64_BREAK_SYSCALL // A + + mov.m ar.rsc=0 // M2 + mov.m r21=ar.fpsr // M2 (12 cyc) + mov r19=b6 // I0 (2 cyc) + ;; + mov.m r23=ar.bspstore // M2 (12 cyc) + mov.m r24=ar.rnat // M2 (5 cyc) + mov.i r26=ar.pfs // I0 (2 cyc) + + invala // M0|1 + nop.m 0 // M + mov r20=r1 // A save r1 + + nop.m 0 + movl r30=sys_call_table // X + +#ifdef CONFIG_XEN + ld8 r28=[r22] +#else + mov r28=cr.iip // M2 (2 cyc) +#endif + cmp.eq p0,p7=r18,r17 // I0 is this a system call? +(p7) br.cond.spnt non_syscall // B no -> + // + // From this point on, we are definitely on the syscall-path + // and we can use (non-banked) scratch registers. + // +/////////////////////////////////////////////////////////////////////// + mov r1=r16 // A move task-pointer to "addl"-addressable reg + mov r2=r16 // A setup r2 for ia64_syscall_setup + add r9=TI_FLAGS+IA64_TASK_SIZE,r16 // A r9 = ¤t_thread_info()->flags + + adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16 + adds r15=-1024,r15 // A subtract 1024 from syscall number + mov r3=NR_syscalls - 1 + ;; + ld1.bias r17=[r16] // M0|1 r17 = current->thread.on_ustack flag + ld4 r9=[r9] // M0|1 r9 = current_thread_info()->flags + extr.u r8=r29,41,2 // I0 extract ei field from cr.ipsr + + shladd r30=r15,3,r30 // A r30 = sys_call_table + 8*(syscall-1024) + addl r22=IA64_RBS_OFFSET,r1 // A compute base of RBS + cmp.leu p6,p7=r15,r3 // A syscall number in range? + ;; + + lfetch.fault.excl.nt1 [r22] // M0|1 prefetch RBS +(p6) ld8 r30=[r30] // M0|1 load address of syscall entry point + tnat.nz.or p7,p0=r15 // I0 is syscall nr a NaT? + + mov.m ar.bspstore=r22 // M2 switch to kernel RBS + cmp.eq p8,p9=2,r8 // A isr.ei==2? + ;; + +(p8) mov r8=0 // A clear ei to 0 +(p7) movl r30=sys_ni_syscall // X + +(p8) adds r28=16,r28 // A switch cr.iip to next bundle +(p9) adds r8=1,r8 // A increment ei to next slot + nop.i 0 + ;; + + mov.m r25=ar.unat // M2 (5 cyc) + dep r29=r8,r29,41,2 // I0 insert new ei into cr.ipsr + adds r15=1024,r15 // A restore original syscall number + // + // If any of the above loads miss in L1D, we'll stall here until + // the data arrives. + // +/////////////////////////////////////////////////////////////////////// + st1 [r16]=r0 // M2|3 clear current->thread.on_ustack flag + mov b6=r30 // I0 setup syscall handler branch reg early + cmp.eq pKStk,pUStk=r0,r17 // A were we on kernel stacks already? + + and r9=_TIF_SYSCALL_TRACEAUDIT,r9 // A mask trace or audit + mov r18=ar.bsp // M2 (12 cyc) +(pKStk) br.cond.spnt .break_fixup // B we're already in kernel-mode -- fix up RBS + ;; +.back_from_break_fixup: +(pUStk) addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1 // A compute base of memory stack + cmp.eq p14,p0=r9,r0 // A are syscalls being traced/audited? + br.call.sptk.many b7=ia64_syscall_setup // B +1: + mov ar.rsc=0x3 // M2 set eager mode, pl 0, LE, loadrs=0 + nop 0 +#ifdef CONFIG_XEN + mov r2=b0; br.call.sptk b0=xen_bsw1;; mov b0=r2;; +#else + bsw.1 // B (6 cyc) regs are saved, switch to bank 1 +#endif + ;; + +#ifdef CONFIG_XEN + movl r16=XSI_PSR_IC + mov r3=1 + ;; + st4 [r16]=r3,XSI_PSR_I_ADDR_OFS-XSI_PSR_IC_OFS // vpsr.ic = 1 +#else + ssm psr.ic | PSR_DEFAULT_BITS // M2 now it's safe to re-enable intr.-collection +#endif + movl r3=ia64_ret_from_syscall // X + ;; + + srlz.i // M0 ensure interruption collection is on + mov rp=r3 // I0 set the real return addr +(p10) br.cond.spnt.many ia64_ret_from_syscall // B return if bad call-frame or r15 is a NaT + +#ifdef CONFIG_XEN +(p15) ld8 r16=[r16] // vpsr.i + ;; +(p15) st1 [r16]=r0,MASK_TO_PEND_OFS // if (p15) vpsr.i = 1 + ;; // if (p15) (vcpu->vcpu_info->evtchn_upcall_mask)=0 +(p15) ld1 r2=[r16] // if (vcpu->vcpu_info->evtchn_upcall_pending) + ;; +(p15) cmp.ne.unc p6,p0=r2,r0 + ;; +(p6) XEN_HYPER_SSM_I // do a real ssm psr.i +#else +(p15) ssm psr.i // M2 restore psr.i +#endif +(p14) br.call.sptk.many b6=b6 // B invoke syscall-handker (ignore return addr) + br.cond.spnt.many ia64_trace_syscall // B do syscall-tracing thingamagic + // NOT REACHED +/////////////////////////////////////////////////////////////////////// + // On entry, we optimistically assumed that we're coming from user-space. + // For the rare cases where a system-call is done from within the kernel, + // we fix things up at this point: +.break_fixup: + add r1=-IA64_PT_REGS_SIZE,sp // A allocate space for pt_regs structure + mov ar.rnat=r24 // M2 restore kernel's AR.RNAT + ;; + mov ar.bspstore=r23 // M2 restore kernel's AR.BSPSTORE + br.cond.sptk .back_from_break_fixup +END(break_fault) + + .org ia64_ivt+0x3000 +///////////////////////////////////////////////////////////////////////////////////////// +// 0x3000 Entry 12 (size 64 bundles) External Interrupt (4) +ENTRY(interrupt) + DBG_FAULT(12) + mov r31=pr // prepare to save predicates + ;; + SAVE_MIN_WITH_COVER // uses r31; defines r2 and r3 +#ifdef CONFIG_XEN + movl r3=XSI_PSR_IC + mov r14=1 + ;; + st4 [r3]=r14 +#else + ssm psr.ic | PSR_DEFAULT_BITS +#endif + ;; + adds r3=8,r2 // set up second base pointer for SAVE_REST + srlz.i // ensure everybody knows psr.ic is back on + ;; + SAVE_REST + ;; + MCA_RECOVER_RANGE(interrupt) + alloc r14=ar.pfs,0,0,2,0 // must be first in an insn group +#ifdef CONFIG_XEN + ;; + XEN_HYPER_GET_IVR + ;; + mov out0=r8 // pass cr.ivr as first arg +#else + mov out0=cr.ivr // pass cr.ivr as first arg +#endif + add out1=16,sp // pass point... [truncated message content] |
From: <yam...@va...> - 2008-02-21 22:31:49
|
Signed-off-by: Isaku Yamahata <yam...@va...> --- include/asm-ia64/xen/interface.h | 686 ++++++++++++++++++++++++++++++++++++++ 1 files changed, 686 insertions(+), 0 deletions(-) create mode 100644 include/asm-ia64/xen/interface.h diff --git a/include/asm-ia64/xen/interface.h b/include/asm-ia64/xen/interface.h new file mode 100644 index 0000000..69418f6 --- /dev/null +++ b/include/asm-ia64/xen/interface.h @@ -0,0 +1,686 @@ +/****************************************************************************** + * arch-ia64/hypervisor-if.h + * + * Guest OS interface to IA64 Xen. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __HYPERVISOR_IF_IA64_H__ +#define __HYPERVISOR_IF_IA64_H__ + +/* + * TODO: + * linux's interface header removed XEN prefix + * Now just work around + */ +#define DEFINE_GUEST_HANDLE_STRUCT(name) \ + __DEFINE_XEN_GUEST_HANDLE(name, struct name) +#define DEFINE_GUEST_HANDLE(name) DEFINE_XEN_GUEST_HANDLE(name) +#define GUEST_HANDLE(name) XEN_GUEST_HANDLE(name) + +/* Structural guest handles introduced in 0x00030201. */ +#if __XEN_INTERFACE_VERSION__ >= 0x00030201 +#define ___DEFINE_XEN_GUEST_HANDLE(name, type) \ + typedef struct { type *p; } __guest_handle_ ## name +#else +#define ___DEFINE_XEN_GUEST_HANDLE(name, type) \ + typedef type * __guest_handle_ ## name +#endif + +#define __DEFINE_XEN_GUEST_HANDLE(name, type) \ + ___DEFINE_XEN_GUEST_HANDLE(name, type) +#define DEFINE_XEN_GUEST_HANDLE(name) __DEFINE_XEN_GUEST_HANDLE(name, name) +#define XEN_GUEST_HANDLE(name) __guest_handle_ ## name +#define XEN_GUEST_HANDLE_64(name) XEN_GUEST_HANDLE(name) +#define uint64_aligned_t uint64_t +#define set_xen_guest_handle(hnd, val) do { (hnd).p = val; } while (0) +#ifdef __XEN_TOOLS__ +#define get_xen_guest_handle(val, hnd) do { val = (hnd).p; } while (0) +#endif + +#ifndef __ASSEMBLY__ +/* Guest handles for primitive C types. */ +__DEFINE_XEN_GUEST_HANDLE(uchar, unsigned char); +__DEFINE_XEN_GUEST_HANDLE(uint, unsigned int); +__DEFINE_XEN_GUEST_HANDLE(ulong, unsigned long); +__DEFINE_XEN_GUEST_HANDLE(u64, unsigned long); +DEFINE_XEN_GUEST_HANDLE(char); +DEFINE_XEN_GUEST_HANDLE(int); +DEFINE_XEN_GUEST_HANDLE(long); +DEFINE_XEN_GUEST_HANDLE(void); + +typedef unsigned long xen_pfn_t; +DEFINE_XEN_GUEST_HANDLE(xen_pfn_t); +#define PRI_xen_pfn "lx" +#endif + +/* Arch specific VIRQs definition */ +#define VIRQ_ITC VIRQ_ARCH_0 /* V. Virtual itc timer */ +#define VIRQ_MCA_CMC VIRQ_ARCH_1 /* MCA cmc interrupt */ +#define VIRQ_MCA_CPE VIRQ_ARCH_2 /* MCA cpe interrupt */ + +/* Maximum number of virtual CPUs in multi-processor guests. */ +/* WARNING: before changing this, check that shared_info fits on a page */ +#define MAX_VIRT_CPUS 64 + +#ifndef __ASSEMBLY__ + +typedef unsigned long xen_ulong_t; + +#ifdef __XEN_TOOLS__ +#define XEN_PAGE_SIZE XC_PAGE_SIZE +#else +#define XEN_PAGE_SIZE PAGE_SIZE +#endif + +#define INVALID_MFN (~0UL) + +#define MEM_G (1UL << 30) +#define MEM_M (1UL << 20) +#define MEM_K (1UL << 10) + +/* Guest physical address of IO ports space. */ +#define IO_PORTS_PADDR 0x00000ffffc000000UL +#define IO_PORTS_SIZE 0x0000000004000000UL + +#define MMIO_START (3 * MEM_G) +#define MMIO_SIZE (512 * MEM_M) + +#define VGA_IO_START 0xA0000UL +#define VGA_IO_SIZE 0x20000 + +#define LEGACY_IO_START (MMIO_START + MMIO_SIZE) +#define LEGACY_IO_SIZE (64 * MEM_M) + +#define IO_PAGE_START (LEGACY_IO_START + LEGACY_IO_SIZE) +#define IO_PAGE_SIZE XEN_PAGE_SIZE + +#define STORE_PAGE_START (IO_PAGE_START + IO_PAGE_SIZE) +#define STORE_PAGE_SIZE XEN_PAGE_SIZE + +#define BUFFER_IO_PAGE_START (STORE_PAGE_START + STORE_PAGE_SIZE) +#define BUFFER_IO_PAGE_SIZE XEN_PAGE_SIZE + +#define BUFFER_PIO_PAGE_START (BUFFER_IO_PAGE_START + BUFFER_IO_PAGE_SIZE) +#define BUFFER_PIO_PAGE_SIZE XEN_PAGE_SIZE + +#define IO_SAPIC_START 0xfec00000UL +#define IO_SAPIC_SIZE 0x100000 + +#define PIB_START 0xfee00000UL +#define PIB_SIZE 0x200000 + +#define GFW_START (4 * MEM_G - 16 * MEM_M) +#define GFW_SIZE (16 * MEM_M) + +/* Nvram belongs to GFW memory space */ +#define NVRAM_SIZE (MEM_K * 64) +#define NVRAM_START (GFW_START + 10 * MEM_M) + +#define NVRAM_VALID_SIG 0x4650494e45584948 /* "HIXENIPF" */ +struct nvram_save_addr { + unsigned long addr; + unsigned long signature; +}; + +struct pt_fpreg { + union { + unsigned long bits[2]; + long double __dummy; /* force 16-byte alignment */ + } u; +}; + +union vac { + unsigned long value; + struct { + int a_int:1; + int a_from_int_cr:1; + int a_to_int_cr:1; + int a_from_psr:1; + int a_from_cpuid:1; + int a_cover:1; + int a_bsw:1; + long reserved:57; + }; +}; +typedef union vac vac_t; + +union vdc { + unsigned long value; + struct { + int d_vmsw:1; + int d_extint:1; + int d_ibr_dbr:1; + int d_pmc:1; + int d_to_pmd:1; + int d_itm:1; + long reserved:58; + }; +}; +typedef union vdc vdc_t; + +struct mapped_regs { + union vac vac; + union vdc vdc; + unsigned long virt_env_vaddr; + unsigned long reserved1[29]; + unsigned long vhpi; + unsigned long reserved2[95]; + union { + unsigned long vgr[16]; + unsigned long bank1_regs[16]; /* bank1 regs (r16-r31) when bank0 active */ + }; + union { + unsigned long vbgr[16]; + unsigned long bank0_regs[16]; /* bank0 regs (r16-r31) when bank1 active */ + }; + unsigned long vnat; + unsigned long vbnat; + unsigned long vcpuid[5]; + unsigned long reserved3[11]; + unsigned long vpsr; + unsigned long vpr; + unsigned long reserved4[76]; + union { + unsigned long vcr[128]; + struct { + unsigned long dcr; /* CR0 */ + unsigned long itm; + unsigned long iva; + unsigned long rsv1[5]; + unsigned long pta; /* CR8 */ + unsigned long rsv2[7]; + unsigned long ipsr; /* CR16 */ + unsigned long isr; + unsigned long rsv3; + unsigned long iip; + unsigned long ifa; + unsigned long itir; + unsigned long iipa; + unsigned long ifs; + unsigned long iim; /* CR24 */ + unsigned long iha; + unsigned long rsv4[38]; + unsigned long lid; /* CR64 */ + unsigned long ivr; + unsigned long tpr; + unsigned long eoi; + unsigned long irr[4]; + unsigned long itv; /* CR72 */ + unsigned long pmv; + unsigned long cmcv; + unsigned long rsv5[5]; + unsigned long lrr0; /* CR80 */ + unsigned long lrr1; + unsigned long rsv6[46]; + }; + }; + union { + unsigned long reserved5[128]; + struct { + unsigned long precover_ifs; + unsigned long unat; /* not sure if this is needed until + NaT arch is done */ + int interrupt_collection_enabled; /* virtual psr.ic */ + /* virtual interrupt deliverable flag is evtchn_upcall_mask in + * shared info area now. interrupt_mask_addr is the address + * of evtchn_upcall_mask for current vcpu + */ + unsigned char *interrupt_mask_addr; + int pending_interruption; + unsigned char vpsr_pp; + unsigned char vpsr_dfh; + unsigned char hpsr_dfh; + unsigned char hpsr_mfh; + unsigned long reserved5_1[4]; + int metaphysical_mode; /* 1 = use metaphys mapping + 0 = use virtual */ + int banknum; /* 0 or 1, which virtual register + bank is active */ + unsigned long rrs[8]; /* region registers */ + unsigned long krs[8]; /* kernel registers */ + unsigned long tmp[16]; /* temp registers + (e.g. for hyperprivops) */ + }; + }; +}; +typedef struct mapped_regs mapped_regs_t; + +struct vpd { + struct mapped_regs vpd_low; + unsigned long reserved6[3456]; + unsigned long vmm_avail[128]; + unsigned long reserved7[4096]; +}; +typedef struct vpd vpd_t; + +struct arch_vcpu_info { +}; +typedef struct arch_vcpu_info arch_vcpu_info_t; + +/* + * This structure is used for magic page in domain pseudo physical address + * space and the result of XENMEM_machine_memory_map. + * As the XENMEM_machine_memory_map result, + * xen_memory_map::nr_entries indicates the size in bytes + * including struct xen_ia64_memmap_info. Not the number of entries. + */ +struct xen_ia64_memmap_info { + uint64_t efi_memmap_size; /* size of EFI memory map */ + uint64_t efi_memdesc_size; /* size of an EFI memory map descriptor */ + uint32_t efi_memdesc_version; /* memory descriptor version */ + void *memdesc[0]; /* array of efi_memory_desc_t */ +}; +typedef struct xen_ia64_memmap_info xen_ia64_memmap_info_t; + +struct arch_shared_info { + /* PFN of the start_info page. */ + unsigned long start_info_pfn; + + /* Interrupt vector for event channel. */ + int evtchn_vector; + + /* PFN of memmap_info page */ + unsigned int memmap_info_num_pages; /* currently only = 1 case is + supported. */ + unsigned long memmap_info_pfn; + + uint64_t pad[31]; +}; +typedef struct arch_shared_info arch_shared_info_t; + +typedef unsigned long xen_callback_t; + +struct ia64_tr_entry { + unsigned long pte; + unsigned long itir; + unsigned long vadr; + unsigned long rid; +}; +typedef struct ia64_tr_entry ia64_tr_entry_t; +DEFINE_XEN_GUEST_HANDLE(ia64_tr_entry_t); + +struct vcpu_tr_regs { + struct ia64_tr_entry itrs[12]; + struct ia64_tr_entry dtrs[12]; +}; + +union vcpu_ar_regs { + unsigned long ar[128]; + struct { + unsigned long kr[8]; + unsigned long rsv1[8]; + unsigned long rsc; + unsigned long bsp; + unsigned long bspstore; + unsigned long rnat; + unsigned long rsv2; + unsigned long fcr; + unsigned long rsv3[2]; + unsigned long eflag; + unsigned long csd; + unsigned long ssd; + unsigned long cflg; + unsigned long fsr; + unsigned long fir; + unsigned long fdr; + unsigned long rsv4; + unsigned long ccv; /* 32 */ + unsigned long rsv5[3]; + unsigned long unat; + unsigned long rsv6[3]; + unsigned long fpsr; + unsigned long rsv7[3]; + unsigned long itc; + unsigned long rsv8[3]; + unsigned long ign1[16]; + unsigned long pfs; /* 64 */ + unsigned long lc; + unsigned long ec; + unsigned long rsv9[45]; + unsigned long ign2[16]; + }; +}; + +union vcpu_cr_regs { + unsigned long cr[128]; + struct { + unsigned long dcr; /* CR0 */ + unsigned long itm; + unsigned long iva; + unsigned long rsv1[5]; + unsigned long pta; /* CR8 */ + unsigned long rsv2[7]; + unsigned long ipsr; /* CR16 */ + unsigned long isr; + unsigned long rsv3; + unsigned long iip; + unsigned long ifa; + unsigned long itir; + unsigned long iipa; + unsigned long ifs; + unsigned long iim; /* CR24 */ + unsigned long iha; + unsigned long rsv4[38]; + unsigned long lid; /* CR64 */ + unsigned long ivr; + unsigned long tpr; + unsigned long eoi; + unsigned long irr[4]; + unsigned long itv; /* CR72 */ + unsigned long pmv; + unsigned long cmcv; + unsigned long rsv5[5]; + unsigned long lrr0; /* CR80 */ + unsigned long lrr1; + unsigned long rsv6[46]; + }; +}; + +struct vcpu_guest_context_regs { + unsigned long r[32]; + unsigned long b[8]; + unsigned long bank[16]; + unsigned long ip; + unsigned long psr; + unsigned long cfm; + unsigned long pr; + unsigned int nats; /* NaT bits for r1-r31. */ + unsigned int bnats; /* Nat bits for banked registers. */ + union vcpu_ar_regs ar; + union vcpu_cr_regs cr; + struct pt_fpreg f[128]; + unsigned long dbr[8]; + unsigned long ibr[8]; + unsigned long rr[8]; + unsigned long pkr[16]; + + /* FIXME: cpuid,pmd,pmc */ + + unsigned long xip; + unsigned long xpsr; + unsigned long xfs; + unsigned long xr[4]; + + struct vcpu_tr_regs tr; + + /* Physical registers in case of debug event. */ + unsigned long excp_iipa; + unsigned long excp_ifa; + unsigned long excp_isr; + unsigned int excp_vector; + + /* + * The rbs is intended to be the image of the stacked registers still + * in the cpu (not yet stored in memory). It is laid out as if it + * were written in memory at a 512 (64*8) aligned address + offset. + * rbs_voff is (offset / 8). rbs_nat contains NaT bits for the + * remaining rbs registers. rbs_rnat contains NaT bits for in memory + * rbs registers. + * Note: loadrs is 2**14 bytes == 2**11 slots. + */ + unsigned int rbs_voff; + unsigned long rbs[2048]; + unsigned long rbs_rnat; + + /* + * RSE.N_STACKED_PHYS via PAL_RSE_INFO + * Strictly this isn't cpu context, but this value is necessary + * for domain save/restore. So is here. + */ + unsigned long num_phys_stacked; +}; + +struct vcpu_guest_context { +#define VGCF_EXTRA_REGS (1UL << 1) /* Set extra regs. */ +#define VGCF_SET_CR_IRR (1UL << 2) /* Set cr_irr[0:3]. */ + unsigned long flags; /* VGCF_* flags */ + + struct vcpu_guest_context_regs regs; + + unsigned long event_callback_ip; + + /* xen doesn't share privregs pages with hvm domain so that this member + * doesn't make sense for hvm domain. + * ~0UL is already used for INVALID_P2M_ENTRY. */ +#define VGC_PRIVREGS_HVM (~(-2UL)) + unsigned long privregs_pfn; +}; +typedef struct vcpu_guest_context vcpu_guest_context_t; +DEFINE_XEN_GUEST_HANDLE(vcpu_guest_context_t); + +/* dom0 vp op */ +#define __HYPERVISOR_ia64_dom0vp_op __HYPERVISOR_arch_0 +/* Map io space in machine address to dom0 physical address space. + Currently physical assigned address equals to machine address. */ +#define IA64_DOM0VP_ioremap 0 + +/* Convert a pseudo physical page frame number to the corresponding + machine page frame number. If no page is assigned, INVALID_MFN or + GPFN_INV_MASK is returned depending on domain's non-vti/vti mode. */ +#define IA64_DOM0VP_phystomach 1 + +/* Convert a machine page frame number to the corresponding pseudo physical + page frame number of the caller domain. */ +#define IA64_DOM0VP_machtophys 3 + +/* Reserved for future use. */ +#define IA64_DOM0VP_iounmap 4 + +/* Unmap and free pages contained in the specified pseudo physical region. */ +#define IA64_DOM0VP_zap_physmap 5 + +/* Assign machine page frame to dom0's pseudo physical address space. */ +#define IA64_DOM0VP_add_physmap 6 + +/* expose the p2m table into domain */ +#define IA64_DOM0VP_expose_p2m 7 + +/* xen perfmon */ +#define IA64_DOM0VP_perfmon 8 + +/* gmfn version of IA64_DOM0VP_add_physmap */ +#define IA64_DOM0VP_add_physmap_with_gmfn 9 + +/* get fpswa revision */ +#define IA64_DOM0VP_fpswa_revision 10 + +/* Add an I/O port space range */ +#define IA64_DOM0VP_add_io_space 11 + +/* expose the foreign domain's p2m table into privileged domain */ +#define IA64_DOM0VP_expose_foreign_p2m 12 +#define IA64_DOM0VP_EFP_ALLOC_PTE 0x1 /* allocate p2m table */ + +/* unexpose the foreign domain's p2m table into privileged domain */ +#define IA64_DOM0VP_unexpose_foreign_p2m 13 + +/* replace this page with newly allocated one and track tlb insert on it. */ +#define IA64_DOM0VP_tlb_track_page 32 + +/* assign a page with newly allocated one and track tlb insert on it. + if page is already assigned to pseudo physical address it results + in error. */ +#define IA64_DOM0VP_tlb_add_track_page 33 + +/* disable tlb traking of this page */ +#define IA64_DOM0VP_tlb_untrack_page 34 + + +/* flags for page assignement to pseudo physical address space */ +#define _ASSIGN_readonly 0 +#define ASSIGN_readonly (1UL << _ASSIGN_readonly) +#define ASSIGN_writable (0UL << _ASSIGN_readonly) /* dummy flag */ +/* Internal only: memory attribute must be WC/UC/UCE. */ +#define _ASSIGN_nocache 1 +#define ASSIGN_nocache (1UL << _ASSIGN_nocache) +/* tlb tracking */ +#define _ASSIGN_tlb_track 2 +#define ASSIGN_tlb_track (1UL << _ASSIGN_tlb_track) +/* Internal only: associated with PGC_allocated bit */ +#define _ASSIGN_pgc_allocated 3 +#define ASSIGN_pgc_allocated (1UL << _ASSIGN_pgc_allocated) + +/* This structure has the same layout of struct ia64_boot_param, defined in + <asm/system.h>. It is redefined here to ease use. */ +struct xen_ia64_boot_param { + unsigned long command_line; /* physical address of cmd line args */ + unsigned long efi_systab; /* physical address of EFI system table */ + unsigned long efi_memmap; /* physical address of EFI memory map */ + unsigned long efi_memmap_size; /* size of EFI memory map */ + unsigned long efi_memdesc_size; /* size of an EFI memory map descriptor */ + unsigned int efi_memdesc_version; /* memory descriptor version */ + struct { + unsigned short num_cols; /* number of columns on console. */ + unsigned short num_rows; /* number of rows on console. */ + unsigned short orig_x; /* cursor's x position */ + unsigned short orig_y; /* cursor's y position */ + } console_info; + unsigned long fpswa; /* physical address of the fpswa interface */ + unsigned long initrd_start; + unsigned long initrd_size; + unsigned long domain_start; /* va where the boot time domain begins */ + unsigned long domain_size; /* how big is the boot domain */ +}; + +#endif /* !__ASSEMBLY__ */ + +/* Size of the shared_info area (this is not related to page size). */ +#define XSI_SHIFT 14 +#define XSI_SIZE (1 << XSI_SHIFT) +/* Log size of mapped_regs area (64 KB - only 4KB is used). */ +#define XMAPPEDREGS_SHIFT 12 +#define XMAPPEDREGS_SIZE (1 << XMAPPEDREGS_SHIFT) +/* Offset of XASI (Xen arch shared info) wrt XSI_BASE. */ +#define XMAPPEDREGS_OFS XSI_SIZE + +/* Hyperprivops. */ +#define HYPERPRIVOP_START 0x1 +#define HYPERPRIVOP_RFI (HYPERPRIVOP_START + 0x0) +#define HYPERPRIVOP_RSM_DT (HYPERPRIVOP_START + 0x1) +#define HYPERPRIVOP_SSM_DT (HYPERPRIVOP_START + 0x2) +#define HYPERPRIVOP_COVER (HYPERPRIVOP_START + 0x3) +#define HYPERPRIVOP_ITC_D (HYPERPRIVOP_START + 0x4) +#define HYPERPRIVOP_ITC_I (HYPERPRIVOP_START + 0x5) +#define HYPERPRIVOP_SSM_I (HYPERPRIVOP_START + 0x6) +#define HYPERPRIVOP_GET_IVR (HYPERPRIVOP_START + 0x7) +#define HYPERPRIVOP_GET_TPR (HYPERPRIVOP_START + 0x8) +#define HYPERPRIVOP_SET_TPR (HYPERPRIVOP_START + 0x9) +#define HYPERPRIVOP_EOI (HYPERPRIVOP_START + 0xa) +#define HYPERPRIVOP_SET_ITM (HYPERPRIVOP_START + 0xb) +#define HYPERPRIVOP_THASH (HYPERPRIVOP_START + 0xc) +#define HYPERPRIVOP_PTC_GA (HYPERPRIVOP_START + 0xd) +#define HYPERPRIVOP_ITR_D (HYPERPRIVOP_START + 0xe) +#define HYPERPRIVOP_GET_RR (HYPERPRIVOP_START + 0xf) +#define HYPERPRIVOP_SET_RR (HYPERPRIVOP_START + 0x10) +#define HYPERPRIVOP_SET_KR (HYPERPRIVOP_START + 0x11) +#define HYPERPRIVOP_FC (HYPERPRIVOP_START + 0x12) +#define HYPERPRIVOP_GET_CPUID (HYPERPRIVOP_START + 0x13) +#define HYPERPRIVOP_GET_PMD (HYPERPRIVOP_START + 0x14) +#define HYPERPRIVOP_GET_EFLAG (HYPERPRIVOP_START + 0x15) +#define HYPERPRIVOP_SET_EFLAG (HYPERPRIVOP_START + 0x16) +#define HYPERPRIVOP_RSM_BE (HYPERPRIVOP_START + 0x17) +#define HYPERPRIVOP_GET_PSR (HYPERPRIVOP_START + 0x18) +#define HYPERPRIVOP_SET_RR0_TO_RR4 (HYPERPRIVOP_START + 0x19) +#define HYPERPRIVOP_MAX (0x1a) + +/* Fast and light hypercalls. */ +#define __HYPERVISOR_ia64_fast_eoi __HYPERVISOR_arch_1 + +/* Extra debug features. */ +#define __HYPERVISOR_ia64_debug_op __HYPERVISOR_arch_2 + +/* Xencomm macros. */ +#define XENCOMM_INLINE_MASK 0xf800000000000000UL +#define XENCOMM_INLINE_FLAG 0x8000000000000000UL + +#ifndef __ASSEMBLY__ + +/* + * Optimization features. + * The hypervisor may do some special optimizations for guests. This hypercall + * can be used to switch on/of these special optimizations. + */ +#define __HYPERVISOR_opt_feature 0x700UL + +#define XEN_IA64_OPTF_OFF 0x0 +#define XEN_IA64_OPTF_ON 0x1 + +/* + * If this feature is switched on, the hypervisor inserts the + * tlb entries without calling the guests traphandler. + * This is useful in guests using region 7 for identity mapping + * like the linux kernel does. + */ +#define XEN_IA64_OPTF_IDENT_MAP_REG7 1 + +/* Identity mapping of region 4 addresses in HVM. */ +#define XEN_IA64_OPTF_IDENT_MAP_REG4 2 + +/* Identity mapping of region 5 addresses in HVM. */ +#define XEN_IA64_OPTF_IDENT_MAP_REG5 3 + +#define XEN_IA64_OPTF_IDENT_MAP_NOT_SET (0) + +struct xen_ia64_opt_feature { + unsigned long cmd; /* Which feature */ + unsigned char on; /* Switch feature on/off */ + union { + struct { + /* The page protection bit mask of the pte. + * This will be or'ed with the pte. */ + unsigned long pgprot; + unsigned long key; /* A protection key for itir. */ + }; + }; +}; + +#endif /* __ASSEMBLY__ */ + +/* xen perfmon */ +#ifdef XEN +#ifndef __ASSEMBLY__ +#ifndef _ASM_IA64_PERFMON_H + +#include <xen/list.h> /* asm/perfmon.h requires struct list_head */ +#include <asm/perfmon.h> +/* for PFM_xxx and pfarg_features_t, pfarg_context_t, pfarg_reg_t, pfarg_load_t */ + +#endif /* _ASM_IA64_PERFMON_H */ + +DEFINE_XEN_GUEST_HANDLE(pfarg_features_t); +DEFINE_XEN_GUEST_HANDLE(pfarg_context_t); +DEFINE_XEN_GUEST_HANDLE(pfarg_reg_t); +DEFINE_XEN_GUEST_HANDLE(pfarg_load_t); +#endif /* __ASSEMBLY__ */ +#endif /* XEN */ + +#endif /* __HYPERVISOR_IF_IA64_H__ */ + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ -- 1.5.3 -- yamahata |
From: <yam...@va...> - 2008-02-21 22:31:49
|
Signed-off-by: Isaku Yamahata <yam...@va...> --- arch/ia64/kernel/acpi.c | 6 ++++++ arch/ia64/xen/machvec.c | 4 ++++ include/asm-ia64/machvec.h | 2 ++ include/asm-ia64/machvec_xen.h | 22 ++++++++++++++++++++++ 4 files changed, 34 insertions(+), 0 deletions(-) create mode 100644 arch/ia64/xen/machvec.c create mode 100644 include/asm-ia64/machvec_xen.h diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index 78f28d8..9c17a46 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c @@ -118,6 +118,10 @@ acpi_get_sysname(void) return "hpzx1"; } else if (!strcmp(hdr->oem_id, "SGI")) { return "sn2"; +#ifdef CONFIG_XEN + } else if (is_running_on_xen() && !strcmp(hdr->oem_id, "XEN")) { + return "xen"; +#endif } return "dig"; @@ -132,6 +136,8 @@ acpi_get_sysname(void) return "sn2"; # elif defined (CONFIG_IA64_DIG) return "dig"; +# elif defined (CONFIG_IA64_XEN) + return "xen"; # else # error Unknown platform. Fix acpi.c. # endif diff --git a/arch/ia64/xen/machvec.c b/arch/ia64/xen/machvec.c new file mode 100644 index 0000000..4ad588a --- /dev/null +++ b/arch/ia64/xen/machvec.c @@ -0,0 +1,4 @@ +#define MACHVEC_PLATFORM_NAME xen +#define MACHVEC_PLATFORM_HEADER <asm/machvec_xen.h> +#include <asm/machvec_init.h> + diff --git a/include/asm-ia64/machvec.h b/include/asm-ia64/machvec.h index c201a20..cea8d63 100644 --- a/include/asm-ia64/machvec.h +++ b/include/asm-ia64/machvec.h @@ -120,6 +120,8 @@ extern void machvec_tlb_migrate_finish (struct mm_struct *); # include <asm/machvec_hpzx1_swiotlb.h> # elif defined (CONFIG_IA64_SGI_SN2) # include <asm/machvec_sn2.h> +# elif defined (CONFIG_IA64_XEN) +# include <asm/machvec_xen.h> # elif defined (CONFIG_IA64_GENERIC) # ifdef MACHVEC_PLATFORM_HEADER diff --git a/include/asm-ia64/machvec_xen.h b/include/asm-ia64/machvec_xen.h new file mode 100644 index 0000000..ed0f84d --- /dev/null +++ b/include/asm-ia64/machvec_xen.h @@ -0,0 +1,22 @@ +#ifndef _ASM_IA64_MACHVEC_XEN_h +#define _ASM_IA64_MACHVEC_XEN_h + +extern ia64_mv_setup_t xen_setup; +extern ia64_mv_cpu_init_t xen_cpu_init; +extern ia64_mv_irq_init_t xen_irq_init; +extern ia64_mv_send_ipi_t xen_platform_send_ipi; + +/* + * This stuff has dual use! + * + * For a generic kernel, the macros are used to initialize the + * platform's machvec structure. When compiling a non-generic kernel, + * the macros are used directly. + */ +#define platform_name "xen" +#define platform_setup xen_setup +#define platform_cpu_init xen_cpu_init +#define platform_irq_init xen_irq_init +#define platform_send_ipi xen_platform_send_ipi + +#endif /* _ASM_IA64_MACHVEC_XEN_h */ -- 1.5.3 -- yamahata |
From: <yam...@va...> - 2008-02-21 22:31:49
|
Signed-off-by: Isaku Yamahata <yam...@va...> --- arch/ia64/kernel/time.c | 204 +++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 204 insertions(+), 0 deletions(-) diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c index 17fda52..1bb0362 100644 --- a/arch/ia64/kernel/time.c +++ b/arch/ia64/kernel/time.c @@ -29,6 +29,14 @@ #include <asm/sections.h> #include <asm/system.h> +#include <asm/xen/hypervisor.h> +#ifdef CONFIG_XEN +#include <linux/kernel_stat.h> +#include <linux/posix-timers.h> +#include <xen/interface/vcpu.h> +#include <asm/percpu.h> +#endif + #include "fsyscall_gtod_data.h" static cycle_t itc_get_cycles(void); @@ -38,6 +46,17 @@ struct fsyscall_gtod_data_t fsyscall_gtod_data = { }; struct itc_jitter_data_t itc_jitter_data; +#ifdef CONFIG_XEN +static void itc_jitter_data_reset(void) +{ + u64 lcycle, ret; + + do { + lcycle = itc_jitter_data.itc_lastcycle; + ret = cmpxchg(&itc_jitter_data.itc_lastcycle, lcycle, 0); + } while (unlikely(ret != lcycle)); +} +#endif volatile int time_keeper_id = 0; /* smp_processor_id() of time-keeper */ @@ -56,13 +75,105 @@ static struct clocksource clocksource_itc = { .mult = 0, /*to be calculated*/ .shift = 16, .flags = CLOCK_SOURCE_IS_CONTINUOUS, +#ifdef CONFIG_XEN + .resume = itc_jitter_data_reset, +#endif }; static struct clocksource *itc_clocksource; +#ifdef CONFIG_XEN +DEFINE_PER_CPU(struct vcpu_runstate_info, runstate); +DEFINE_PER_CPU(unsigned long, processed_stolen_time); +DEFINE_PER_CPU(unsigned long, processed_blocked_time); +#define NS_PER_TICK (1000000000LL/HZ) +static unsigned long +consider_steal_time(unsigned long new_itm) +{ + unsigned long stolen, blocked, sched_time; + unsigned long delta_itm = 0, stolentick = 0; + int cpu = smp_processor_id(); + struct vcpu_runstate_info *runstate; + struct task_struct *p = current; + + runstate = &per_cpu(runstate, smp_processor_id()); + + do { + sched_time = runstate->state_entry_time; + mb(); + stolen = runstate->time[RUNSTATE_runnable] + + runstate->time[RUNSTATE_offline] - + per_cpu(processed_stolen_time, cpu); + blocked = runstate->time[RUNSTATE_blocked] - + per_cpu(processed_blocked_time, cpu); + mb(); + } while (sched_time != runstate->state_entry_time); + + /* + * Check for vcpu migration effect + * In this case, itc value is reversed. + * This causes huge stolen value. + * This function just checks and reject this effect. + */ + if (!time_after_eq(runstate->time[RUNSTATE_blocked], + per_cpu(processed_blocked_time, cpu))) + blocked = 0; + + if (!time_after_eq(runstate->time[RUNSTATE_runnable] + + runstate->time[RUNSTATE_offline], + per_cpu(processed_stolen_time, cpu))) + stolen = 0; + + if (!time_after(delta_itm + new_itm, ia64_get_itc())) + stolentick = ia64_get_itc() - delta_itm - new_itm; + + do_div(stolentick, NS_PER_TICK); + stolentick++; + + do_div(stolen, NS_PER_TICK); + + if (stolen > stolentick) + stolen = stolentick; + + stolentick -= stolen; + do_div(blocked, NS_PER_TICK); + + if (blocked > stolentick) + blocked = stolentick; + + if (stolen > 0 || blocked > 0) { + account_steal_time(NULL, jiffies_to_cputime(stolen)); + account_steal_time(idle_task(cpu), jiffies_to_cputime(blocked)); + run_local_timers(); + + if (rcu_pending(cpu)) + rcu_check_callbacks(cpu, user_mode(get_irq_regs())); + + scheduler_tick(); + run_posix_cpu_timers(p); + delta_itm += local_cpu_data->itm_delta * (stolen + blocked); + + if (cpu == time_keeper_id) { + write_seqlock(&xtime_lock); + do_timer(stolen + blocked); + local_cpu_data->itm_next = delta_itm + new_itm; + write_sequnlock(&xtime_lock); + } else { + local_cpu_data->itm_next = delta_itm + new_itm; + } + per_cpu(processed_stolen_time, cpu) += NS_PER_TICK * stolen; + per_cpu(processed_blocked_time, cpu) += NS_PER_TICK * blocked; + } + return delta_itm; +} +#else +#define consider_steal_time(new_itm) (0) +#endif + static irqreturn_t timer_interrupt (int irq, void *dev_id) { unsigned long new_itm; + unsigned long delta_itm; /* XEN */ if (unlikely(cpu_is_offline(smp_processor_id()))) { return IRQ_HANDLED; @@ -78,6 +189,13 @@ timer_interrupt (int irq, void *dev_id) profile_tick(CPU_PROFILING); + if (is_running_on_xen()) { + delta_itm = consider_steal_time(new_itm); + new_itm += delta_itm; + if (time_after(new_itm, ia64_get_itc()) && delta_itm) + goto skip_process_time_accounting; + } + while (1) { update_process_times(user_mode(get_irq_regs())); @@ -107,6 +225,8 @@ timer_interrupt (int irq, void *dev_id) local_irq_disable(); } +skip_process_time_accounting: /* XEN */ + do { /* * If we're too close to the next clock tick for @@ -161,6 +281,84 @@ static int __init nojitter_setup(char *str) __setup("nojitter", nojitter_setup); +#ifdef CONFIG_XEN +/* taken from i386/kernel/time-xen.c */ +static void init_missing_ticks_accounting(int cpu) +{ + struct vcpu_register_runstate_memory_area area; + struct vcpu_runstate_info *runstate = &per_cpu(runstate, cpu); + int rc; + + memset(runstate, 0, sizeof(*runstate)); + + area.addr.v = runstate; + rc = HYPERVISOR_vcpu_op(VCPUOP_register_runstate_memory_area, cpu, + &area); + WARN_ON(rc && rc != -ENOSYS); + + per_cpu(processed_blocked_time, cpu) = runstate->time[RUNSTATE_blocked]; + per_cpu(processed_stolen_time, cpu) = runstate->time[RUNSTATE_runnable] + + runstate->time[RUNSTATE_offline]; +} + +static int xen_ia64_settimefoday_after_resume; + +static int __init __xen_ia64_settimeofday_after_resume(char *str) +{ + xen_ia64_settimefoday_after_resume = 1; + return 1; +} + +__setup("xen_ia64_settimefoday_after_resume", + __xen_ia64_settimeofday_after_resume); + +/* Called after suspend, to resume time. */ +void +time_resume(void) +{ + unsigned int cpu; + + /* Just trigger a tick. */ + ia64_cpu_local_tick(); + + if (xen_ia64_settimefoday_after_resume) { + /* do_settimeofday() resets timer interplator */ + struct timespec xen_time; + int ret; + efi_gettimeofday(&xen_time); + + ret = do_settimeofday(&xen_time); + WARN_ON(ret); + } else { +#if 0 + /* adjust EFI time */ + struct timespec my_time = CURRENT_TIME; + struct timespec xen_time; + static timespec diff; + struct xen_domctl domctl; + int ret; + + efi_gettimeofday(&xen_time); + diff = timespec_sub(&xen_time, &my_time); + domctl.cmd = XEN_DOMCTL_settimeoffset; + domctl.domain = DOMID_SELF; + domctl.u.settimeoffset.timeoffset_seconds = diff.tv_sec; + ret = HYPERVISOR_domctl_op(&domctl); + WARN_ON(ret); +#endif + /* itc_clocksource remembers the last timer status in + * itc_jitter_data. Forget it */ + clocksource_resume(); + } + + for_each_online_cpu(cpu) + init_missing_ticks_accounting(cpu); + + touch_softlockup_watchdog(); +} +#else +#define init_missing_ticks_accounting(cpu) do {} while (0) +#endif void __devinit ia64_init_itm (void) @@ -256,6 +454,12 @@ ia64_init_itm (void) */ clocksource_itc.rating = 50; + if (is_running_on_xen()) + init_missing_ticks_accounting(smp_processor_id()); + + /* avoid softlock up message when cpu is unplug and plugged again. */ + touch_softlockup_watchdog(); + /* Setup the CPU local timer tick */ ia64_cpu_local_tick(); -- 1.5.3 -- yamahata |
From: <yam...@va...> - 2008-02-21 22:31:48
|
Currently it detects by checking psr.cpl != 0. It's ok for now, but more abstraction would be needed later like x86. Presumably extending booting protocol (i.e. extending struct ia64_boot_param) or multi entry points depending on hypervisor would be necessary. Signed-off-by: Isaku Yamahata <yam...@va...> --- arch/ia64/kernel/head.S | 6 ++++ arch/ia64/xen/xensetup.S | 40 +++++++++++++++++++++++++++ include/asm-ia64/xen/hypervisor.h | 55 +++++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+), 0 deletions(-) create mode 100644 arch/ia64/xen/xensetup.S create mode 100644 include/asm-ia64/xen/hypervisor.h diff --git a/arch/ia64/kernel/head.S b/arch/ia64/kernel/head.S index d3a41d5..2f8d770 100644 --- a/arch/ia64/kernel/head.S +++ b/arch/ia64/kernel/head.S @@ -367,6 +367,12 @@ start_ap: ;; (isBP) st8 [r2]=r28 // save the address of the boot param area passed by the bootloader +#ifdef CONFIG_XEN + // Note: isBP is used by the subprogram. + br.call.sptk.many rp=early_xen_setup + ;; +#endif + #ifdef CONFIG_SMP (isAP) br.call.sptk.many rp=start_secondary .ret0: diff --git a/arch/ia64/xen/xensetup.S b/arch/ia64/xen/xensetup.S new file mode 100644 index 0000000..17ad297 --- /dev/null +++ b/arch/ia64/xen/xensetup.S @@ -0,0 +1,40 @@ +/* + * Support routines for Xen + * + * Copyright (C) 2005 Dan Magenheimer <dan...@hp...> + */ + +#include <asm/processor.h> +#include <asm/asmmacro.h> + + .section .data.read_mostly + .align 8 + .global running_on_xen +running_on_xen: + data4 0 + .previous + +#define isBP p3 // are we the Bootstrap Processor? + + .text +GLOBAL_ENTRY(early_xen_setup) + mov r8=ar.rsc // Initialized in head.S +(isBP) movl r9=running_on_xen;; + extr.u r8=r8,2,2;; // Extract pl fields + cmp.eq p7,p0=r8,r0 // p7: !running on xen + mov r8=1 // booleanize. +(p7) br.ret.sptk.many rp;; +(isBP) st4 [r9]=r8 + movl r10=xen_ivt;; + + mov cr.iva=r10 + + /* Set xsi base. */ +#define FW_HYPERCALL_SET_SHARED_INFO_VA 0x600 +(isBP) mov r2=FW_HYPERCALL_SET_SHARED_INFO_VA +(isBP) movl r28=XSI_BASE;; +(isBP) break 0x1000;; + + br.ret.sptk.many rp + ;; +END(early_xen_setup) diff --git a/include/asm-ia64/xen/hypervisor.h b/include/asm-ia64/xen/hypervisor.h new file mode 100644 index 0000000..4ee50c9 --- /dev/null +++ b/include/asm-ia64/xen/hypervisor.h @@ -0,0 +1,55 @@ +/****************************************************************************** + * hypervisor.h + * + * Linux-specific hypervisor handling. + * + * Copyright (c) 2002-2004, K A Fraser + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation; or, when distributed + * separately from the Linux kernel or incorporated into other + * software packages, subject to the following license: + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this source file (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, modify, + * merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef __HYPERVISOR_H__ +#define __HYPERVISOR_H__ + +#ifdef CONFIG_XEN +/* running_on_xen is set before executing any C code by early_xen_setup */ +extern const int running_on_xen; +#define is_running_on_xen() (running_on_xen) +#else /* CONFIG_XEN */ +# ifdef CONFIG_VMX_GUEST +# define is_running_on_xen() (1) +# else /* CONFIG_VMX_GUEST */ +# define is_running_on_xen() (0) +# endif /* CONFIG_VMX_GUEST */ +#endif /* CONFIG_XEN */ + +#ifdef CONFIG_XEN_PRIVILEGED_GUEST +#define is_initial_xendomain() \ + (is_running_on_xen() ? xen_start_info->flags & SIF_INITDOMAIN : 0) +#else +#define is_initial_xendomain() 0 +#endif + +#endif /* __HYPERVISOR_H__ */ -- 1.5.3 -- yamahata |
From: <yam...@va...> - 2008-02-21 22:31:48
|
Signed-off-by: Isaku Yamahata <yam...@va...> --- arch/ia64/kernel/asm-offsets.c | 25 ++++++++++++++ include/asm-ia64/xen/privop.h | 73 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+), 0 deletions(-) create mode 100644 include/asm-ia64/xen/privop.h diff --git a/arch/ia64/kernel/asm-offsets.c b/arch/ia64/kernel/asm-offsets.c index 0aebc6f..b432638 100644 --- a/arch/ia64/kernel/asm-offsets.c +++ b/arch/ia64/kernel/asm-offsets.c @@ -278,4 +278,29 @@ void foo(void) offsetof (struct itc_jitter_data_t, itc_jitter)); DEFINE(IA64_ITC_LASTCYCLE_OFFSET, offsetof (struct itc_jitter_data_t, itc_lastcycle)); + +#ifdef CONFIG_XEN + BLANK(); + +#define DEFINE_MAPPED_REG_OFS(sym, field) \ + DEFINE(sym, (XMAPPEDREGS_OFS + offsetof(mapped_regs_t, field))) + + DEFINE_MAPPED_REG_OFS(XSI_PSR_I_ADDR_OFS, interrupt_mask_addr); + DEFINE_MAPPED_REG_OFS(XSI_IPSR_OFS, ipsr); + DEFINE_MAPPED_REG_OFS(XSI_IIP_OFS, iip); + DEFINE_MAPPED_REG_OFS(XSI_IFS_OFS, ifs); + DEFINE_MAPPED_REG_OFS(XSI_PRECOVER_IFS_OFS, precover_ifs); + DEFINE_MAPPED_REG_OFS(XSI_ISR_OFS, isr); + DEFINE_MAPPED_REG_OFS(XSI_IFA_OFS, ifa); + DEFINE_MAPPED_REG_OFS(XSI_IIPA_OFS, iipa); + DEFINE_MAPPED_REG_OFS(XSI_IIM_OFS, iim); + DEFINE_MAPPED_REG_OFS(XSI_IHA_OFS, iha); + DEFINE_MAPPED_REG_OFS(XSI_ITIR_OFS, itir); + DEFINE_MAPPED_REG_OFS(XSI_PSR_IC_OFS, interrupt_collection_enabled); + DEFINE_MAPPED_REG_OFS(XSI_BANKNUM_OFS, banknum); + DEFINE_MAPPED_REG_OFS(XSI_BANK0_R16_OFS, bank0_regs[0]); + DEFINE_MAPPED_REG_OFS(XSI_BANK1_R16_OFS, bank1_regs[0]); + DEFINE_MAPPED_REG_OFS(XSI_B0NATS_OFS, vbnat); + DEFINE_MAPPED_REG_OFS(XSI_B1NATS_OFS, vnat); +#endif /* CONFIG_XEN */ } diff --git a/include/asm-ia64/xen/privop.h b/include/asm-ia64/xen/privop.h new file mode 100644 index 0000000..dd3e5ec --- /dev/null +++ b/include/asm-ia64/xen/privop.h @@ -0,0 +1,73 @@ +#ifndef _ASM_IA64_XEN_PRIVOP_H +#define _ASM_IA64_XEN_PRIVOP_H + +/* + * Copyright (C) 2005 Hewlett-Packard Co + * Dan Magenheimer <dan...@hp...> + * + * Paravirtualizations of privileged operations for Xen/ia64 + * + * + * inline privop and paravirt_alt support + * Copyright (c) 2007 Isaku Yamahata <yamahata at valinux co jp> + * VA Linux Systems Japan K.K. + * + */ + +#ifndef __ASSEMBLY__ +#include <linux/types.h> /* arch-ia64.h requires uint64_t */ +#include <linux/stringify.h> +#endif +#include <asm/xen/interface.h> + +/* At 1 MB, before per-cpu space but still addressable using addl instead + of movl. */ +#define XSI_BASE 0xfffffffffff00000 + +/* Address of mapped regs. */ +#define XMAPPEDREGS_BASE (XSI_BASE + XSI_SIZE) + +#ifdef __ASSEMBLY__ +#define XEN_HYPER_RFI break HYPERPRIVOP_RFI +#define XEN_HYPER_RSM_PSR_DT break HYPERPRIVOP_RSM_DT +#define XEN_HYPER_SSM_PSR_DT break HYPERPRIVOP_SSM_DT +#define XEN_HYPER_COVER break HYPERPRIVOP_COVER +#define XEN_HYPER_ITC_D break HYPERPRIVOP_ITC_D +#define XEN_HYPER_ITC_I break HYPERPRIVOP_ITC_I +#define XEN_HYPER_SSM_I break HYPERPRIVOP_SSM_I +#define XEN_HYPER_GET_IVR break HYPERPRIVOP_GET_IVR +#define XEN_HYPER_GET_TPR break HYPERPRIVOP_GET_TPR +#define XEN_HYPER_SET_TPR break HYPERPRIVOP_SET_TPR +#define XEN_HYPER_EOI break HYPERPRIVOP_EOI +#define XEN_HYPER_SET_ITM break HYPERPRIVOP_SET_ITM +#define XEN_HYPER_THASH break HYPERPRIVOP_THASH +#define XEN_HYPER_PTC_GA break HYPERPRIVOP_PTC_GA +#define XEN_HYPER_ITR_D break HYPERPRIVOP_ITR_D +#define XEN_HYPER_GET_RR break HYPERPRIVOP_GET_RR +#define XEN_HYPER_SET_RR break HYPERPRIVOP_SET_RR +#define XEN_HYPER_SET_KR break HYPERPRIVOP_SET_KR +#define XEN_HYPER_FC break HYPERPRIVOP_FC +#define XEN_HYPER_GET_CPUID break HYPERPRIVOP_GET_CPUID +#define XEN_HYPER_GET_PMD break HYPERPRIVOP_GET_PMD +#define XEN_HYPER_GET_EFLAG break HYPERPRIVOP_GET_EFLAG +#define XEN_HYPER_SET_EFLAG break HYPERPRIVOP_SET_EFLAG +#define XEN_HYPER_GET_PSR break HYPERPRIVOP_GET_PSR +#define XEN_HYPER_SET_RR0_TO_RR4 break HYPERPRIVOP_SET_RR0_TO_RR4 + +#define XSI_IFS (XSI_BASE + XSI_IFS_OFS) +#define XSI_PRECOVER_IFS (XSI_BASE + XSI_PRECOVER_IFS_OFS) +#define XSI_IFA (XSI_BASE + XSI_IFA_OFS) +#define XSI_ISR (XSI_BASE + XSI_ISR_OFS) +#define XSI_IIM (XSI_BASE + XSI_IIM_OFS) +#define XSI_ITIR (XSI_BASE + XSI_ITIR_OFS) +#define XSI_PSR_I_ADDR (XSI_BASE + XSI_PSR_I_ADDR_OFS) +#define XSI_PSR_IC (XSI_BASE + XSI_PSR_IC_OFS) +#define XSI_IPSR (XSI_BASE + XSI_IPSR_OFS) +#define XSI_IIP (XSI_BASE + XSI_IIP_OFS) +#define XSI_B1NAT (XSI_BASE + XSI_B1NATS_OFS) +#define XSI_BANK1_R16 (XSI_BASE + XSI_BANK1_R16_OFS) +#define XSI_BANKNUM (XSI_BASE + XSI_BANKNUM_OFS) +#define XSI_IHA (XSI_BASE + XSI_IHA_OFS) +#endif + +#endif /* _ASM_IA64_XEN_PRIVOP_H */ -- 1.5.3 -- yamahata |
From: <yam...@va...> - 2008-02-21 22:31:44
|
Xenlinux/ia64 needs to reserve one more region passed from xen hypervisor as start info. Signed-off-by: Isaku Yamahata <yam...@va...> --- include/asm-ia64/meminit.h | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-) diff --git a/include/asm-ia64/meminit.h b/include/asm-ia64/meminit.h index f93308f..7c12c08 100644 --- a/include/asm-ia64/meminit.h +++ b/include/asm-ia64/meminit.h @@ -18,10 +18,17 @@ * - crash dumping code reserved region * - Kernel memory map built from EFI memory map * - ELF core header + * ifdef CONFIG_XEN + * - xen start info + * endif * * More could be added if necessary */ +#ifdef CONFIG_XEN #define IA64_MAX_RSVD_REGIONS 8 +#else +#define IA64_MAX_RSVD_REGIONS 9 +#endif struct rsvd_region { unsigned long start; /* virtual address of beginning of element */ -- 1.5.3 -- yamahata |
From: <yam...@va...> - 2008-02-21 22:31:42
|
Hi linux/ia64 developers. Few days before Eddie posted the mail for Linux/IA64 paravirtualization. But only a few responded partially because there was no reviewable patches. Here is the patches for xen/ia64 Linux paravirtualization. The goal is to merge IA64 xen Linux paravirtualization for both domU and dom0 eventually. However the first step is to merge domU portion. As you can see from the current patchset, abstraction and many clean up must be done before merge. Before starting cleaning up, we want to discuss with linux ia64 developers. Please comment. Especially the first blocker is the paravirtualization of the hand written assembly code as Eddie already tried to discuss. The corresponding patch is "ia64/xen: xen hand written assembly code paravirtualization." NOTE: This patchset depends on another patchset which I sent out as "Xen arch portability patches." thansk, Diffstat: arch/ia64/Kconfig | 76 + arch/ia64/Makefile | 12 +- arch/ia64/configs/xen_domu_wip_defconfig | 854 ++++++++++++ arch/ia64/kernel/Makefile | 63 + arch/ia64/kernel/acpi.c | 6 + arch/ia64/kernel/asm-offsets.c | 25 + arch/ia64/kernel/entry.S | 41 +- arch/ia64/kernel/fsys.S | 41 + arch/ia64/kernel/gate.S | 55 + arch/ia64/kernel/gate.lds.S | 18 + arch/ia64/kernel/head.S | 6 + arch/ia64/kernel/iosapic.c | 89 ++- arch/ia64/kernel/irq_ia64.c | 363 +++++- arch/ia64/kernel/mca.c | 22 + arch/ia64/kernel/module.c | 32 + arch/ia64/kernel/pal.S | 5 +- arch/ia64/kernel/paravirt_alt.c | 118 ++ arch/ia64/kernel/paravirt_core.c | 201 +++ arch/ia64/kernel/paravirt_entry.c | 99 ++ arch/ia64/kernel/paravirt_nop.c | 49 + arch/ia64/kernel/paravirtentry.S | 37 + arch/ia64/kernel/patch.c | 28 + arch/ia64/kernel/salinfo.c | 44 + arch/ia64/kernel/setup.c | 121 ++ arch/ia64/kernel/smpboot.c | 4 + arch/ia64/kernel/time.c | 204 +++ arch/ia64/kernel/vmlinux.lds.S | 41 + arch/ia64/kernel/xengate-data.S | 3 + arch/ia64/mm/init.c | 22 +- arch/ia64/xen/Kconfig | 29 + arch/ia64/xen/Makefile | 11 + arch/ia64/xen/hypercall.S | 141 ++ arch/ia64/xen/hypervisor.c | 228 +++ arch/ia64/xen/machvec.c | 4 + arch/ia64/xen/paravirt_xen.c | 242 ++++ arch/ia64/xen/privops_asm.S | 221 +++ arch/ia64/xen/privops_c.c | 279 ++++ arch/ia64/xen/util.c | 101 ++ arch/ia64/xen/xcom_asm.S | 27 + arch/ia64/xen/xcom_hcall.c | 458 +++++++ arch/ia64/xen/xencomm.c | 108 ++ arch/ia64/xen/xenentry.S | 798 +++++++++++ arch/ia64/xen/xenivt.S | 2204 ++++++++++++++++++++++++++++++ arch/ia64/xen/xenminstate.h | 320 +++++ arch/ia64/xen/xenpal.S | 76 + arch/ia64/xen/xensetup.S | 50 + include/asm-ia64/gcc_intrin.h | 58 +- include/asm-ia64/hw_irq.h | 10 + include/asm-ia64/intel_intrin.h | 64 +- include/asm-ia64/intrinsics.h | 12 + include/asm-ia64/iosapic.h | 2 + include/asm-ia64/irq.h | 33 + include/asm-ia64/machvec.h | 2 + include/asm-ia64/machvec_xen.h | 22 + include/asm-ia64/meminit.h | 7 + include/asm-ia64/mmu_context.h | 6 +- include/asm-ia64/module.h | 6 + include/asm-ia64/page.h | 11 + include/asm-ia64/paravirt_alt.h | 82 ++ include/asm-ia64/paravirt_core.h | 54 + include/asm-ia64/paravirt_entry.h | 62 + include/asm-ia64/paravirt_nop.h | 46 + include/asm-ia64/privop.h | 67 + include/asm-ia64/privop_paravirt.h | 587 ++++++++ include/asm-ia64/sal.h | 36 + include/asm-ia64/sync_bitops.h | 61 + include/asm-ia64/system.h | 4 +- include/asm-ia64/xen/hypercall.h | 426 ++++++ include/asm-ia64/xen/hypervisor.h | 249 ++++ include/asm-ia64/xen/interface.h | 686 ++++++++++ include/asm-ia64/xen/page.h | 19 + include/asm-ia64/xen/privop.h | 609 +++++++++ include/asm-ia64/xen/xcom_hcall.h | 55 + include/asm-ia64/xen/xencomm.h | 33 + 74 files changed, 11190 insertions(+), 95 deletions(-) -- yamahata |
From: <yam...@va...> - 2008-02-21 22:31:42
|
ia64/Xen will replace setting rr[0-4] with single hypercall later. Signed-off-by: Isaku Yamahata <yam...@va...> --- include/asm-ia64/intrinsics.h | 10 ++++++++++ include/asm-ia64/mmu_context.h | 6 +----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/include/asm-ia64/intrinsics.h b/include/asm-ia64/intrinsics.h index f1135b5..c206755 100644 --- a/include/asm-ia64/intrinsics.h +++ b/include/asm-ia64/intrinsics.h @@ -18,6 +18,15 @@ # include <asm/gcc_intrin.h> #endif +#define ia64_set_rr0_to_rr4(val0, val1, val2, val3, val4) \ +do { \ + ia64_set_rr(0x0000000000000000UL, (val0)); \ + ia64_set_rr(0x2000000000000000UL, (val1)); \ + ia64_set_rr(0x4000000000000000UL, (val2)); \ + ia64_set_rr(0x6000000000000000UL, (val3)); \ + ia64_set_rr(0x8000000000000000UL, (val4)); \ +} while (0) + /* * Force an unresolved reference if someone tries to use * ia64_fetch_and_add() with a bad value. @@ -183,4 +192,5 @@ extern long ia64_cmpxchg_called_with_bad_pointer (void); #endif /* !CONFIG_IA64_DEBUG_CMPXCHG */ #endif +#include <asm/privop.h> #endif /* _ASM_IA64_INTRINSICS_H */ diff --git a/include/asm-ia64/mmu_context.h b/include/asm-ia64/mmu_context.h index cef2400..040bc87 100644 --- a/include/asm-ia64/mmu_context.h +++ b/include/asm-ia64/mmu_context.h @@ -152,11 +152,7 @@ reload_context (nv_mm_context_t context) # endif #endif - ia64_set_rr(0x0000000000000000UL, rr0); - ia64_set_rr(0x2000000000000000UL, rr1); - ia64_set_rr(0x4000000000000000UL, rr2); - ia64_set_rr(0x6000000000000000UL, rr3); - ia64_set_rr(0x8000000000000000UL, rr4); + ia64_set_rr0_to_rr4(rr0, rr1, rr2, rr3, rr4); ia64_srlz_i(); /* srlz.i implies srlz.d */ } -- 1.5.3 -- yamahata |
From: <yam...@va...> - 2008-02-21 22:31:42
|
__local_irq_save() and local_save_flags() are used to mask interruptions. They read all psr bits that requres whole bit emulation. On the other hand, reading only psr.i, the single bit, can be virtualized cheaply. Signed-off-by: Isaku Yamahata <yam...@va...> --- include/asm-ia64/intrinsics.h | 2 ++ include/asm-ia64/system.h | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/include/asm-ia64/intrinsics.h b/include/asm-ia64/intrinsics.h index c206755..5800ad0 100644 --- a/include/asm-ia64/intrinsics.h +++ b/include/asm-ia64/intrinsics.h @@ -18,6 +18,8 @@ # include <asm/gcc_intrin.h> #endif +#define ia64_get_psr_i() (ia64_getreg(_IA64_REG_PSR) & IA64_PSR_I) + #define ia64_set_rr0_to_rr4(val0, val1, val2, val3, val4) \ do { \ ia64_set_rr(0x0000000000000000UL, (val0)); \ diff --git a/include/asm-ia64/system.h b/include/asm-ia64/system.h index 595112b..2bca73e 100644 --- a/include/asm-ia64/system.h +++ b/include/asm-ia64/system.h @@ -125,7 +125,7 @@ extern struct ia64_boot_param { #define __local_irq_save(x) \ do { \ ia64_stop(); \ - (x) = ia64_getreg(_IA64_REG_PSR); \ + (x) = ia64_get_psr_i(); \ ia64_stop(); \ ia64_rsm(IA64_PSR_I); \ } while (0) @@ -173,7 +173,7 @@ do { \ #endif /* !CONFIG_IA64_DEBUG_IRQ */ #define local_irq_enable() ({ ia64_stop(); ia64_ssm(IA64_PSR_I); ia64_srlz_d(); }) -#define local_save_flags(flags) ({ ia64_stop(); (flags) = ia64_getreg(_IA64_REG_PSR); }) +#define local_save_flags(flags) ({ ia64_stop(); (flags) = ia64_get_psr_i(); }) #define irqs_disabled() \ ({ \ -- 1.5.3 -- yamahata |
From: <yam...@va...> - 2008-02-21 22:31:42
|
Signed-off-by: Isaku Yamahata <yam...@va...> --- include/asm-ia64/sync_bitops.h | 61 ++++++++++++++++++++++++++++++++++++++++ 1 files changed, 61 insertions(+), 0 deletions(-) create mode 100644 include/asm-ia64/sync_bitops.h diff --git a/include/asm-ia64/sync_bitops.h b/include/asm-ia64/sync_bitops.h new file mode 100644 index 0000000..dc402be --- /dev/null +++ b/include/asm-ia64/sync_bitops.h @@ -0,0 +1,61 @@ +#ifndef __XEN_SYNC_BITOPS_H__ +#define __XEN_SYNC_BITOPS_H__ + +/* + * Copyright 1992, Linus Torvalds. + * Heavily modified to provide guaranteed strong synchronisation + * when communicating with Xen or other guest OSes running on other CPUs. + */ + +#define ADDR (*(volatile long *) addr) + +static inline void sync_set_bit(int nr, volatile void *addr) +{ + set_bit(nr, addr); +} + +static inline void sync_clear_bit(int nr, volatile void *addr) +{ + clear_bit(nr, addr); +} + +static inline void sync_change_bit(int nr, volatile void *addr) +{ + change_bit(nr, addr); +} + +static inline int sync_test_and_set_bit(int nr, volatile void *addr) +{ + return test_and_set_bit(nr, addr); +} + +static inline int sync_test_and_clear_bit(int nr, volatile void *addr) +{ + return test_and_clear_bit(nr, addr); +} + +static inline int sync_test_and_change_bit(int nr, volatile void *addr) +{ + return test_and_change_bit(nr, addr); +} + +static inline int sync_const_test_bit(int nr, const volatile void *addr) +{ + return test_bit(nr, addr); +} + +static inline int sync_var_test_bit(int nr, volatile void *addr) +{ + return test_bit(nr, addr); +} + +#define sync_cmpxchg ia64_cmpxchg4_acq + +#define sync_test_bit(nr,addr) \ + (__builtin_constant_p(nr) ? \ + sync_const_test_bit((nr), (addr)) : \ + sync_var_test_bit((nr), (addr))) + +#define sync_cmpxchg_subword sync_cmpxchg + +#endif /* __XEN_SYNC_BITOPS_H__ */ -- 1.5.3 -- yamahata |
From: Zhang, X. <xia...@in...> - 2008-02-18 03:52:33
|
Dong, Eddie wrote: > > In X86, there are another enhancement (dynamic patching) base on > pv_ops. The purpose is to improve cpu predication by converting > indriect function call to direct function call for both C & ASM code. > We may take similar approach some time later too. > > We really need advices from community before we jump into coding. > CC some active members that I though may be interested in pv_ops > since KVM-IA64 mailinglist doesn;t exist yet. Hi, Eddie we just created the kvm-ia64-devel mailing list, and cc to the guys from this list who maybe interested in this topic. If you or other guys who are interested in kvm-ia64-devel or pv_virt_ops for ia64, please subscribe it here http://kvm.qumranet.com/kvmwiki/Lists%2C_IRC Xiantao |
From: Avi K. <av...@qu...> - 2008-02-17 09:43:49
|
Zhang, Xiantao wrote: > From: Xiantao Zhang <xia...@in...> > Date: Fri, 15 Feb 2008 10:50:22 +0800 > Subject: [PATCH] qemu: IA64 also need to workaround tcg code. > Applied, thanks. -- Any sufficiently difficult bug is indistinguishable from a feature. |
From: Zhang, X. <xia...@in...> - 2008-02-15 03:19:38
|
From: Xiantao Zhang <xia...@in...> Date: Fri, 15 Feb 2008 10:50:22 +0800 Subject: [PATCH] qemu: IA64 also need to workaround tcg code. Signed-off-by: Xiantao Zhang <xia...@in...> --- qemu/dyngen.c | 1 - qemu/hw/ipf.c | 1 - qemu/target-ia64/fake-exec.c | 44 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 qemu/target-ia64/fake-exec.c diff --git a/qemu/dyngen.c b/qemu/dyngen.c index e5122e3..146d4ec 100644 --- a/qemu/dyngen.c +++ b/qemu/dyngen.c @@ -2767,7 +2767,6 @@ fprintf(outfile, " uint8_t *arm_pool_ptr = gen_code_buf + 0x1000000;\n"); #endif #ifdef HOST_IA64 -#error broken { long addend, not_first = 0; unsigned long sym_idx; diff --git a/qemu/hw/ipf.c b/qemu/hw/ipf.c index ce67715..8c5304d 100644 --- a/qemu/hw/ipf.c +++ b/qemu/hw/ipf.c @@ -37,7 +37,6 @@ #include "boards.h" #include "firmware.h" #include "ia64intrin.h" -#include "dyngen.h" #include <unistd.h> #include "qemu-kvm.h" diff --git a/qemu/target-ia64/fake-exec.c b/qemu/target-ia64/fake-exec.c new file mode 100644 index 0000000..0be4ffd --- /dev/null +++ b/qemu/target-ia64/fake-exec.c @@ -0,0 +1,44 @@ +/* + * fake-exec.c for ia64. + * + * This is a file for stub functions so that compilation is possible + * when TCG CPU emulation is disabled during compilation. + * + * Copyright 2007 IBM Corporation. + * Added by & Authors: + * Jerone Young <jy...@us...> + * + * Copyright 2008 Intel Corporation. + * Added by Xiantao Zhang <xia...@in...> + * + * This work is licensed under the GNU GPL licence version 2 or later. + * + */ +#include "exec.h" +#include "cpu.h" + +int code_copy_enabled = 0; + +void cpu_gen_init(void) +{ +} + +unsigned long code_gen_max_block_size(void) +{ + return 32; +} + +int cpu_ia64_gen_code(CPUState *env, TranslationBlock *tb, int *gen_code_size_ptr) +{ + return 0; +} + +void flush_icache_range(unsigned long start, unsigned long stop) +{ + while (start < stop) { + asm volatile ("fc %0" :: "r"(start)); + start += 32; + } + asm volatile (";;sync.i;;srlz.i;;"); +} + -- 1.5.2 |
From: Hollis B. <ho...@us...> - 2008-02-12 16:40:16
|
On Tue, 2008-02-12 at 22:06 +0800, Zhang, Xiantao wrote: > Hollis Blanchard wrote: > > On Fri, 2008-02-01 at 17:34 +0800, Zhang, Xiantao wrote: > >> From: Xiantao Zhang <xia...@in...> > >> Date: Fri, 1 Feb 2008 17:18:03 +0800 > >> Subject: [PATCH] Make non-x86 arch partially support make sync. > >> > >> Make non-x86 arch partially support make sync, and other archs > >> can get right header files for userspace. > >> Signed-off-by: Xiantao Zhang <xia...@in...> --- > >> kernel/Makefile | 19 ++++++++++++++++--- > >> 1 files changed, 16 insertions(+), 3 deletions(-) > > Hi, Hollis > This is a intial version to support more arch. Yes, as you > pointed, we also need more work to support it fully. Could you make a > patch for that ? It's not just that the original doesn't support all architectures; I think the comments and suggestions I made need to be addressed before it can be committed even for just ia64. -- Hollis Blanchard IBM Linux Technology Center |
From: Zhang, X. <xia...@in...> - 2008-02-12 14:06:59
|
Hollis Blanchard wrote: > On Fri, 2008-02-01 at 17:34 +0800, Zhang, Xiantao wrote: >> From: Xiantao Zhang <xia...@in...> >> Date: Fri, 1 Feb 2008 17:18:03 +0800 >> Subject: [PATCH] Make non-x86 arch partially support make sync. >> >> Make non-x86 arch partially support make sync, and other archs >> can get right header files for userspace. >> Signed-off-by: Xiantao Zhang <xia...@in...> --- >> kernel/Makefile | 19 ++++++++++++++++--- >> 1 files changed, 16 insertions(+), 3 deletions(-) Hi, Hollis This is a intial version to support more arch. Yes, as you pointed, we also need more work to support it fully. Could you make a patch for that ? Thanks Xiantao |
From: Zhang, X. <xia...@in...> - 2008-02-07 11:16:47
|
Akio Takebe wrote: > Hi, Xiantao > >> From: Zhang Xiantao <xia...@in...> >> Date: Tue, 29 Jan 2008 17:27:06 +0800 >> Subject: [PATCH] README: How to boot up guests on kvm/ia64 >> >> Guide: How to boot up guests on kvm/ia64 >> Signed-off-by: Xiantao Zhang <xia...@in...> --- >> arch/ia64/kvm/README | 72 > The better place of the README is Documentation/ia64/. Hi, Akio Thank you for your suggestion! Yes, Documentation/ia64 is a better choice for that :) Thanks Xiantao |
From: Akio T. <tak...@jp...> - 2008-02-07 11:07:59
|
Hi, Xiantao >From: Zhang Xiantao <xia...@in...> >Date: Tue, 29 Jan 2008 17:27:06 +0800 >Subject: [PATCH] README: How to boot up guests on kvm/ia64 > >Guide: How to boot up guests on kvm/ia64 >Signed-off-by: Xiantao Zhang <xia...@in...> >--- > arch/ia64/kvm/README | 72 The better place of the README is Documentation/ia64/. Best Regards, Akio Takebe |
From: Hollis B. <ho...@us...> - 2008-02-04 22:18:40
|
On Fri, 2008-02-01 at 17:34 +0800, Zhang, Xiantao wrote: > From: Xiantao Zhang <xia...@in...> > Date: Fri, 1 Feb 2008 17:18:03 +0800 > Subject: [PATCH] Make non-x86 arch partially support make sync. > > Make non-x86 arch partially support make sync, and other archs > can get right header files for userspace. > Signed-off-by: Xiantao Zhang <xia...@in...> > --- > kernel/Makefile | 19 ++++++++++++++++--- > 1 files changed, 16 insertions(+), 3 deletions(-) > > diff --git a/kernel/Makefile b/kernel/Makefile > index 7a435b5..2f0d7d5 100644 > --- a/kernel/Makefile > +++ b/kernel/Makefile > @@ -13,6 +13,17 @@ LINUX = ../linux-2.6 > > version = $(shell cd $(LINUX); git describe) > > +ARCH := $(shell uname -m | sed -e s/i.86/i386/) > +SRCARCH := $(ARCH) > + > +# Additional ARCH settings for x86 > +ifeq ($(ARCH),i386) > + SRCARCH := x86 > +endif > +ifeq ($(ARCH),x86_64) > + SRCARCH := x86 > +endif > + > _hack = mv $1 $1.orig && \ > gawk -v version=$(version) -f hack-module.awk $1.orig \ > | sed '/\#include/! s/\blapic\b/l_apic/g' > $1 && rm $1.orig ARCH is already set in ../config.mak. "case" would be a better shell construct than "ifeq" for this translation. > @@ -30,14 +41,15 @@ all:: > sync: > rm -rf tmp > rsync --exclude='*.mod.c' -R \ > - "$(LINUX)"/arch/x86/kvm/./*.[ch] \ > + "$(LINUX)"/arch/$(SRCARCH)/kvm/./*.[cSh] \ > "$(LINUX)"/virt/kvm/./*.[ch] \ > "$(LINUX)"/./include/linux/kvm*.h \ > - "$(LINUX)"/./include/asm-x86/kvm*.h \ > + "$(LINUX)"/./include/asm-$(SRCARCH)/kvm*.h \ > tmp/ > rm -rf include/asm > - ln -s asm-x86 include/asm > + ln -s asm-$(SRCARCH) include/asm > > +ifeq ($(SRCARCH),x86) Rather than adding an ifdef for every architecture here, can we define a HEADERS variable and do something like for hdr in $HEADERS ; do $(call hack, $hdr) done HEADERS could be defined in the case statements you're going to add. ;) > $(call unifdef, include/linux/kvm.h) > $(call unifdef, include/linux/kvm_para.h) Why are these headers not common? > $(call unifdef, include/asm-x86/kvm.h) > @@ -48,6 +60,7 @@ sync: > $(call hack, svm.c) > $(call hack, x86.c) > $(call hack, irq.h) > +endif > for i in $$(find tmp -type f -printf '%P '); \ > do cmp -s $$i tmp/$$i || cp tmp/$$i $$i; done > rm -rf tmp -- Hollis Blanchard IBM Linux Technology Center |
From: Jes S. <je...@sg...> - 2008-02-04 13:47:44
|
Hi Xiantao, Any chance you have an update of the status of the public tree for the ia64 kernel patches? Thanks, Jes |
From: Zhang, X. <xia...@in...> - 2008-02-03 10:26:43
|
Hi, all Thank you for your intention about kvm/ia64. Now, we have enabled save/restore and Live migration on kvm/ia64, and will send out the implementation after the leave for Chinese New Year!(Feb 4- Feb 11).=20 Thanks! Xiantao |
From: Zhang, X. <xia...@in...> - 2008-02-03 07:01:54
|
From: Xiantao Zhang <xia...@in...> Date: Sun, 3 Feb 2008 14:46:02 +0800 Subject: [PATCH] kvm: Let ioctl_get_regs suppot input pararmeters. Since kvm_regs is allocated from kernel stack, and its size is limited. In order to save large register files of some archs, this API should accept input parameters. User need to pass a user-space pointer with large memory, and kernel can copy reigster files to it. Signed-off-by: Xiantao Zhang<xia...@in...> --- virt/kvm/kvm_main.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index a499f50..6d74d0b 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -807,7 +807,8 @@ static long kvm_vcpu_ioctl(struct file *filp, case KVM_GET_REGS: { struct kvm_regs kvm_regs; =20 - memset(&kvm_regs, 0, sizeof kvm_regs); + if (copy_from_user(&kvm_regs, argp, sizeof kvm_regs)) + goto out; r =3D kvm_arch_vcpu_ioctl_get_regs(vcpu, &kvm_regs); if (r) goto out; --=20 1.5.2 |
From: Zhang, X. <xia...@in...> - 2008-02-01 09:35:27
|
From: Xiantao Zhang <xia...@in...> Date: Fri, 1 Feb 2008 17:18:03 +0800 Subject: [PATCH] Make non-x86 arch partially support make sync. Make non-x86 arch partially support make sync, and other archs can get right header files for userspace. Signed-off-by: Xiantao Zhang <xia...@in...> --- kernel/Makefile | 19 ++++++++++++++++--- 1 files changed, 16 insertions(+), 3 deletions(-) diff --git a/kernel/Makefile b/kernel/Makefile index 7a435b5..2f0d7d5 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -13,6 +13,17 @@ LINUX =3D ../linux-2.6 =20 version =3D $(shell cd $(LINUX); git describe) =20 +ARCH :=3D $(shell uname -m | sed -e s/i.86/i386/) +SRCARCH :=3D $(ARCH) + +# Additional ARCH settings for x86 +ifeq ($(ARCH),i386) + SRCARCH :=3D x86 +endif +ifeq ($(ARCH),x86_64) + SRCARCH :=3D x86 +endif + _hack =3D mv $1 $1.orig && \ gawk -v version=3D$(version) -f hack-module.awk $1.orig \ | sed '/\#include/! s/\blapic\b/l_apic/g' > $1 && rm $1.orig @@ -30,14 +41,15 @@ all:: sync: rm -rf tmp rsync --exclude=3D'*.mod.c' -R \ - "$(LINUX)"/arch/x86/kvm/./*.[ch] \ + "$(LINUX)"/arch/$(SRCARCH)/kvm/./*.[cSh] \ "$(LINUX)"/virt/kvm/./*.[ch] \ "$(LINUX)"/./include/linux/kvm*.h \ - "$(LINUX)"/./include/asm-x86/kvm*.h \ + "$(LINUX)"/./include/asm-$(SRCARCH)/kvm*.h \ tmp/ rm -rf include/asm - ln -s asm-x86 include/asm + ln -s asm-$(SRCARCH) include/asm =20 +ifeq ($(SRCARCH),x86) $(call unifdef, include/linux/kvm.h) $(call unifdef, include/linux/kvm_para.h) $(call unifdef, include/asm-x86/kvm.h) @@ -48,6 +60,7 @@ sync: $(call hack, svm.c) $(call hack, x86.c) $(call hack, irq.h) +endif for i in $$(find tmp -type f -printf '%P '); \ do cmp -s $$i tmp/$$i || cp tmp/$$i $$i; done rm -rf tmp --=20 1.5.2 |
From: Zhang, X. <xia...@in...> - 2008-02-01 04:01:35
|
Akio Takebe wrote: > Hi, Xiantao >=20 >> +void thash_vhpt_insert(VCPU *v, u64 pte, u64 itir, u64 va, int >> type) +{ + u64 phy_pte, psr; >> + ia64_rr mrr; >> + >> + mrr.val =3D ia64_get_rr(va); >> + phy_pte =3D translate_phy_pte(&pte, itir, va); >> + >> + if (itir_ps(itir) >=3D mrr.ps) { >> + vhpt_insert(phy_pte, itir, va, pte); >> + } else { >> + phy_pte &=3D ~PAGE_FLAGS_RV_MASK; >> + psr =3D ia64_clear_ic(); >> + ia64_itc(type, va, phy_pte, itir_ps(itir)); >> + ia64_set_psr(psr); >> + ia64_srlz_i(); >> + } >> +} > You add ia64_srlz_i() into ia64_set_psr() with [02]patch. > So is this a redundancy if the patch is applied? Yes, we need to remove it. Once the second patch is picked up. Thanks Xiantao |