mirror of
https://github.com/AetherDroid/android_kernel_samsung_on5xelte.git
synced 2025-10-30 15:48:52 +01:00
Fixed MTP to work with TWRP
This commit is contained in:
commit
f6dfaef42e
50820 changed files with 20846062 additions and 0 deletions
23
arch/x86/include/asm/xen/events.h
Normal file
23
arch/x86/include/asm/xen/events.h
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef _ASM_X86_XEN_EVENTS_H
|
||||
#define _ASM_X86_XEN_EVENTS_H
|
||||
|
||||
enum ipi_vector {
|
||||
XEN_RESCHEDULE_VECTOR,
|
||||
XEN_CALL_FUNCTION_VECTOR,
|
||||
XEN_CALL_FUNCTION_SINGLE_VECTOR,
|
||||
XEN_SPIN_UNLOCK_VECTOR,
|
||||
XEN_IRQ_WORK_VECTOR,
|
||||
XEN_NMI_VECTOR,
|
||||
|
||||
XEN_NR_IPIS,
|
||||
};
|
||||
|
||||
static inline int xen_irqs_disabled(struct pt_regs *regs)
|
||||
{
|
||||
return raw_irqs_disabled_flags(regs->flags);
|
||||
}
|
||||
|
||||
/* No need for a barrier -- XCHG is a barrier on x86. */
|
||||
#define xchg_xen_ulong(ptr, val) xchg((ptr), (val))
|
||||
|
||||
#endif /* _ASM_X86_XEN_EVENTS_H */
|
||||
603
arch/x86/include/asm/xen/hypercall.h
Normal file
603
arch/x86/include/asm/xen/hypercall.h
Normal file
|
|
@ -0,0 +1,603 @@
|
|||
/******************************************************************************
|
||||
* hypercall.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 _ASM_X86_XEN_HYPERCALL_H
|
||||
#define _ASM_X86_XEN_HYPERCALL_H
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/errno.h>
|
||||
#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:
|
||||
* - Work on 32- and 64-bit.
|
||||
* The two architectures put their arguments in different sets of
|
||||
* registers.
|
||||
*
|
||||
* - Work around asm syntax quirks
|
||||
* It isn't possible to specify one of the rNN registers in a
|
||||
* constraint, so we use explicit register variables to get the
|
||||
* args into the right place.
|
||||
*
|
||||
* - Mark all registers as potentially clobbered
|
||||
* Even unused parameters can be clobbered by the hypervisor, so we
|
||||
* need to make sure gcc knows it.
|
||||
*
|
||||
* - Avoid compiler bugs.
|
||||
* This is the tricky part. Because x86_32 has such a constrained
|
||||
* register set, gcc versions below 4.3 have trouble generating
|
||||
* code when all the arg registers and memory are trashed by the
|
||||
* asm. There are syntactically simpler ways of achieving the
|
||||
* semantics below, but they cause the compiler to crash.
|
||||
*
|
||||
* The only combination I found which works is:
|
||||
* - assign the __argX variables first
|
||||
* - list all actually used parameters as "+r" (__argX)
|
||||
* - clobber the rest
|
||||
*
|
||||
* The result certainly isn't pretty, and it really shows up cpp's
|
||||
* weakness as as macro language. Sorry. (But let's just give thanks
|
||||
* there aren't more than 5 arguments...)
|
||||
*/
|
||||
|
||||
extern struct { char _entry[32]; } hypercall_page[];
|
||||
|
||||
#define __HYPERCALL "call hypercall_page+%c[offset]"
|
||||
#define __HYPERCALL_ENTRY(x) \
|
||||
[offset] "i" (__HYPERVISOR_##x * sizeof(hypercall_page[0]))
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
#define __HYPERCALL_RETREG "eax"
|
||||
#define __HYPERCALL_ARG1REG "ebx"
|
||||
#define __HYPERCALL_ARG2REG "ecx"
|
||||
#define __HYPERCALL_ARG3REG "edx"
|
||||
#define __HYPERCALL_ARG4REG "esi"
|
||||
#define __HYPERCALL_ARG5REG "edi"
|
||||
#else
|
||||
#define __HYPERCALL_RETREG "rax"
|
||||
#define __HYPERCALL_ARG1REG "rdi"
|
||||
#define __HYPERCALL_ARG2REG "rsi"
|
||||
#define __HYPERCALL_ARG3REG "rdx"
|
||||
#define __HYPERCALL_ARG4REG "r10"
|
||||
#define __HYPERCALL_ARG5REG "r8"
|
||||
#endif
|
||||
|
||||
#define __HYPERCALL_DECLS \
|
||||
register unsigned long __res asm(__HYPERCALL_RETREG); \
|
||||
register unsigned long __arg1 asm(__HYPERCALL_ARG1REG) = __arg1; \
|
||||
register unsigned long __arg2 asm(__HYPERCALL_ARG2REG) = __arg2; \
|
||||
register unsigned long __arg3 asm(__HYPERCALL_ARG3REG) = __arg3; \
|
||||
register unsigned long __arg4 asm(__HYPERCALL_ARG4REG) = __arg4; \
|
||||
register unsigned long __arg5 asm(__HYPERCALL_ARG5REG) = __arg5;
|
||||
|
||||
#define __HYPERCALL_0PARAM "=r" (__res)
|
||||
#define __HYPERCALL_1PARAM __HYPERCALL_0PARAM, "+r" (__arg1)
|
||||
#define __HYPERCALL_2PARAM __HYPERCALL_1PARAM, "+r" (__arg2)
|
||||
#define __HYPERCALL_3PARAM __HYPERCALL_2PARAM, "+r" (__arg3)
|
||||
#define __HYPERCALL_4PARAM __HYPERCALL_3PARAM, "+r" (__arg4)
|
||||
#define __HYPERCALL_5PARAM __HYPERCALL_4PARAM, "+r" (__arg5)
|
||||
|
||||
#define __HYPERCALL_0ARG()
|
||||
#define __HYPERCALL_1ARG(a1) \
|
||||
__HYPERCALL_0ARG() __arg1 = (unsigned long)(a1);
|
||||
#define __HYPERCALL_2ARG(a1,a2) \
|
||||
__HYPERCALL_1ARG(a1) __arg2 = (unsigned long)(a2);
|
||||
#define __HYPERCALL_3ARG(a1,a2,a3) \
|
||||
__HYPERCALL_2ARG(a1,a2) __arg3 = (unsigned long)(a3);
|
||||
#define __HYPERCALL_4ARG(a1,a2,a3,a4) \
|
||||
__HYPERCALL_3ARG(a1,a2,a3) __arg4 = (unsigned long)(a4);
|
||||
#define __HYPERCALL_5ARG(a1,a2,a3,a4,a5) \
|
||||
__HYPERCALL_4ARG(a1,a2,a3,a4) __arg5 = (unsigned long)(a5);
|
||||
|
||||
#define __HYPERCALL_CLOBBER5 "memory"
|
||||
#define __HYPERCALL_CLOBBER4 __HYPERCALL_CLOBBER5, __HYPERCALL_ARG5REG
|
||||
#define __HYPERCALL_CLOBBER3 __HYPERCALL_CLOBBER4, __HYPERCALL_ARG4REG
|
||||
#define __HYPERCALL_CLOBBER2 __HYPERCALL_CLOBBER3, __HYPERCALL_ARG3REG
|
||||
#define __HYPERCALL_CLOBBER1 __HYPERCALL_CLOBBER2, __HYPERCALL_ARG2REG
|
||||
#define __HYPERCALL_CLOBBER0 __HYPERCALL_CLOBBER1, __HYPERCALL_ARG1REG
|
||||
|
||||
#define _hypercall0(type, name) \
|
||||
({ \
|
||||
__HYPERCALL_DECLS; \
|
||||
__HYPERCALL_0ARG(); \
|
||||
asm volatile (__HYPERCALL \
|
||||
: __HYPERCALL_0PARAM \
|
||||
: __HYPERCALL_ENTRY(name) \
|
||||
: __HYPERCALL_CLOBBER0); \
|
||||
(type)__res; \
|
||||
})
|
||||
|
||||
#define _hypercall1(type, name, a1) \
|
||||
({ \
|
||||
__HYPERCALL_DECLS; \
|
||||
__HYPERCALL_1ARG(a1); \
|
||||
asm volatile (__HYPERCALL \
|
||||
: __HYPERCALL_1PARAM \
|
||||
: __HYPERCALL_ENTRY(name) \
|
||||
: __HYPERCALL_CLOBBER1); \
|
||||
(type)__res; \
|
||||
})
|
||||
|
||||
#define _hypercall2(type, name, a1, a2) \
|
||||
({ \
|
||||
__HYPERCALL_DECLS; \
|
||||
__HYPERCALL_2ARG(a1, a2); \
|
||||
asm volatile (__HYPERCALL \
|
||||
: __HYPERCALL_2PARAM \
|
||||
: __HYPERCALL_ENTRY(name) \
|
||||
: __HYPERCALL_CLOBBER2); \
|
||||
(type)__res; \
|
||||
})
|
||||
|
||||
#define _hypercall3(type, name, a1, a2, a3) \
|
||||
({ \
|
||||
__HYPERCALL_DECLS; \
|
||||
__HYPERCALL_3ARG(a1, a2, a3); \
|
||||
asm volatile (__HYPERCALL \
|
||||
: __HYPERCALL_3PARAM \
|
||||
: __HYPERCALL_ENTRY(name) \
|
||||
: __HYPERCALL_CLOBBER3); \
|
||||
(type)__res; \
|
||||
})
|
||||
|
||||
#define _hypercall4(type, name, a1, a2, a3, a4) \
|
||||
({ \
|
||||
__HYPERCALL_DECLS; \
|
||||
__HYPERCALL_4ARG(a1, a2, a3, a4); \
|
||||
asm volatile (__HYPERCALL \
|
||||
: __HYPERCALL_4PARAM \
|
||||
: __HYPERCALL_ENTRY(name) \
|
||||
: __HYPERCALL_CLOBBER4); \
|
||||
(type)__res; \
|
||||
})
|
||||
|
||||
#define _hypercall5(type, name, a1, a2, a3, a4, a5) \
|
||||
({ \
|
||||
__HYPERCALL_DECLS; \
|
||||
__HYPERCALL_5ARG(a1, a2, a3, a4, a5); \
|
||||
asm volatile (__HYPERCALL \
|
||||
: __HYPERCALL_5PARAM \
|
||||
: __HYPERCALL_ENTRY(name) \
|
||||
: __HYPERCALL_CLOBBER5); \
|
||||
(type)__res; \
|
||||
})
|
||||
|
||||
static inline long
|
||||
privcmd_call(unsigned call,
|
||||
unsigned long a1, unsigned long a2,
|
||||
unsigned long a3, unsigned long a4,
|
||||
unsigned long a5)
|
||||
{
|
||||
__HYPERCALL_DECLS;
|
||||
__HYPERCALL_5ARG(a1, a2, a3, a4, a5);
|
||||
|
||||
asm volatile("call *%[call]"
|
||||
: __HYPERCALL_5PARAM
|
||||
: [call] "a" (&hypercall_page[call])
|
||||
: __HYPERCALL_CLOBBER5);
|
||||
|
||||
return (long)__res;
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_set_trap_table(struct trap_info *table)
|
||||
{
|
||||
return _hypercall1(int, set_trap_table, table);
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_mmu_update(struct mmu_update *req, int count,
|
||||
int *success_count, domid_t domid)
|
||||
{
|
||||
return _hypercall4(int, mmu_update, req, count, success_count, domid);
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_mmuext_op(struct mmuext_op *op, int count,
|
||||
int *success_count, domid_t domid)
|
||||
{
|
||||
return _hypercall4(int, mmuext_op, op, count, success_count, domid);
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_set_gdt(unsigned long *frame_list, int entries)
|
||||
{
|
||||
return _hypercall2(int, set_gdt, frame_list, entries);
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_stack_switch(unsigned long ss, unsigned long esp)
|
||||
{
|
||||
return _hypercall2(int, stack_switch, ss, esp);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
static inline int
|
||||
HYPERVISOR_set_callbacks(unsigned long event_selector,
|
||||
unsigned long event_address,
|
||||
unsigned long failsafe_selector,
|
||||
unsigned long failsafe_address)
|
||||
{
|
||||
return _hypercall4(int, set_callbacks,
|
||||
event_selector, event_address,
|
||||
failsafe_selector, failsafe_address);
|
||||
}
|
||||
#else /* CONFIG_X86_64 */
|
||||
static inline int
|
||||
HYPERVISOR_set_callbacks(unsigned long event_address,
|
||||
unsigned long failsafe_address,
|
||||
unsigned long syscall_address)
|
||||
{
|
||||
return _hypercall3(int, set_callbacks,
|
||||
event_address, failsafe_address,
|
||||
syscall_address);
|
||||
}
|
||||
#endif /* CONFIG_X86_{32,64} */
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_callback_op(int cmd, void *arg)
|
||||
{
|
||||
return _hypercall2(int, callback_op, cmd, arg);
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_fpu_taskswitch(int set)
|
||||
{
|
||||
return _hypercall1(int, fpu_taskswitch, set);
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_sched_op(int cmd, void *arg)
|
||||
{
|
||||
return _hypercall2(int, sched_op, cmd, arg);
|
||||
}
|
||||
|
||||
static inline long
|
||||
HYPERVISOR_set_timer_op(u64 timeout)
|
||||
{
|
||||
unsigned long timeout_hi = (unsigned long)(timeout>>32);
|
||||
unsigned long timeout_lo = (unsigned long)timeout;
|
||||
return _hypercall2(long, set_timer_op, timeout_lo, timeout_hi);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static inline unsigned long
|
||||
HYPERVISOR_get_debugreg(int reg)
|
||||
{
|
||||
return _hypercall1(unsigned long, get_debugreg, reg);
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_update_descriptor(u64 ma, u64 desc)
|
||||
{
|
||||
if (sizeof(u64) == sizeof(long))
|
||||
return _hypercall2(int, update_descriptor, ma, desc);
|
||||
return _hypercall4(int, update_descriptor, ma, ma>>32, desc, desc>>32);
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_memory_op(unsigned int cmd, void *arg)
|
||||
{
|
||||
return _hypercall2(int, memory_op, cmd, arg);
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_multicall(void *call_list, uint32_t nr_calls)
|
||||
{
|
||||
return _hypercall2(int, multicall, call_list, nr_calls);
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_update_va_mapping(unsigned long va, pte_t new_val,
|
||||
unsigned long flags)
|
||||
{
|
||||
if (sizeof(new_val) == sizeof(long))
|
||||
return _hypercall3(int, update_va_mapping, va,
|
||||
new_val.pte, flags);
|
||||
else
|
||||
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))
|
||||
rc = xen_event_channel_op_compat(cmd, arg);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_xen_version(int cmd, void *arg)
|
||||
{
|
||||
return _hypercall2(int, xen_version, cmd, arg);
|
||||
}
|
||||
|
||||
static inline int
|
||||
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))
|
||||
rc = xen_physdev_op_compat(cmd, arg);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count)
|
||||
{
|
||||
return _hypercall3(int, grant_table_op, cmd, uop, count);
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_update_va_mapping_otherdomain(unsigned long va, pte_t new_val,
|
||||
unsigned long flags, domid_t domid)
|
||||
{
|
||||
if (sizeof(new_val) == sizeof(long))
|
||||
return _hypercall4(int, update_va_mapping_otherdomain, va,
|
||||
new_val.pte, flags, domid);
|
||||
else
|
||||
return _hypercall5(int, update_va_mapping_otherdomain, va,
|
||||
new_val.pte, new_val.pte >> 32,
|
||||
flags, domid);
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_vm_assist(unsigned int cmd, unsigned int type)
|
||||
{
|
||||
return _hypercall2(int, vm_assist, cmd, type);
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_vcpu_op(int cmd, int vcpuid, void *extra_args)
|
||||
{
|
||||
return _hypercall3(int, vcpu_op, cmd, vcpuid, extra_args);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
static inline int
|
||||
HYPERVISOR_set_segment_base(int reg, unsigned long value)
|
||||
{
|
||||
return _hypercall2(int, set_segment_base, reg, value);
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_suspend(unsigned long start_info_mfn)
|
||||
{
|
||||
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
|
||||
HYPERVISOR_nmi_op(unsigned long op, unsigned long arg)
|
||||
{
|
||||
return _hypercall2(int, nmi_op, op, arg);
|
||||
}
|
||||
|
||||
static inline unsigned long __must_check
|
||||
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
|
||||
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->args[0] = va;
|
||||
if (sizeof(new_val) == sizeof(long)) {
|
||||
mcl->args[1] = new_val.pte;
|
||||
mcl->args[2] = flags;
|
||||
} else {
|
||||
mcl->args[1] = new_val.pte;
|
||||
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
|
||||
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;
|
||||
|
||||
trace_xen_mc_entry(mcl, 3);
|
||||
}
|
||||
|
||||
static inline void
|
||||
MULTI_update_va_mapping_otherdomain(struct multicall_entry *mcl, unsigned long va,
|
||||
pte_t new_val, unsigned long flags,
|
||||
domid_t domid)
|
||||
{
|
||||
mcl->op = __HYPERVISOR_update_va_mapping_otherdomain;
|
||||
mcl->args[0] = va;
|
||||
if (sizeof(new_val) == sizeof(long)) {
|
||||
mcl->args[1] = new_val.pte;
|
||||
mcl->args[2] = flags;
|
||||
mcl->args[3] = domid;
|
||||
} else {
|
||||
mcl->args[1] = new_val.pte;
|
||||
mcl->args[2] = new_val.pte >> 32;
|
||||
mcl->args[3] = flags;
|
||||
mcl->args[4] = domid;
|
||||
}
|
||||
|
||||
trace_xen_mc_entry(mcl, sizeof(new_val) == sizeof(long) ? 4 : 5);
|
||||
}
|
||||
|
||||
static inline void
|
||||
MULTI_update_descriptor(struct multicall_entry *mcl, u64 maddr,
|
||||
struct desc_struct desc)
|
||||
{
|
||||
mcl->op = __HYPERVISOR_update_descriptor;
|
||||
if (sizeof(maddr) == sizeof(long)) {
|
||||
mcl->args[0] = maddr;
|
||||
mcl->args[1] = *(unsigned long *)&desc;
|
||||
} else {
|
||||
mcl->args[0] = maddr;
|
||||
mcl->args[1] = maddr >> 32;
|
||||
mcl->args[2] = desc.a;
|
||||
mcl->args[3] = desc.b;
|
||||
}
|
||||
|
||||
trace_xen_mc_entry(mcl, sizeof(maddr) == sizeof(long) ? 2 : 4);
|
||||
}
|
||||
|
||||
static inline void
|
||||
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
|
||||
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;
|
||||
|
||||
trace_xen_mc_entry(mcl, 4);
|
||||
}
|
||||
|
||||
static inline void
|
||||
MULTI_mmuext_op(struct multicall_entry *mcl, struct mmuext_op *op, int count,
|
||||
int *success_count, domid_t domid)
|
||||
{
|
||||
mcl->op = __HYPERVISOR_mmuext_op;
|
||||
mcl->args[0] = (unsigned long)op;
|
||||
mcl->args[1] = count;
|
||||
mcl->args[2] = (unsigned long)success_count;
|
||||
mcl->args[3] = domid;
|
||||
|
||||
trace_xen_mc_entry(mcl, 4);
|
||||
}
|
||||
|
||||
static inline void
|
||||
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
|
||||
MULTI_stack_switch(struct multicall_entry *mcl,
|
||||
unsigned long ss, unsigned long esp)
|
||||
{
|
||||
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 */
|
||||
60
arch/x86/include/asm/xen/hypervisor.h
Normal file
60
arch/x86/include/asm/xen/hypervisor.h
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/******************************************************************************
|
||||
* 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 _ASM_X86_XEN_HYPERVISOR_H
|
||||
#define _ASM_X86_XEN_HYPERVISOR_H
|
||||
|
||||
extern struct shared_info *HYPERVISOR_shared_info;
|
||||
extern struct start_info *xen_start_info;
|
||||
|
||||
#include <asm/processor.h>
|
||||
|
||||
static inline uint32_t xen_cpuid_base(void)
|
||||
{
|
||||
return hypervisor_cpuid_base("XenVMMXenVMM", 2);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_XEN
|
||||
extern bool xen_hvm_need_lapic(void);
|
||||
|
||||
static inline bool xen_x2apic_para_available(void)
|
||||
{
|
||||
return xen_hvm_need_lapic();
|
||||
}
|
||||
#else
|
||||
static inline bool xen_x2apic_para_available(void)
|
||||
{
|
||||
return (xen_cpuid_base() != 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ASM_X86_XEN_HYPERVISOR_H */
|
||||
189
arch/x86/include/asm/xen/interface.h
Normal file
189
arch/x86/include/asm/xen/interface.h
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
/******************************************************************************
|
||||
* arch-x86_32.h
|
||||
*
|
||||
* Guest OS interface to x86 Xen.
|
||||
*
|
||||
* Copyright (c) 2004, K A Fraser
|
||||
*/
|
||||
|
||||
#ifndef _ASM_X86_XEN_INTERFACE_H
|
||||
#define _ASM_X86_XEN_INTERFACE_H
|
||||
|
||||
#ifdef __XEN__
|
||||
#define __DEFINE_GUEST_HANDLE(name, type) \
|
||||
typedef struct { type *p; } __guest_handle_ ## name
|
||||
#else
|
||||
#define __DEFINE_GUEST_HANDLE(name, type) \
|
||||
typedef type * __guest_handle_ ## name
|
||||
#endif
|
||||
|
||||
#define DEFINE_GUEST_HANDLE_STRUCT(name) \
|
||||
__DEFINE_GUEST_HANDLE(name, struct name)
|
||||
#define DEFINE_GUEST_HANDLE(name) __DEFINE_GUEST_HANDLE(name, name)
|
||||
#define GUEST_HANDLE(name) __guest_handle_ ## name
|
||||
|
||||
#ifdef __XEN__
|
||||
#if defined(__i386__)
|
||||
#define set_xen_guest_handle(hnd, val) \
|
||||
do { \
|
||||
if (sizeof(hnd) == 8) \
|
||||
*(uint64_t *)&(hnd) = 0; \
|
||||
(hnd).p = val; \
|
||||
} while (0)
|
||||
#elif defined(__x86_64__)
|
||||
#define set_xen_guest_handle(hnd, val) do { (hnd).p = val; } while (0)
|
||||
#endif
|
||||
#else
|
||||
#if defined(__i386__)
|
||||
#define set_xen_guest_handle(hnd, val) \
|
||||
do { \
|
||||
if (sizeof(hnd) == 8) \
|
||||
*(uint64_t *)&(hnd) = 0; \
|
||||
(hnd) = val; \
|
||||
} while (0)
|
||||
#elif defined(__x86_64__)
|
||||
#define set_xen_guest_handle(hnd, val) do { (hnd) = val; } while (0)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
/* Explicitly size integers that represent pfns in the public interface
|
||||
* with Xen so that on ARM we can have one ABI that works for 32 and 64
|
||||
* bit guests. */
|
||||
typedef unsigned long xen_pfn_t;
|
||||
#define PRI_xen_pfn "lx"
|
||||
typedef unsigned long xen_ulong_t;
|
||||
#define PRI_xen_ulong "lx"
|
||||
typedef long xen_long_t;
|
||||
#define PRI_xen_long "lx"
|
||||
|
||||
/* Guest handles for primitive C types. */
|
||||
__DEFINE_GUEST_HANDLE(uchar, unsigned char);
|
||||
__DEFINE_GUEST_HANDLE(uint, unsigned int);
|
||||
DEFINE_GUEST_HANDLE(char);
|
||||
DEFINE_GUEST_HANDLE(int);
|
||||
DEFINE_GUEST_HANDLE(void);
|
||||
DEFINE_GUEST_HANDLE(uint64_t);
|
||||
DEFINE_GUEST_HANDLE(uint32_t);
|
||||
DEFINE_GUEST_HANDLE(xen_pfn_t);
|
||||
DEFINE_GUEST_HANDLE(xen_ulong_t);
|
||||
#endif
|
||||
|
||||
#ifndef HYPERVISOR_VIRT_START
|
||||
#define HYPERVISOR_VIRT_START mk_unsigned_long(__HYPERVISOR_VIRT_START)
|
||||
#endif
|
||||
|
||||
#define MACH2PHYS_VIRT_START mk_unsigned_long(__MACH2PHYS_VIRT_START)
|
||||
#define MACH2PHYS_VIRT_END mk_unsigned_long(__MACH2PHYS_VIRT_END)
|
||||
#define MACH2PHYS_NR_ENTRIES ((MACH2PHYS_VIRT_END-MACH2PHYS_VIRT_START)>>__MACH2PHYS_SHIFT)
|
||||
|
||||
/* Maximum number of virtual CPUs in multi-processor guests. */
|
||||
#define MAX_VIRT_CPUS 32
|
||||
|
||||
/*
|
||||
* SEGMENT DESCRIPTOR TABLES
|
||||
*/
|
||||
/*
|
||||
* A number of GDT entries are reserved by Xen. These are not situated at the
|
||||
* start of the GDT because some stupid OSes export hard-coded selector values
|
||||
* in their ABI. These hard-coded values are always near the start of the GDT,
|
||||
* so Xen places itself out of the way, at the far end of the GDT.
|
||||
*/
|
||||
#define FIRST_RESERVED_GDT_PAGE 14
|
||||
#define FIRST_RESERVED_GDT_BYTE (FIRST_RESERVED_GDT_PAGE * 4096)
|
||||
#define FIRST_RESERVED_GDT_ENTRY (FIRST_RESERVED_GDT_BYTE / 8)
|
||||
|
||||
/*
|
||||
* Send an array of these to HYPERVISOR_set_trap_table()
|
||||
* The privilege level specifies which modes may enter a trap via a software
|
||||
* interrupt. On x86/64, since rings 1 and 2 are unavailable, we allocate
|
||||
* privilege levels as follows:
|
||||
* Level == 0: No one may enter
|
||||
* Level == 1: Kernel may enter
|
||||
* Level == 2: Kernel may enter
|
||||
* Level == 3: Everyone may enter
|
||||
*/
|
||||
#define TI_GET_DPL(_ti) ((_ti)->flags & 3)
|
||||
#define TI_GET_IF(_ti) ((_ti)->flags & 4)
|
||||
#define TI_SET_DPL(_ti, _dpl) ((_ti)->flags |= (_dpl))
|
||||
#define TI_SET_IF(_ti, _if) ((_ti)->flags |= ((!!(_if))<<2))
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
struct trap_info {
|
||||
uint8_t vector; /* exception vector */
|
||||
uint8_t flags; /* 0-3: privilege level; 4: clear event enable? */
|
||||
uint16_t cs; /* code selector */
|
||||
unsigned long address; /* code offset */
|
||||
};
|
||||
DEFINE_GUEST_HANDLE_STRUCT(trap_info);
|
||||
|
||||
struct arch_shared_info {
|
||||
unsigned long max_pfn; /* max pfn that appears in table */
|
||||
/* Frame containing list of mfns containing list of mfns containing p2m. */
|
||||
unsigned long pfn_to_mfn_frame_list_list;
|
||||
unsigned long nmi_reason;
|
||||
};
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
#include <asm/xen/interface_32.h>
|
||||
#else
|
||||
#include <asm/xen/interface_64.h>
|
||||
#endif
|
||||
|
||||
#include <asm/pvclock-abi.h>
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
/*
|
||||
* The following is all CPU context. Note that the fpu_ctxt block is filled
|
||||
* in by FXSAVE if the CPU has feature FXSR; otherwise FSAVE is used.
|
||||
*/
|
||||
struct vcpu_guest_context {
|
||||
/* FPU registers come first so they can be aligned for FXSAVE/FXRSTOR. */
|
||||
struct { char x[512]; } fpu_ctxt; /* User-level FPU registers */
|
||||
#define VGCF_I387_VALID (1<<0)
|
||||
#define VGCF_HVM_GUEST (1<<1)
|
||||
#define VGCF_IN_KERNEL (1<<2)
|
||||
unsigned long flags; /* VGCF_* flags */
|
||||
struct cpu_user_regs user_regs; /* User-level CPU registers */
|
||||
struct trap_info trap_ctxt[256]; /* Virtual IDT */
|
||||
unsigned long ldt_base, ldt_ents; /* LDT (linear address, # ents) */
|
||||
unsigned long gdt_frames[16], gdt_ents; /* GDT (machine frames, # ents) */
|
||||
unsigned long kernel_ss, kernel_sp; /* Virtual TSS (only SS1/SP1) */
|
||||
/* NB. User pagetable on x86/64 is placed in ctrlreg[1]. */
|
||||
unsigned long ctrlreg[8]; /* CR0-CR7 (control registers) */
|
||||
unsigned long debugreg[8]; /* DB0-DB7 (debug registers) */
|
||||
#ifdef __i386__
|
||||
unsigned long event_callback_cs; /* CS:EIP of event callback */
|
||||
unsigned long event_callback_eip;
|
||||
unsigned long failsafe_callback_cs; /* CS:EIP of failsafe callback */
|
||||
unsigned long failsafe_callback_eip;
|
||||
#else
|
||||
unsigned long event_callback_eip;
|
||||
unsigned long failsafe_callback_eip;
|
||||
unsigned long syscall_callback_eip;
|
||||
#endif
|
||||
unsigned long vm_assist; /* VMASST_TYPE_* bitmap */
|
||||
#ifdef __x86_64__
|
||||
/* Segment base addresses. */
|
||||
uint64_t fs_base;
|
||||
uint64_t gs_base_kernel;
|
||||
uint64_t gs_base_user;
|
||||
#endif
|
||||
};
|
||||
DEFINE_GUEST_HANDLE_STRUCT(vcpu_guest_context);
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
/*
|
||||
* Prefix forces emulation of some non-trapping instructions.
|
||||
* Currently only CPUID.
|
||||
*/
|
||||
#ifdef __ASSEMBLY__
|
||||
#define XEN_EMULATE_PREFIX .byte 0x0f,0x0b,0x78,0x65,0x6e ;
|
||||
#define XEN_CPUID XEN_EMULATE_PREFIX cpuid
|
||||
#else
|
||||
#define XEN_EMULATE_PREFIX ".byte 0x0f,0x0b,0x78,0x65,0x6e ; "
|
||||
#define XEN_CPUID XEN_EMULATE_PREFIX "cpuid"
|
||||
#endif
|
||||
|
||||
#endif /* _ASM_X86_XEN_INTERFACE_H */
|
||||
102
arch/x86/include/asm/xen/interface_32.h
Normal file
102
arch/x86/include/asm/xen/interface_32.h
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
/******************************************************************************
|
||||
* arch-x86_32.h
|
||||
*
|
||||
* Guest OS interface to x86 32-bit Xen.
|
||||
*
|
||||
* Copyright (c) 2004, K A Fraser
|
||||
*/
|
||||
|
||||
#ifndef _ASM_X86_XEN_INTERFACE_32_H
|
||||
#define _ASM_X86_XEN_INTERFACE_32_H
|
||||
|
||||
|
||||
/*
|
||||
* These flat segments are in the Xen-private section of every GDT. Since these
|
||||
* are also present in the initial GDT, many OSes will be able to avoid
|
||||
* installing their own GDT.
|
||||
*/
|
||||
#define FLAT_RING1_CS 0xe019 /* GDT index 259 */
|
||||
#define FLAT_RING1_DS 0xe021 /* GDT index 260 */
|
||||
#define FLAT_RING1_SS 0xe021 /* GDT index 260 */
|
||||
#define FLAT_RING3_CS 0xe02b /* GDT index 261 */
|
||||
#define FLAT_RING3_DS 0xe033 /* GDT index 262 */
|
||||
#define FLAT_RING3_SS 0xe033 /* GDT index 262 */
|
||||
|
||||
#define FLAT_KERNEL_CS FLAT_RING1_CS
|
||||
#define FLAT_KERNEL_DS FLAT_RING1_DS
|
||||
#define FLAT_KERNEL_SS FLAT_RING1_SS
|
||||
#define FLAT_USER_CS FLAT_RING3_CS
|
||||
#define FLAT_USER_DS FLAT_RING3_DS
|
||||
#define FLAT_USER_SS FLAT_RING3_SS
|
||||
|
||||
/* And the trap vector is... */
|
||||
#define TRAP_INSTR "int $0x82"
|
||||
|
||||
#define __MACH2PHYS_VIRT_START 0xF5800000
|
||||
#define __MACH2PHYS_VIRT_END 0xF6800000
|
||||
|
||||
#define __MACH2PHYS_SHIFT 2
|
||||
|
||||
/*
|
||||
* Virtual addresses beyond this are not modifiable by guest OSes. The
|
||||
* machine->physical mapping table starts at this address, read-only.
|
||||
*/
|
||||
#define __HYPERVISOR_VIRT_START 0xF5800000
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
struct cpu_user_regs {
|
||||
uint32_t ebx;
|
||||
uint32_t ecx;
|
||||
uint32_t edx;
|
||||
uint32_t esi;
|
||||
uint32_t edi;
|
||||
uint32_t ebp;
|
||||
uint32_t eax;
|
||||
uint16_t error_code; /* private */
|
||||
uint16_t entry_vector; /* private */
|
||||
uint32_t eip;
|
||||
uint16_t cs;
|
||||
uint8_t saved_upcall_mask;
|
||||
uint8_t _pad0;
|
||||
uint32_t eflags; /* eflags.IF == !saved_upcall_mask */
|
||||
uint32_t esp;
|
||||
uint16_t ss, _pad1;
|
||||
uint16_t es, _pad2;
|
||||
uint16_t ds, _pad3;
|
||||
uint16_t fs, _pad4;
|
||||
uint16_t gs, _pad5;
|
||||
};
|
||||
DEFINE_GUEST_HANDLE_STRUCT(cpu_user_regs);
|
||||
|
||||
typedef uint64_t tsc_timestamp_t; /* RDTSC timestamp */
|
||||
|
||||
struct arch_vcpu_info {
|
||||
unsigned long cr2;
|
||||
unsigned long pad[5]; /* sizeof(struct vcpu_info) == 64 */
|
||||
};
|
||||
|
||||
struct xen_callback {
|
||||
unsigned long cs;
|
||||
unsigned long eip;
|
||||
};
|
||||
typedef struct xen_callback xen_callback_t;
|
||||
|
||||
#define XEN_CALLBACK(__cs, __eip) \
|
||||
((struct xen_callback){ .cs = (__cs), .eip = (unsigned long)(__eip) })
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
|
||||
/*
|
||||
* Page-directory addresses above 4GB do not fit into architectural %cr3.
|
||||
* When accessing %cr3, or equivalent field in vcpu_guest_context, guests
|
||||
* must use the following accessor macros to pack/unpack valid MFNs.
|
||||
*
|
||||
* Note that Xen is using the fact that the pagetable base is always
|
||||
* page-aligned, and putting the 12 MSB of the address into the 12 LSB
|
||||
* of cr3.
|
||||
*/
|
||||
#define xen_pfn_to_cr3(pfn) (((unsigned)(pfn) << 12) | ((unsigned)(pfn) >> 20))
|
||||
#define xen_cr3_to_pfn(cr3) (((unsigned)(cr3) >> 12) | ((unsigned)(cr3) << 20))
|
||||
|
||||
#endif /* _ASM_X86_XEN_INTERFACE_32_H */
|
||||
148
arch/x86/include/asm/xen/interface_64.h
Normal file
148
arch/x86/include/asm/xen/interface_64.h
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
#ifndef _ASM_X86_XEN_INTERFACE_64_H
|
||||
#define _ASM_X86_XEN_INTERFACE_64_H
|
||||
|
||||
/*
|
||||
* 64-bit segment selectors
|
||||
* These flat segments are in the Xen-private section of every GDT. Since these
|
||||
* are also present in the initial GDT, many OSes will be able to avoid
|
||||
* installing their own GDT.
|
||||
*/
|
||||
|
||||
#define FLAT_RING3_CS32 0xe023 /* GDT index 260 */
|
||||
#define FLAT_RING3_CS64 0xe033 /* GDT index 261 */
|
||||
#define FLAT_RING3_DS32 0xe02b /* GDT index 262 */
|
||||
#define FLAT_RING3_DS64 0x0000 /* NULL selector */
|
||||
#define FLAT_RING3_SS32 0xe02b /* GDT index 262 */
|
||||
#define FLAT_RING3_SS64 0xe02b /* GDT index 262 */
|
||||
|
||||
#define FLAT_KERNEL_DS64 FLAT_RING3_DS64
|
||||
#define FLAT_KERNEL_DS32 FLAT_RING3_DS32
|
||||
#define FLAT_KERNEL_DS FLAT_KERNEL_DS64
|
||||
#define FLAT_KERNEL_CS64 FLAT_RING3_CS64
|
||||
#define FLAT_KERNEL_CS32 FLAT_RING3_CS32
|
||||
#define FLAT_KERNEL_CS FLAT_KERNEL_CS64
|
||||
#define FLAT_KERNEL_SS64 FLAT_RING3_SS64
|
||||
#define FLAT_KERNEL_SS32 FLAT_RING3_SS32
|
||||
#define FLAT_KERNEL_SS FLAT_KERNEL_SS64
|
||||
|
||||
#define FLAT_USER_DS64 FLAT_RING3_DS64
|
||||
#define FLAT_USER_DS32 FLAT_RING3_DS32
|
||||
#define FLAT_USER_DS FLAT_USER_DS64
|
||||
#define FLAT_USER_CS64 FLAT_RING3_CS64
|
||||
#define FLAT_USER_CS32 FLAT_RING3_CS32
|
||||
#define FLAT_USER_CS FLAT_USER_CS64
|
||||
#define FLAT_USER_SS64 FLAT_RING3_SS64
|
||||
#define FLAT_USER_SS32 FLAT_RING3_SS32
|
||||
#define FLAT_USER_SS FLAT_USER_SS64
|
||||
|
||||
#define __HYPERVISOR_VIRT_START 0xFFFF800000000000
|
||||
#define __HYPERVISOR_VIRT_END 0xFFFF880000000000
|
||||
#define __MACH2PHYS_VIRT_START 0xFFFF800000000000
|
||||
#define __MACH2PHYS_VIRT_END 0xFFFF804000000000
|
||||
#define __MACH2PHYS_SHIFT 3
|
||||
|
||||
/*
|
||||
* int HYPERVISOR_set_segment_base(unsigned int which, unsigned long base)
|
||||
* @which == SEGBASE_* ; @base == 64-bit base address
|
||||
* Returns 0 on success.
|
||||
*/
|
||||
#define SEGBASE_FS 0
|
||||
#define SEGBASE_GS_USER 1
|
||||
#define SEGBASE_GS_KERNEL 2
|
||||
#define SEGBASE_GS_USER_SEL 3 /* Set user %gs specified in base[15:0] */
|
||||
|
||||
/*
|
||||
* int HYPERVISOR_iret(void)
|
||||
* All arguments are on the kernel stack, in the following format.
|
||||
* Never returns if successful. Current kernel context is lost.
|
||||
* The saved CS is mapped as follows:
|
||||
* RING0 -> RING3 kernel mode.
|
||||
* RING1 -> RING3 kernel mode.
|
||||
* RING2 -> RING3 kernel mode.
|
||||
* RING3 -> RING3 user mode.
|
||||
* However RING0 indicates that the guest kernel should return to iteself
|
||||
* directly with
|
||||
* orb $3,1*8(%rsp)
|
||||
* iretq
|
||||
* If flags contains VGCF_in_syscall:
|
||||
* Restore RAX, RIP, RFLAGS, RSP.
|
||||
* Discard R11, RCX, CS, SS.
|
||||
* Otherwise:
|
||||
* Restore RAX, R11, RCX, CS:RIP, RFLAGS, SS:RSP.
|
||||
* All other registers are saved on hypercall entry and restored to user.
|
||||
*/
|
||||
/* Guest exited in SYSCALL context? Return to guest with SYSRET? */
|
||||
#define _VGCF_in_syscall 8
|
||||
#define VGCF_in_syscall (1<<_VGCF_in_syscall)
|
||||
#define VGCF_IN_SYSCALL VGCF_in_syscall
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
struct iret_context {
|
||||
/* Top of stack (%rsp at point of hypercall). */
|
||||
uint64_t rax, r11, rcx, flags, rip, cs, rflags, rsp, ss;
|
||||
/* Bottom of iret stack frame. */
|
||||
};
|
||||
|
||||
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
|
||||
/* Anonymous union includes both 32- and 64-bit names (e.g., eax/rax). */
|
||||
#define __DECL_REG(name) union { \
|
||||
uint64_t r ## name, e ## name; \
|
||||
uint32_t _e ## name; \
|
||||
}
|
||||
#else
|
||||
/* Non-gcc sources must always use the proper 64-bit name (e.g., rax). */
|
||||
#define __DECL_REG(name) uint64_t r ## name
|
||||
#endif
|
||||
|
||||
struct cpu_user_regs {
|
||||
uint64_t r15;
|
||||
uint64_t r14;
|
||||
uint64_t r13;
|
||||
uint64_t r12;
|
||||
__DECL_REG(bp);
|
||||
__DECL_REG(bx);
|
||||
uint64_t r11;
|
||||
uint64_t r10;
|
||||
uint64_t r9;
|
||||
uint64_t r8;
|
||||
__DECL_REG(ax);
|
||||
__DECL_REG(cx);
|
||||
__DECL_REG(dx);
|
||||
__DECL_REG(si);
|
||||
__DECL_REG(di);
|
||||
uint32_t error_code; /* private */
|
||||
uint32_t entry_vector; /* private */
|
||||
__DECL_REG(ip);
|
||||
uint16_t cs, _pad0[1];
|
||||
uint8_t saved_upcall_mask;
|
||||
uint8_t _pad1[3];
|
||||
__DECL_REG(flags); /* rflags.IF == !saved_upcall_mask */
|
||||
__DECL_REG(sp);
|
||||
uint16_t ss, _pad2[3];
|
||||
uint16_t es, _pad3[3];
|
||||
uint16_t ds, _pad4[3];
|
||||
uint16_t fs, _pad5[3]; /* Non-zero => takes precedence over fs_base. */
|
||||
uint16_t gs, _pad6[3]; /* Non-zero => takes precedence over gs_base_usr. */
|
||||
};
|
||||
DEFINE_GUEST_HANDLE_STRUCT(cpu_user_regs);
|
||||
|
||||
#undef __DECL_REG
|
||||
|
||||
#define xen_pfn_to_cr3(pfn) ((unsigned long)(pfn) << 12)
|
||||
#define xen_cr3_to_pfn(cr3) ((unsigned long)(cr3) >> 12)
|
||||
|
||||
struct arch_vcpu_info {
|
||||
unsigned long cr2;
|
||||
unsigned long pad; /* sizeof(vcpu_info_t) == 64 */
|
||||
};
|
||||
|
||||
typedef unsigned long xen_callback_t;
|
||||
|
||||
#define XEN_CALLBACK(__cs, __rip) \
|
||||
((unsigned long)(__rip))
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
|
||||
#endif /* _ASM_X86_XEN_INTERFACE_64_H */
|
||||
38
arch/x86/include/asm/xen/page-coherent.h
Normal file
38
arch/x86/include/asm/xen/page-coherent.h
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
#ifndef _ASM_X86_XEN_PAGE_COHERENT_H
|
||||
#define _ASM_X86_XEN_PAGE_COHERENT_H
|
||||
|
||||
#include <asm/page.h>
|
||||
#include <linux/dma-attrs.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
|
||||
static inline void *xen_alloc_coherent_pages(struct device *hwdev, size_t size,
|
||||
dma_addr_t *dma_handle, gfp_t flags,
|
||||
struct dma_attrs *attrs)
|
||||
{
|
||||
void *vstart = (void*)__get_free_pages(flags, get_order(size));
|
||||
*dma_handle = virt_to_phys(vstart);
|
||||
return vstart;
|
||||
}
|
||||
|
||||
static inline void xen_free_coherent_pages(struct device *hwdev, size_t size,
|
||||
void *cpu_addr, dma_addr_t dma_handle,
|
||||
struct dma_attrs *attrs)
|
||||
{
|
||||
free_pages((unsigned long) cpu_addr, get_order(size));
|
||||
}
|
||||
|
||||
static inline void xen_dma_map_page(struct device *hwdev, struct page *page,
|
||||
unsigned long offset, size_t size, enum dma_data_direction dir,
|
||||
struct dma_attrs *attrs) { }
|
||||
|
||||
static inline void xen_dma_unmap_page(struct device *hwdev, dma_addr_t handle,
|
||||
size_t size, enum dma_data_direction dir,
|
||||
struct dma_attrs *attrs) { }
|
||||
|
||||
static inline void xen_dma_sync_single_for_cpu(struct device *hwdev,
|
||||
dma_addr_t handle, size_t size, enum dma_data_direction dir) { }
|
||||
|
||||
static inline void xen_dma_sync_single_for_device(struct device *hwdev,
|
||||
dma_addr_t handle, size_t size, enum dma_data_direction dir) { }
|
||||
|
||||
#endif /* _ASM_X86_XEN_PAGE_COHERENT_H */
|
||||
246
arch/x86/include/asm/xen/page.h
Normal file
246
arch/x86/include/asm/xen/page.h
Normal file
|
|
@ -0,0 +1,246 @@
|
|||
#ifndef _ASM_X86_XEN_PAGE_H
|
||||
#define _ASM_X86_XEN_PAGE_H
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/pfn.h>
|
||||
#include <linux/mm.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/pgtable.h>
|
||||
|
||||
#include <xen/interface/xen.h>
|
||||
#include <xen/grant_table.h>
|
||||
#include <xen/features.h>
|
||||
|
||||
/* Xen machine address */
|
||||
typedef struct xmaddr {
|
||||
phys_addr_t maddr;
|
||||
} xmaddr_t;
|
||||
|
||||
/* Xen pseudo-physical address */
|
||||
typedef struct xpaddr {
|
||||
phys_addr_t paddr;
|
||||
} xpaddr_t;
|
||||
|
||||
#define XMADDR(x) ((xmaddr_t) { .maddr = (x) })
|
||||
#define XPADDR(x) ((xpaddr_t) { .paddr = (x) })
|
||||
|
||||
/**** MACHINE <-> PHYSICAL CONVERSION MACROS ****/
|
||||
#define INVALID_P2M_ENTRY (~0UL)
|
||||
#define FOREIGN_FRAME_BIT (1UL<<(BITS_PER_LONG-1))
|
||||
#define IDENTITY_FRAME_BIT (1UL<<(BITS_PER_LONG-2))
|
||||
#define FOREIGN_FRAME(m) ((m) | FOREIGN_FRAME_BIT)
|
||||
#define IDENTITY_FRAME(m) ((m) | IDENTITY_FRAME_BIT)
|
||||
|
||||
/* Maximum amount of memory we can handle in a domain in pages */
|
||||
#define MAX_DOMAIN_PAGES \
|
||||
((unsigned long)((u64)CONFIG_XEN_MAX_DOMAIN_MEMORY * 1024 * 1024 * 1024 / PAGE_SIZE))
|
||||
|
||||
extern unsigned long *machine_to_phys_mapping;
|
||||
extern unsigned long machine_to_phys_nr;
|
||||
|
||||
extern unsigned long get_phys_to_machine(unsigned long pfn);
|
||||
extern bool set_phys_to_machine(unsigned long pfn, unsigned long mfn);
|
||||
extern bool __init early_set_phys_to_machine(unsigned long pfn, unsigned long mfn);
|
||||
extern bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn);
|
||||
extern unsigned long set_phys_range_identity(unsigned long pfn_s,
|
||||
unsigned long pfn_e);
|
||||
|
||||
extern int set_foreign_p2m_mapping(struct gnttab_map_grant_ref *map_ops,
|
||||
struct gnttab_map_grant_ref *kmap_ops,
|
||||
struct page **pages, unsigned int count);
|
||||
extern int m2p_add_override(unsigned long mfn, struct page *page,
|
||||
struct gnttab_map_grant_ref *kmap_op);
|
||||
extern int clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops,
|
||||
struct gnttab_map_grant_ref *kmap_ops,
|
||||
struct page **pages, unsigned int count);
|
||||
extern int m2p_remove_override(struct page *page,
|
||||
struct gnttab_map_grant_ref *kmap_op,
|
||||
unsigned long mfn);
|
||||
extern struct page *m2p_find_override(unsigned long mfn);
|
||||
extern unsigned long m2p_find_override_pfn(unsigned long mfn, unsigned long pfn);
|
||||
|
||||
static inline unsigned long pfn_to_mfn(unsigned long pfn)
|
||||
{
|
||||
unsigned long mfn;
|
||||
|
||||
if (xen_feature(XENFEAT_auto_translated_physmap))
|
||||
return pfn;
|
||||
|
||||
mfn = get_phys_to_machine(pfn);
|
||||
|
||||
if (mfn != INVALID_P2M_ENTRY)
|
||||
mfn &= ~(FOREIGN_FRAME_BIT | IDENTITY_FRAME_BIT);
|
||||
|
||||
return mfn;
|
||||
}
|
||||
|
||||
static inline int phys_to_machine_mapping_valid(unsigned long pfn)
|
||||
{
|
||||
if (xen_feature(XENFEAT_auto_translated_physmap))
|
||||
return 1;
|
||||
|
||||
return get_phys_to_machine(pfn) != INVALID_P2M_ENTRY;
|
||||
}
|
||||
|
||||
static inline unsigned long mfn_to_pfn_no_overrides(unsigned long mfn)
|
||||
{
|
||||
unsigned long pfn;
|
||||
int ret;
|
||||
|
||||
if (xen_feature(XENFEAT_auto_translated_physmap))
|
||||
return mfn;
|
||||
|
||||
if (unlikely(mfn >= machine_to_phys_nr))
|
||||
return ~0;
|
||||
|
||||
/*
|
||||
* The array access can fail (e.g., device space beyond end of RAM).
|
||||
* In such cases it doesn't matter what we return (we return garbage),
|
||||
* but we must handle the fault without crashing!
|
||||
*/
|
||||
ret = __get_user(pfn, &machine_to_phys_mapping[mfn]);
|
||||
if (ret < 0)
|
||||
return ~0;
|
||||
|
||||
return pfn;
|
||||
}
|
||||
|
||||
static inline unsigned long mfn_to_pfn(unsigned long mfn)
|
||||
{
|
||||
unsigned long pfn;
|
||||
|
||||
if (xen_feature(XENFEAT_auto_translated_physmap))
|
||||
return mfn;
|
||||
|
||||
pfn = mfn_to_pfn_no_overrides(mfn);
|
||||
if (get_phys_to_machine(pfn) != mfn) {
|
||||
/*
|
||||
* If this appears to be a foreign mfn (because the pfn
|
||||
* doesn't map back to the mfn), then check the local override
|
||||
* table to see if there's a better pfn to use.
|
||||
*
|
||||
* m2p_find_override_pfn returns ~0 if it doesn't find anything.
|
||||
*/
|
||||
pfn = m2p_find_override_pfn(mfn, ~0);
|
||||
}
|
||||
|
||||
/*
|
||||
* pfn is ~0 if there are no entries in the m2p for mfn or if the
|
||||
* entry doesn't map back to the mfn and m2p_override doesn't have a
|
||||
* valid entry for it.
|
||||
*/
|
||||
if (pfn == ~0 &&
|
||||
get_phys_to_machine(mfn) == IDENTITY_FRAME(mfn))
|
||||
pfn = mfn;
|
||||
|
||||
return pfn;
|
||||
}
|
||||
|
||||
static inline xmaddr_t phys_to_machine(xpaddr_t phys)
|
||||
{
|
||||
unsigned offset = phys.paddr & ~PAGE_MASK;
|
||||
return XMADDR(PFN_PHYS(pfn_to_mfn(PFN_DOWN(phys.paddr))) | offset);
|
||||
}
|
||||
|
||||
static inline xpaddr_t machine_to_phys(xmaddr_t machine)
|
||||
{
|
||||
unsigned offset = machine.maddr & ~PAGE_MASK;
|
||||
return XPADDR(PFN_PHYS(mfn_to_pfn(PFN_DOWN(machine.maddr))) | offset);
|
||||
}
|
||||
|
||||
/*
|
||||
* We detect special mappings in one of two ways:
|
||||
* 1. If the MFN is an I/O page then Xen will set the m2p entry
|
||||
* to be outside our maximum possible pseudophys range.
|
||||
* 2. If the MFN belongs to a different domain then we will certainly
|
||||
* not have MFN in our p2m table. Conversely, if the page is ours,
|
||||
* then we'll have p2m(m2p(MFN))==MFN.
|
||||
* If we detect a special mapping then it doesn't have a 'struct page'.
|
||||
* We force !pfn_valid() by returning an out-of-range pointer.
|
||||
*
|
||||
* NB. These checks require that, for any MFN that is not in our reservation,
|
||||
* there is no PFN such that p2m(PFN) == MFN. Otherwise we can get confused if
|
||||
* we are foreign-mapping the MFN, and the other domain as m2p(MFN) == PFN.
|
||||
* Yikes! Various places must poke in INVALID_P2M_ENTRY for safety.
|
||||
*
|
||||
* NB2. When deliberately mapping foreign pages into the p2m table, you *must*
|
||||
* use FOREIGN_FRAME(). This will cause pte_pfn() to choke on it, as we
|
||||
* require. In all the cases we care about, the FOREIGN_FRAME bit is
|
||||
* masked (e.g., pfn_to_mfn()) so behaviour there is correct.
|
||||
*/
|
||||
static inline unsigned long mfn_to_local_pfn(unsigned long mfn)
|
||||
{
|
||||
unsigned long pfn;
|
||||
|
||||
if (xen_feature(XENFEAT_auto_translated_physmap))
|
||||
return mfn;
|
||||
|
||||
pfn = mfn_to_pfn(mfn);
|
||||
if (get_phys_to_machine(pfn) != mfn)
|
||||
return -1; /* force !pfn_valid() */
|
||||
return pfn;
|
||||
}
|
||||
|
||||
/* VIRT <-> MACHINE conversion */
|
||||
#define virt_to_machine(v) (phys_to_machine(XPADDR(__pa(v))))
|
||||
#define virt_to_pfn(v) (PFN_DOWN(__pa(v)))
|
||||
#define virt_to_mfn(v) (pfn_to_mfn(virt_to_pfn(v)))
|
||||
#define mfn_to_virt(m) (__va(mfn_to_pfn(m) << PAGE_SHIFT))
|
||||
|
||||
static inline unsigned long pte_mfn(pte_t pte)
|
||||
{
|
||||
return (pte.pte & PTE_PFN_MASK) >> PAGE_SHIFT;
|
||||
}
|
||||
|
||||
static inline pte_t mfn_pte(unsigned long page_nr, pgprot_t pgprot)
|
||||
{
|
||||
pte_t pte;
|
||||
|
||||
pte.pte = ((phys_addr_t)page_nr << PAGE_SHIFT) |
|
||||
massage_pgprot(pgprot);
|
||||
|
||||
return pte;
|
||||
}
|
||||
|
||||
static inline pteval_t pte_val_ma(pte_t pte)
|
||||
{
|
||||
return pte.pte;
|
||||
}
|
||||
|
||||
static inline pte_t __pte_ma(pteval_t x)
|
||||
{
|
||||
return (pte_t) { .pte = x };
|
||||
}
|
||||
|
||||
#define pmd_val_ma(v) ((v).pmd)
|
||||
#ifdef __PAGETABLE_PUD_FOLDED
|
||||
#define pud_val_ma(v) ((v).pgd.pgd)
|
||||
#else
|
||||
#define pud_val_ma(v) ((v).pud)
|
||||
#endif
|
||||
#define __pmd_ma(x) ((pmd_t) { (x) } )
|
||||
|
||||
#define pgd_val_ma(x) ((x).pgd)
|
||||
|
||||
void xen_set_domain_pte(pte_t *ptep, pte_t pteval, unsigned domid);
|
||||
|
||||
xmaddr_t arbitrary_virt_to_machine(void *address);
|
||||
unsigned long arbitrary_virt_to_mfn(void *vaddr);
|
||||
void make_lowmem_page_readonly(void *vaddr);
|
||||
void make_lowmem_page_readwrite(void *vaddr);
|
||||
|
||||
#define xen_remap(cookie, size) ioremap((cookie), (size));
|
||||
#define xen_unmap(cookie) iounmap((cookie))
|
||||
|
||||
static inline bool xen_arch_need_swiotlb(struct device *dev,
|
||||
unsigned long pfn,
|
||||
unsigned long mfn)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif /* _ASM_X86_XEN_PAGE_H */
|
||||
82
arch/x86/include/asm/xen/pci.h
Normal file
82
arch/x86/include/asm/xen/pci.h
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
#ifndef _ASM_X86_XEN_PCI_H
|
||||
#define _ASM_X86_XEN_PCI_H
|
||||
|
||||
#if defined(CONFIG_PCI_XEN)
|
||||
extern int __init pci_xen_init(void);
|
||||
extern int __init pci_xen_hvm_init(void);
|
||||
#define pci_xen 1
|
||||
#else
|
||||
#define pci_xen 0
|
||||
#define pci_xen_init (0)
|
||||
static inline int pci_xen_hvm_init(void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
#if defined(CONFIG_XEN_DOM0)
|
||||
int __init pci_xen_initial_domain(void);
|
||||
int xen_find_device_domain_owner(struct pci_dev *dev);
|
||||
int xen_register_device_domain_owner(struct pci_dev *dev, uint16_t domain);
|
||||
int xen_unregister_device_domain_owner(struct pci_dev *dev);
|
||||
#else
|
||||
static inline int __init pci_xen_initial_domain(void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
static inline int xen_find_device_domain_owner(struct pci_dev *dev)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
static inline int xen_register_device_domain_owner(struct pci_dev *dev,
|
||||
uint16_t domain)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
static inline int xen_unregister_device_domain_owner(struct pci_dev *dev)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_PCI_MSI)
|
||||
#if defined(CONFIG_PCI_XEN)
|
||||
/* The drivers/pci/xen-pcifront.c sets this structure to
|
||||
* its own functions.
|
||||
*/
|
||||
struct xen_pci_frontend_ops {
|
||||
int (*enable_msi)(struct pci_dev *dev, int vectors[]);
|
||||
void (*disable_msi)(struct pci_dev *dev);
|
||||
int (*enable_msix)(struct pci_dev *dev, int vectors[], int nvec);
|
||||
void (*disable_msix)(struct pci_dev *dev);
|
||||
};
|
||||
|
||||
extern struct xen_pci_frontend_ops *xen_pci_frontend;
|
||||
|
||||
static inline int xen_pci_frontend_enable_msi(struct pci_dev *dev,
|
||||
int vectors[])
|
||||
{
|
||||
if (xen_pci_frontend && xen_pci_frontend->enable_msi)
|
||||
return xen_pci_frontend->enable_msi(dev, vectors);
|
||||
return -ENODEV;
|
||||
}
|
||||
static inline void xen_pci_frontend_disable_msi(struct pci_dev *dev)
|
||||
{
|
||||
if (xen_pci_frontend && xen_pci_frontend->disable_msi)
|
||||
xen_pci_frontend->disable_msi(dev);
|
||||
}
|
||||
static inline int xen_pci_frontend_enable_msix(struct pci_dev *dev,
|
||||
int vectors[], int nvec)
|
||||
{
|
||||
if (xen_pci_frontend && xen_pci_frontend->enable_msix)
|
||||
return xen_pci_frontend->enable_msix(dev, vectors, nvec);
|
||||
return -ENODEV;
|
||||
}
|
||||
static inline void xen_pci_frontend_disable_msix(struct pci_dev *dev)
|
||||
{
|
||||
if (xen_pci_frontend && xen_pci_frontend->disable_msix)
|
||||
xen_pci_frontend->disable_msix(dev);
|
||||
}
|
||||
#endif /* CONFIG_PCI_XEN */
|
||||
#endif /* CONFIG_PCI_MSI */
|
||||
|
||||
#endif /* _ASM_X86_XEN_PCI_H */
|
||||
16
arch/x86/include/asm/xen/swiotlb-xen.h
Normal file
16
arch/x86/include/asm/xen/swiotlb-xen.h
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
#ifndef _ASM_X86_SWIOTLB_XEN_H
|
||||
#define _ASM_X86_SWIOTLB_XEN_H
|
||||
|
||||
#ifdef CONFIG_SWIOTLB_XEN
|
||||
extern int xen_swiotlb;
|
||||
extern int __init pci_xen_swiotlb_detect(void);
|
||||
extern void __init pci_xen_swiotlb_init(void);
|
||||
extern int pci_xen_swiotlb_init_late(void);
|
||||
#else
|
||||
#define xen_swiotlb (0)
|
||||
static inline int __init pci_xen_swiotlb_detect(void) { return 0; }
|
||||
static inline void __init pci_xen_swiotlb_init(void) { }
|
||||
static inline int pci_xen_swiotlb_init_late(void) { return -ENXIO; }
|
||||
#endif
|
||||
|
||||
#endif /* _ASM_X86_SWIOTLB_XEN_H */
|
||||
18
arch/x86/include/asm/xen/trace_types.h
Normal file
18
arch/x86/include/asm/xen/trace_types.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
#ifndef _ASM_XEN_TRACE_TYPES_H
|
||||
#define _ASM_XEN_TRACE_TYPES_H
|
||||
|
||||
enum xen_mc_flush_reason {
|
||||
XEN_MC_FL_NONE, /* explicit flush */
|
||||
XEN_MC_FL_BATCH, /* out of hypercall space */
|
||||
XEN_MC_FL_ARGS, /* out of argument space */
|
||||
XEN_MC_FL_CALLBACK, /* out of callback space */
|
||||
};
|
||||
|
||||
enum xen_mc_extend_args {
|
||||
XEN_MC_XE_OK,
|
||||
XEN_MC_XE_BAD_OP,
|
||||
XEN_MC_XE_NO_SPACE
|
||||
};
|
||||
typedef void (*xen_mc_callback_fn_t)(void *);
|
||||
|
||||
#endif /* _ASM_XEN_TRACE_TYPES_H */
|
||||
Loading…
Add table
Add a link
Reference in a new issue