diff options
Diffstat (limited to 'arch/x86/include/asm/xen/hypercall.h')
| -rw-r--r-- | arch/x86/include/asm/xen/hypercall.h | 83 | 
1 files changed, 64 insertions, 19 deletions
diff --git a/arch/x86/include/asm/xen/hypercall.h b/arch/x86/include/asm/xen/hypercall.h index a3c28ae4025..ca08a27b90b 100644 --- a/arch/x86/include/asm/xen/hypercall.h +++ b/arch/x86/include/asm/xen/hypercall.h @@ -39,12 +39,16 @@  #include <linux/string.h>  #include <linux/types.h> +#include <trace/events/xen.h> +  #include <asm/page.h>  #include <asm/pgtable.h>  #include <xen/interface/xen.h>  #include <xen/interface/sched.h>  #include <xen/interface/physdev.h> +#include <xen/interface/platform.h> +#include <xen/interface/xen-mca.h>  /*   * The hypercall asms have to meet several constraints: @@ -287,7 +291,7 @@ HYPERVISOR_fpu_taskswitch(int set)  static inline int  HYPERVISOR_sched_op(int cmd, void *arg)  { -	return _hypercall2(int, sched_op_new, cmd, arg); +	return _hypercall2(int, sched_op, cmd, arg);  }  static inline long @@ -299,6 +303,20 @@ HYPERVISOR_set_timer_op(u64 timeout)  }  static inline int +HYPERVISOR_mca(struct xen_mc *mc_op) +{ +	mc_op->interface_version = XEN_MCA_INTERFACE_VERSION; +	return _hypercall1(int, mca, mc_op); +} + +static inline int +HYPERVISOR_dom0_op(struct xen_platform_op *platform_op) +{ +	platform_op->interface_version = XENPF_INTERFACE_VERSION; +	return _hypercall1(int, dom0_op, platform_op); +} + +static inline int  HYPERVISOR_set_debugreg(int reg, unsigned long value)  {  	return _hypercall2(int, set_debugreg, reg, value); @@ -325,7 +343,7 @@ HYPERVISOR_memory_op(unsigned int cmd, void *arg)  }  static inline int -HYPERVISOR_multicall(void *call_list, int nr_calls) +HYPERVISOR_multicall(void *call_list, uint32_t nr_calls)  {  	return _hypercall2(int, multicall, call_list, nr_calls);  } @@ -341,18 +359,14 @@ HYPERVISOR_update_va_mapping(unsigned long va, pte_t new_val,  		return _hypercall4(int, update_va_mapping, va,  				   new_val.pte, new_val.pte >> 32, flags);  } +extern int __must_check xen_event_channel_op_compat(int, void *);  static inline int  HYPERVISOR_event_channel_op(int cmd, void *arg)  {  	int rc = _hypercall2(int, event_channel_op, cmd, arg); -	if (unlikely(rc == -ENOSYS)) { -		struct evtchn_op op; -		op.cmd = cmd; -		memcpy(&op.u, arg, sizeof(op.u)); -		rc = _hypercall1(int, event_channel_op_compat, &op); -		memcpy(arg, &op.u, sizeof(op.u)); -	} +	if (unlikely(rc == -ENOSYS)) +		rc = xen_event_channel_op_compat(cmd, arg);  	return rc;  } @@ -368,17 +382,14 @@ HYPERVISOR_console_io(int cmd, int count, char *str)  	return _hypercall3(int, console_io, cmd, count, str);  } +extern int __must_check xen_physdev_op_compat(int, void *); +  static inline int  HYPERVISOR_physdev_op(int cmd, void *arg)  {  	int rc = _hypercall2(int, physdev_op, cmd, arg); -	if (unlikely(rc == -ENOSYS)) { -		struct physdev_op op; -		op.cmd = cmd; -		memcpy(&op.u, arg, sizeof(op.u)); -		rc = _hypercall1(int, physdev_op_compat, &op); -		memcpy(arg, &op.u, sizeof(op.u)); -	} +	if (unlikely(rc == -ENOSYS)) +		rc = xen_physdev_op_compat(cmd, arg);  	return rc;  } @@ -422,10 +433,17 @@ HYPERVISOR_set_segment_base(int reg, unsigned long value)  #endif  static inline int -HYPERVISOR_suspend(unsigned long srec) +HYPERVISOR_suspend(unsigned long start_info_mfn)  { -	return _hypercall3(int, sched_op, SCHEDOP_shutdown, -			   SHUTDOWN_suspend, srec); +	struct sched_shutdown r = { .reason = SHUTDOWN_suspend }; + +	/* +	 * For a PV guest the tools require that the start_info mfn be +	 * present in rdx/edx when the hypercall is made. Per the +	 * hypercall calling convention this is the third hypercall +	 * argument, which is start_info_mfn here. +	 */ +	return _hypercall3(int, sched_op, SCHEDOP_shutdown, &r, start_info_mfn);  }  static inline int @@ -440,11 +458,20 @@ HYPERVISOR_hvm_op(int op, void *arg)         return _hypercall2(unsigned long, hvm_op, op, arg);  } +static inline int +HYPERVISOR_tmem_op( +	struct tmem_op *op) +{ +	return _hypercall1(int, tmem_op, op); +} +  static inline void  MULTI_fpu_taskswitch(struct multicall_entry *mcl, int set)  {  	mcl->op = __HYPERVISOR_fpu_taskswitch;  	mcl->args[0] = set; + +	trace_xen_mc_entry(mcl, 1);  }  static inline void @@ -461,6 +488,8 @@ MULTI_update_va_mapping(struct multicall_entry *mcl, unsigned long va,  		mcl->args[2] = new_val.pte >> 32;  		mcl->args[3] = flags;  	} + +	trace_xen_mc_entry(mcl, sizeof(new_val) == sizeof(long) ? 3 : 4);  }  static inline void @@ -471,6 +500,8 @@ MULTI_grant_table_op(struct multicall_entry *mcl, unsigned int cmd,  	mcl->args[0] = cmd;  	mcl->args[1] = (unsigned long)uop;  	mcl->args[2] = count; + +	trace_xen_mc_entry(mcl, 3);  }  static inline void @@ -490,6 +521,8 @@ MULTI_update_va_mapping_otherdomain(struct multicall_entry *mcl, unsigned long v  		mcl->args[3] = flags;  		mcl->args[4] = domid;  	} + +	trace_xen_mc_entry(mcl, sizeof(new_val) == sizeof(long) ? 4 : 5);  }  static inline void @@ -506,6 +539,8 @@ MULTI_update_descriptor(struct multicall_entry *mcl, u64 maddr,  		mcl->args[2] = desc.a;  		mcl->args[3] = desc.b;  	} + +	trace_xen_mc_entry(mcl, sizeof(maddr) == sizeof(long) ? 2 : 4);  }  static inline void @@ -514,6 +549,8 @@ MULTI_memory_op(struct multicall_entry *mcl, unsigned int cmd, void *arg)  	mcl->op = __HYPERVISOR_memory_op;  	mcl->args[0] = cmd;  	mcl->args[1] = (unsigned long)arg; + +	trace_xen_mc_entry(mcl, 2);  }  static inline void @@ -525,6 +562,8 @@ MULTI_mmu_update(struct multicall_entry *mcl, struct mmu_update *req,  	mcl->args[1] = count;  	mcl->args[2] = (unsigned long)success_count;  	mcl->args[3] = domid; + +	trace_xen_mc_entry(mcl, 4);  }  static inline void @@ -536,6 +575,8 @@ MULTI_mmuext_op(struct multicall_entry *mcl, struct mmuext_op *op, int count,  	mcl->args[1] = count;  	mcl->args[2] = (unsigned long)success_count;  	mcl->args[3] = domid; + +	trace_xen_mc_entry(mcl, 4);  }  static inline void @@ -544,6 +585,8 @@ MULTI_set_gdt(struct multicall_entry *mcl, unsigned long *frames, int entries)  	mcl->op = __HYPERVISOR_set_gdt;  	mcl->args[0] = (unsigned long)frames;  	mcl->args[1] = entries; + +	trace_xen_mc_entry(mcl, 2);  }  static inline void @@ -553,6 +596,8 @@ MULTI_stack_switch(struct multicall_entry *mcl,  	mcl->op = __HYPERVISOR_stack_switch;  	mcl->args[0] = ss;  	mcl->args[1] = esp; + +	trace_xen_mc_entry(mcl, 2);  }  #endif /* _ASM_X86_XEN_HYPERCALL_H */  | 
