Import xen sub-arch includes.
MFC after: 2 weeks
This commit is contained in:
parent
f35db5f7ca
commit
41c24a46d4
82
sys/i386/include/xen/evtchn.h
Normal file
82
sys/i386/include/xen/evtchn.h
Normal file
@ -0,0 +1,82 @@
|
||||
/******************************************************************************
|
||||
* evtchn.h
|
||||
*
|
||||
* Communication via Xen event channels.
|
||||
* Also definitions for the device that demuxes notifications to userspace.
|
||||
*
|
||||
* Copyright (c) 2004, K A Fraser
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef __ASM_EVTCHN_H__
|
||||
#define __ASM_EVTCHN_H__
|
||||
#include <machine/pcpu.h>
|
||||
#include <machine/xen/hypervisor.h>
|
||||
#include <machine/xen/synch_bitops.h>
|
||||
#include <machine/frame.h>
|
||||
|
||||
/*
|
||||
* LOW-LEVEL DEFINITIONS
|
||||
*/
|
||||
|
||||
/*
|
||||
* Unlike notify_remote_via_evtchn(), this is safe to use across
|
||||
* save/restore. Notifications on a broken connection are silently dropped.
|
||||
*/
|
||||
void notify_remote_via_irq(int irq);
|
||||
|
||||
|
||||
/* Entry point for notifications into Linux subsystems. */
|
||||
void evtchn_do_upcall(struct trapframe *frame);
|
||||
|
||||
/* Entry point for notifications into the userland character device. */
|
||||
void evtchn_device_upcall(int port);
|
||||
|
||||
void mask_evtchn(int port);
|
||||
|
||||
void unmask_evtchn(int port);
|
||||
|
||||
|
||||
|
||||
static inline void
|
||||
clear_evtchn(int port)
|
||||
{
|
||||
shared_info_t *s = HYPERVISOR_shared_info;
|
||||
synch_clear_bit(port, &s->evtchn_pending[0]);
|
||||
}
|
||||
|
||||
static inline void
|
||||
notify_remote_via_evtchn(int port)
|
||||
{
|
||||
struct evtchn_send send = { .port = port };
|
||||
(void)HYPERVISOR_event_channel_op(EVTCHNOP_send, &send);
|
||||
}
|
||||
|
||||
/*
|
||||
* Use these to access the event channel underlying the IRQ handle returned
|
||||
* by bind_*_to_irqhandler().
|
||||
*/
|
||||
int irq_to_evtchn_port(int irq);
|
||||
|
||||
|
||||
/*
|
||||
* CHARACTER-DEVICE DEFINITIONS
|
||||
*/
|
||||
|
||||
#define PORT_NORMAL 0x0000
|
||||
#define PORT_EXCEPTION 0x8000
|
||||
#define PORTIDX_MASK 0x7fff
|
||||
|
||||
/* /dev/xen/evtchn resides at device number major=10, minor=200 */
|
||||
#define EVTCHN_MINOR 200
|
||||
|
||||
/* /dev/xen/evtchn ioctls: */
|
||||
/* EVTCHN_RESET: Clear and reinit the event buffer. Clear error condition. */
|
||||
#define EVTCHN_RESET _IO('E', 1)
|
||||
/* EVTCHN_BIND: Bind to the specified event-channel port. */
|
||||
#define EVTCHN_BIND _IO('E', 2)
|
||||
/* EVTCHN_UNBIND: Unbind from the specified event-channel port. */
|
||||
#define EVTCHN_UNBIND _IO('E', 3)
|
||||
|
||||
#endif /* __ASM_EVTCHN_H__ */
|
22
sys/i386/include/xen/features.h
Normal file
22
sys/i386/include/xen/features.h
Normal file
@ -0,0 +1,22 @@
|
||||
/******************************************************************************
|
||||
* features.h
|
||||
*
|
||||
* Query the features reported by Xen.
|
||||
*
|
||||
* Copyright (c) 2006, Ian Campbell
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef __ASM_XEN_FEATURES_H__
|
||||
#define __ASM_XEN_FEATURES_H__
|
||||
|
||||
#include <xen/interface/version.h>
|
||||
|
||||
extern void setup_xen_features(void);
|
||||
|
||||
extern uint8_t xen_features[XENFEAT_NR_SUBMAPS * 32];
|
||||
|
||||
#define xen_feature(flag) (xen_features[flag])
|
||||
|
||||
#endif /* __ASM_XEN_FEATURES_H__ */
|
405
sys/i386/include/xen/hypercall.h
Normal file
405
sys/i386/include/xen/hypercall.h
Normal file
@ -0,0 +1,405 @@
|
||||
/******************************************************************************
|
||||
* hypercall.h
|
||||
*
|
||||
* Linux-specific hypervisor handling.
|
||||
*
|
||||
* Copyright (c) 2002-2004, K A Fraser
|
||||
*
|
||||
* This file may be 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 __HYPERCALL_H__
|
||||
#define __HYPERCALL_H__
|
||||
|
||||
#include <sys/systm.h>
|
||||
#include <xen/interface/xen.h>
|
||||
#include <xen/interface/sched.h>
|
||||
|
||||
#define __STR(x) #x
|
||||
#define STR(x) __STR(x)
|
||||
#define ENOXENSYS 38
|
||||
#define CONFIG_XEN_COMPAT 0x030002
|
||||
|
||||
|
||||
#if defined(XEN)
|
||||
#define HYPERCALL_STR(name) \
|
||||
"call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"
|
||||
#else
|
||||
#define HYPERCALL_STR(name) \
|
||||
"mov hypercall_stubs,%%eax; " \
|
||||
"add $("STR(__HYPERVISOR_##name)" * 32),%%eax; " \
|
||||
"call *%%eax"
|
||||
#endif
|
||||
|
||||
#define _hypercall0(type, name) \
|
||||
({ \
|
||||
long __res; \
|
||||
__asm__ volatile ( \
|
||||
HYPERCALL_STR(name) \
|
||||
: "=a" (__res) \
|
||||
: \
|
||||
: "memory" ); \
|
||||
(type)__res; \
|
||||
})
|
||||
|
||||
#define _hypercall1(type, name, a1) \
|
||||
({ \
|
||||
long __res, __ign1; \
|
||||
__asm__ volatile ( \
|
||||
HYPERCALL_STR(name) \
|
||||
: "=a" (__res), "=b" (__ign1) \
|
||||
: "1" ((long)(a1)) \
|
||||
: "memory" ); \
|
||||
(type)__res; \
|
||||
})
|
||||
|
||||
#define _hypercall2(type, name, a1, a2) \
|
||||
({ \
|
||||
long __res, __ign1, __ign2; \
|
||||
__asm__ volatile ( \
|
||||
HYPERCALL_STR(name) \
|
||||
: "=a" (__res), "=b" (__ign1), "=c" (__ign2) \
|
||||
: "1" ((long)(a1)), "2" ((long)(a2)) \
|
||||
: "memory" ); \
|
||||
(type)__res; \
|
||||
})
|
||||
|
||||
#define _hypercall3(type, name, a1, a2, a3) \
|
||||
({ \
|
||||
long __res, __ign1, __ign2, __ign3; \
|
||||
__asm__ volatile ( \
|
||||
HYPERCALL_STR(name) \
|
||||
: "=a" (__res), "=b" (__ign1), "=c" (__ign2), \
|
||||
"=d" (__ign3) \
|
||||
: "1" ((long)(a1)), "2" ((long)(a2)), \
|
||||
"3" ((long)(a3)) \
|
||||
: "memory" ); \
|
||||
(type)__res; \
|
||||
})
|
||||
|
||||
#define _hypercall4(type, name, a1, a2, a3, a4) \
|
||||
({ \
|
||||
long __res, __ign1, __ign2, __ign3, __ign4; \
|
||||
__asm__ volatile ( \
|
||||
HYPERCALL_STR(name) \
|
||||
: "=a" (__res), "=b" (__ign1), "=c" (__ign2), \
|
||||
"=d" (__ign3), "=S" (__ign4) \
|
||||
: "1" ((long)(a1)), "2" ((long)(a2)), \
|
||||
"3" ((long)(a3)), "4" ((long)(a4)) \
|
||||
: "memory" ); \
|
||||
(type)__res; \
|
||||
})
|
||||
|
||||
#define _hypercall5(type, name, a1, a2, a3, a4, a5) \
|
||||
({ \
|
||||
long __res, __ign1, __ign2, __ign3, __ign4, __ign5; \
|
||||
__asm__ volatile ( \
|
||||
HYPERCALL_STR(name) \
|
||||
: "=a" (__res), "=b" (__ign1), "=c" (__ign2), \
|
||||
"=d" (__ign3), "=S" (__ign4), "=D" (__ign5) \
|
||||
: "1" ((long)(a1)), "2" ((long)(a2)), \
|
||||
"3" ((long)(a3)), "4" ((long)(a4)), \
|
||||
"5" ((long)(a5)) \
|
||||
: "memory" ); \
|
||||
(type)__res; \
|
||||
})
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_set_trap_table(
|
||||
trap_info_t *table)
|
||||
{
|
||||
return _hypercall1(int, set_trap_table, table);
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_mmu_update(
|
||||
mmu_update_t *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(
|
||||
mmuext_op_t *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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_fpu_taskswitch(
|
||||
int set)
|
||||
{
|
||||
return _hypercall1(int, fpu_taskswitch, set);
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_sched_op_compat(
|
||||
int cmd, unsigned long arg)
|
||||
{
|
||||
return _hypercall2(int, sched_op_compat, cmd, arg);
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_sched_op(
|
||||
int cmd, void *arg)
|
||||
{
|
||||
return _hypercall2(int, sched_op, cmd, arg);
|
||||
}
|
||||
|
||||
static inline long
|
||||
HYPERVISOR_set_timer_op(
|
||||
uint64_t 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);
|
||||
}
|
||||
#if 0
|
||||
static inline int
|
||||
HYPERVISOR_platform_op(
|
||||
struct xen_platform_op *platform_op)
|
||||
{
|
||||
platform_op->interface_version = XENPF_INTERFACE_VERSION;
|
||||
return _hypercall1(int, platform_op, platform_op);
|
||||
}
|
||||
#endif
|
||||
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(
|
||||
uint64_t ma, uint64_t 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, int nr_calls)
|
||||
{
|
||||
return _hypercall2(int, multicall, call_list, nr_calls);
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_update_va_mapping(
|
||||
unsigned long va, uint64_t new_val, unsigned long flags)
|
||||
{
|
||||
uint32_t hi, lo;
|
||||
|
||||
lo = (uint32_t)(new_val & 0xffffffff);
|
||||
hi = (uint32_t)(new_val >> 32);
|
||||
|
||||
return _hypercall4(int, update_va_mapping, va,
|
||||
lo, hi, flags);
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_event_channel_op(
|
||||
int cmd, void *arg)
|
||||
{
|
||||
int rc = _hypercall2(int, event_channel_op, cmd, arg);
|
||||
|
||||
#if CONFIG_XEN_COMPAT <= 0x030002
|
||||
if (__predict_false(rc == -ENOXENSYS)) {
|
||||
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));
|
||||
}
|
||||
#endif
|
||||
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);
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_physdev_op(
|
||||
int cmd, void *arg)
|
||||
{
|
||||
int rc = _hypercall2(int, physdev_op, cmd, arg);
|
||||
#if CONFIG_XEN_COMPAT <= 0x030002
|
||||
if (__predict_false(rc == -ENOXENSYS)) {
|
||||
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));
|
||||
}
|
||||
#endif
|
||||
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, uint64_t new_val, unsigned long flags, domid_t domid)
|
||||
{
|
||||
uint32_t hi, lo;
|
||||
|
||||
lo = (uint32_t)(new_val & 0xffffffff);
|
||||
hi = (uint32_t)(new_val >> 32);
|
||||
|
||||
return _hypercall5(int, update_va_mapping_otherdomain, va,
|
||||
lo, hi, 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);
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_suspend(
|
||||
unsigned long srec)
|
||||
{
|
||||
struct sched_shutdown sched_shutdown = {
|
||||
.reason = SHUTDOWN_suspend
|
||||
};
|
||||
int rc = _hypercall3(int, sched_op, SCHEDOP_shutdown,
|
||||
&sched_shutdown, srec);
|
||||
#if CONFIG_XEN_COMPAT <= 0x030002
|
||||
if (rc == -ENOXENSYS)
|
||||
rc = _hypercall3(int, sched_op_compat, SCHEDOP_shutdown,
|
||||
SHUTDOWN_suspend, srec);
|
||||
#endif
|
||||
return (rc);
|
||||
}
|
||||
|
||||
#if CONFIG_XEN_COMPAT <= 0x030002
|
||||
static inline int
|
||||
HYPERVISOR_nmi_op(
|
||||
unsigned long op, void *arg)
|
||||
{
|
||||
return _hypercall2(int, nmi_op, op, arg);
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_callback_op(
|
||||
int cmd, void *arg)
|
||||
{
|
||||
return _hypercall2(int, callback_op, cmd, arg);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_XEN
|
||||
static inline unsigned long
|
||||
HYPERVISOR_hvm_op(
|
||||
int op, void *arg)
|
||||
{
|
||||
return _hypercall2(unsigned long, hvm_op, op, arg);
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_xenoprof_op(
|
||||
int op, void *arg)
|
||||
{
|
||||
return _hypercall2(int, xenoprof_op, op, arg);
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_kexec_op(
|
||||
unsigned long op, void *args)
|
||||
{
|
||||
return _hypercall2(int, kexec_op, op, args);
|
||||
}
|
||||
#endif /* __HYPERCALL_H__ */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* c-file-style: "linux"
|
||||
* indent-tabs-mode: t
|
||||
* c-indent-level: 8
|
||||
* c-basic-offset: 8
|
||||
* tab-width: 8
|
||||
* End:
|
||||
*/
|
143
sys/i386/include/xen/hypervisor.h
Normal file
143
sys/i386/include/xen/hypervisor.h
Normal file
@ -0,0 +1,143 @@
|
||||
/******************************************************************************
|
||||
* hypervisor.h
|
||||
*
|
||||
* Linux-specific hypervisor handling.
|
||||
*
|
||||
* Copyright (c) 2002, K A Fraser
|
||||
*/
|
||||
|
||||
#ifndef __HYPERVISOR_H__
|
||||
#define __HYPERVISOR_H__
|
||||
|
||||
#define is_running_on_xen() 1
|
||||
|
||||
#ifdef PAE
|
||||
#ifndef CONFIG_X86_PAE
|
||||
#define CONFIG_X86_PAE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/systm.h>
|
||||
#include <xen/interface/xen.h>
|
||||
#include <xen/interface/platform.h>
|
||||
#include <xen/interface/event_channel.h>
|
||||
#include <xen/interface/physdev.h>
|
||||
#include <xen/interface/sched.h>
|
||||
#include <xen/interface/callback.h>
|
||||
#include <machine/xen/hypercall.h>
|
||||
|
||||
#if defined(__amd64__)
|
||||
#define MULTI_UVMFLAGS_INDEX 2
|
||||
#define MULTI_UVMDOMID_INDEX 3
|
||||
#else
|
||||
#define MULTI_UVMFLAGS_INDEX 3
|
||||
#define MULTI_UVMDOMID_INDEX 4
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_XEN_PRIVILEGED_GUEST
|
||||
#define is_initial_xendomain() (xen_start_info->flags & SIF_INITDOMAIN)
|
||||
#else
|
||||
#define is_initial_xendomain() 0
|
||||
#endif
|
||||
|
||||
extern start_info_t *xen_start_info;
|
||||
|
||||
extern uint64_t get_system_time(int ticks);
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_console_write(char *str, int count)
|
||||
{
|
||||
return HYPERVISOR_console_io(CONSOLEIO_write, count, str);
|
||||
}
|
||||
|
||||
static inline void HYPERVISOR_crash(void) __dead2;
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_yield(void)
|
||||
{
|
||||
int rc = HYPERVISOR_sched_op(SCHEDOP_yield, NULL);
|
||||
|
||||
#if CONFIG_XEN_COMPAT <= 0x030002
|
||||
if (rc == -ENOXENSYS)
|
||||
rc = HYPERVISOR_sched_op_compat(SCHEDOP_yield, 0);
|
||||
#endif
|
||||
return (rc);
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_block(
|
||||
void)
|
||||
{
|
||||
int rc = HYPERVISOR_sched_op(SCHEDOP_block, NULL);
|
||||
|
||||
#if CONFIG_XEN_COMPAT <= 0x030002
|
||||
if (rc == -ENOXENSYS)
|
||||
rc = HYPERVISOR_sched_op_compat(SCHEDOP_block, 0);
|
||||
#endif
|
||||
return (rc);
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
HYPERVISOR_shutdown(unsigned int reason)
|
||||
{
|
||||
struct sched_shutdown sched_shutdown = {
|
||||
.reason = reason
|
||||
};
|
||||
|
||||
HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
|
||||
#if CONFIG_XEN_COMPAT <= 0x030002
|
||||
HYPERVISOR_sched_op_compat(SCHEDOP_shutdown, reason);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void
|
||||
HYPERVISOR_crash(void)
|
||||
{
|
||||
HYPERVISOR_shutdown(SHUTDOWN_crash);
|
||||
/* NEVER REACHED */
|
||||
for (;;) ; /* eliminate noreturn error */
|
||||
}
|
||||
|
||||
/* Transfer control to hypervisor until an event is detected on one */
|
||||
/* of the specified ports or the specified number of ticks elapse */
|
||||
static inline int
|
||||
HYPERVISOR_poll(
|
||||
evtchn_port_t *ports, unsigned int nr_ports, int ticks)
|
||||
{
|
||||
int rc;
|
||||
struct sched_poll sched_poll = {
|
||||
.nr_ports = nr_ports,
|
||||
.timeout = get_system_time(ticks)
|
||||
};
|
||||
set_xen_guest_handle(sched_poll.ports, ports);
|
||||
|
||||
rc = HYPERVISOR_sched_op(SCHEDOP_poll, &sched_poll);
|
||||
#if CONFIG_XEN_COMPAT <= 0x030002
|
||||
if (rc == -ENOXENSYS)
|
||||
rc = HYPERVISOR_sched_op_compat(SCHEDOP_yield, 0);
|
||||
#endif
|
||||
return (rc);
|
||||
}
|
||||
|
||||
static inline void
|
||||
MULTI_update_va_mapping(
|
||||
multicall_entry_t *mcl, unsigned long va,
|
||||
uint64_t new_val, unsigned long flags)
|
||||
{
|
||||
mcl->op = __HYPERVISOR_update_va_mapping;
|
||||
mcl->args[0] = va;
|
||||
#if defined(__amd64__)
|
||||
mcl->args[1] = new_val.pte;
|
||||
#elif defined(PAE)
|
||||
mcl->args[1] = (uint32_t)(new_val & 0xffffffff) ;
|
||||
mcl->args[2] = (uint32_t)(new_val >> 32);
|
||||
#else
|
||||
mcl->args[1] = new_val;
|
||||
mcl->args[2] = 0;
|
||||
#endif
|
||||
mcl->args[MULTI_UVMFLAGS_INDEX] = flags;
|
||||
}
|
||||
|
||||
#endif /* __HYPERVISOR_H__ */
|
139
sys/i386/include/xen/synch_bitops.h
Normal file
139
sys/i386/include/xen/synch_bitops.h
Normal file
@ -0,0 +1,139 @@
|
||||
#ifndef __XEN_SYNCH_BITOPS_H__
|
||||
#define __XEN_SYNCH_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 synch_set_bit(int nr, volatile void * addr)
|
||||
{
|
||||
__asm__ __volatile__ (
|
||||
"lock btsl %1,%0"
|
||||
: "=m" (ADDR) : "Ir" (nr) : "memory" );
|
||||
}
|
||||
|
||||
static __inline__ void synch_clear_bit(int nr, volatile void * addr)
|
||||
{
|
||||
__asm__ __volatile__ (
|
||||
"lock btrl %1,%0"
|
||||
: "=m" (ADDR) : "Ir" (nr) : "memory" );
|
||||
}
|
||||
|
||||
static __inline__ void synch_change_bit(int nr, volatile void * addr)
|
||||
{
|
||||
__asm__ __volatile__ (
|
||||
"lock btcl %1,%0"
|
||||
: "=m" (ADDR) : "Ir" (nr) : "memory" );
|
||||
}
|
||||
|
||||
static __inline__ int synch_test_and_set_bit(int nr, volatile void * addr)
|
||||
{
|
||||
int oldbit;
|
||||
__asm__ __volatile__ (
|
||||
"lock btsl %2,%1\n\tsbbl %0,%0"
|
||||
: "=r" (oldbit), "=m" (ADDR) : "Ir" (nr) : "memory");
|
||||
return oldbit;
|
||||
}
|
||||
|
||||
static __inline__ int synch_test_and_clear_bit(int nr, volatile void * addr)
|
||||
{
|
||||
int oldbit;
|
||||
__asm__ __volatile__ (
|
||||
"lock btrl %2,%1\n\tsbbl %0,%0"
|
||||
: "=r" (oldbit), "=m" (ADDR) : "Ir" (nr) : "memory");
|
||||
return oldbit;
|
||||
}
|
||||
|
||||
static __inline__ int synch_test_and_change_bit(int nr, volatile void * addr)
|
||||
{
|
||||
int oldbit;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
"lock btcl %2,%1\n\tsbbl %0,%0"
|
||||
: "=r" (oldbit), "=m" (ADDR) : "Ir" (nr) : "memory");
|
||||
return oldbit;
|
||||
}
|
||||
|
||||
struct __synch_xchg_dummy { unsigned long a[100]; };
|
||||
#define __synch_xg(x) ((volatile struct __synch_xchg_dummy *)(x))
|
||||
|
||||
#define synch_cmpxchg(ptr, old, new) \
|
||||
((__typeof__(*(ptr)))__synch_cmpxchg((ptr),\
|
||||
(unsigned long)(old), \
|
||||
(unsigned long)(new), \
|
||||
sizeof(*(ptr))))
|
||||
|
||||
static inline unsigned long __synch_cmpxchg(volatile void *ptr,
|
||||
unsigned long old,
|
||||
unsigned long new, int size)
|
||||
{
|
||||
unsigned long prev;
|
||||
switch (size) {
|
||||
case 1:
|
||||
__asm__ __volatile__("lock; cmpxchgb %b1,%2"
|
||||
: "=a"(prev)
|
||||
: "q"(new), "m"(*__synch_xg(ptr)),
|
||||
"0"(old)
|
||||
: "memory");
|
||||
return prev;
|
||||
case 2:
|
||||
__asm__ __volatile__("lock; cmpxchgw %w1,%2"
|
||||
: "=a"(prev)
|
||||
: "q"(new), "m"(*__synch_xg(ptr)),
|
||||
"0"(old)
|
||||
: "memory");
|
||||
return prev;
|
||||
#ifdef CONFIG_X86_64
|
||||
case 4:
|
||||
__asm__ __volatile__("lock; cmpxchgl %k1,%2"
|
||||
: "=a"(prev)
|
||||
: "q"(new), "m"(*__synch_xg(ptr)),
|
||||
"0"(old)
|
||||
: "memory");
|
||||
return prev;
|
||||
case 8:
|
||||
__asm__ __volatile__("lock; cmpxchgq %1,%2"
|
||||
: "=a"(prev)
|
||||
: "q"(new), "m"(*__synch_xg(ptr)),
|
||||
"0"(old)
|
||||
: "memory");
|
||||
return prev;
|
||||
#else
|
||||
case 4:
|
||||
__asm__ __volatile__("lock; cmpxchgl %1,%2"
|
||||
: "=a"(prev)
|
||||
: "q"(new), "m"(*__synch_xg(ptr)),
|
||||
"0"(old)
|
||||
: "memory");
|
||||
return prev;
|
||||
#endif
|
||||
}
|
||||
return old;
|
||||
}
|
||||
|
||||
static __inline__ int synch_const_test_bit(int nr, const volatile void * addr)
|
||||
{
|
||||
return ((1UL << (nr & 31)) &
|
||||
(((const volatile unsigned int *) addr)[nr >> 5])) != 0;
|
||||
}
|
||||
|
||||
static __inline__ int synch_var_test_bit(int nr, volatile void * addr)
|
||||
{
|
||||
int oldbit;
|
||||
__asm__ __volatile__ (
|
||||
"btl %2,%1\n\tsbbl %0,%0"
|
||||
: "=r" (oldbit) : "m" (ADDR), "Ir" (nr) );
|
||||
return oldbit;
|
||||
}
|
||||
|
||||
#define synch_test_bit(nr,addr) \
|
||||
(__builtin_constant_p(nr) ? \
|
||||
synch_const_test_bit((nr),(addr)) : \
|
||||
synch_var_test_bit((nr),(addr)))
|
||||
|
||||
#endif /* __XEN_SYNCH_BITOPS_H__ */
|
371
sys/i386/include/xen/xen-os.h
Normal file
371
sys/i386/include/xen/xen-os.h
Normal file
@ -0,0 +1,371 @@
|
||||
/******************************************************************************
|
||||
* os.h
|
||||
*
|
||||
* random collection of macros and definition
|
||||
*/
|
||||
|
||||
#ifndef _XEN_OS_H_
|
||||
#define _XEN_OS_H_
|
||||
#include <machine/param.h>
|
||||
#ifdef PAE
|
||||
#define CONFIG_X86_PAE
|
||||
#endif
|
||||
|
||||
#include <xen/interface/xen.h>
|
||||
|
||||
/* Force a proper event-channel callback from Xen. */
|
||||
void force_evtchn_callback(void);
|
||||
|
||||
#ifdef SMP
|
||||
#include <sys/time.h> /* XXX for pcpu.h */
|
||||
#include <sys/pcpu.h> /* XXX for PCPU_GET */
|
||||
extern int gdt_set;
|
||||
static inline int
|
||||
smp_processor_id(void)
|
||||
{
|
||||
if (likely(gdt_set))
|
||||
return PCPU_GET(cpuid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
#define smp_processor_id() 0
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL (void *)0
|
||||
#endif
|
||||
|
||||
#ifndef PANIC_IF
|
||||
#define PANIC_IF(exp) if (unlikely(exp)) {printk("panic - %s: %s:%d\n",#exp, __FILE__, __LINE__); panic("%s: %s:%d", #exp, __FILE__, __LINE__);}
|
||||
#endif
|
||||
|
||||
extern shared_info_t *HYPERVISOR_shared_info;
|
||||
|
||||
/* Somewhere in the middle of the GCC 2.96 development cycle, we implemented
|
||||
a mechanism by which the user can annotate likely branch directions and
|
||||
expect the blocks to be reordered appropriately. Define __builtin_expect
|
||||
to nothing for earlier compilers. */
|
||||
|
||||
/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */
|
||||
static inline void rep_nop(void)
|
||||
{
|
||||
__asm__ __volatile__ ( "rep;nop" : : : "memory" );
|
||||
}
|
||||
#define cpu_relax() rep_nop()
|
||||
|
||||
|
||||
#if __GNUC__ == 2 && __GNUC_MINOR__ < 96
|
||||
#define __builtin_expect(x, expected_value) (x)
|
||||
#endif
|
||||
|
||||
#define DEFINE_PER_CPU(type, name) \
|
||||
__typeof__(type) per_cpu__##name
|
||||
|
||||
#define per_cpu(var, cpu) (*((void)cpu, &per_cpu__##var))
|
||||
|
||||
/* crude memory allocator for memory allocation early in
|
||||
* boot
|
||||
*/
|
||||
void *bootmem_alloc(unsigned int size);
|
||||
void bootmem_free(void *ptr, unsigned int size);
|
||||
|
||||
|
||||
/* Everything below this point is not included by assembler (.S) files. */
|
||||
#ifndef __ASSEMBLY__
|
||||
#include <sys/types.h>
|
||||
|
||||
void printk(const char *fmt, ...);
|
||||
|
||||
/* some function prototypes */
|
||||
void trap_init(void);
|
||||
|
||||
extern int preemptable;
|
||||
#define preempt_disable() (preemptable = 0)
|
||||
#define preempt_enable() (preemptable = 1)
|
||||
#define preempt_enable_no_resched() (preemptable = 1)
|
||||
|
||||
|
||||
/*
|
||||
* STI/CLI equivalents. These basically set and clear the virtual
|
||||
* event_enable flag in teh shared_info structure. Note that when
|
||||
* the enable bit is set, there may be pending events to be handled.
|
||||
* We may therefore call into do_hypervisor_callback() directly.
|
||||
*/
|
||||
#define likely(x) __builtin_expect((x),1)
|
||||
#define unlikely(x) __builtin_expect((x),0)
|
||||
|
||||
|
||||
|
||||
#define __cli() \
|
||||
do { \
|
||||
vcpu_info_t *_vcpu; \
|
||||
preempt_disable(); \
|
||||
_vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
|
||||
_vcpu->evtchn_upcall_mask = 1; \
|
||||
preempt_enable_no_resched(); \
|
||||
barrier(); \
|
||||
} while (0)
|
||||
|
||||
#define __sti() \
|
||||
do { \
|
||||
vcpu_info_t *_vcpu; \
|
||||
barrier(); \
|
||||
preempt_disable(); \
|
||||
_vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
|
||||
_vcpu->evtchn_upcall_mask = 0; \
|
||||
barrier(); /* unmask then check (avoid races) */ \
|
||||
if ( unlikely(_vcpu->evtchn_upcall_pending) ) \
|
||||
force_evtchn_callback(); \
|
||||
preempt_enable(); \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define __save_flags(x) \
|
||||
do { \
|
||||
vcpu_info_t *vcpu; \
|
||||
vcpu = HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
|
||||
(x) = _vcpu->evtchn_upcall_mask; \
|
||||
} while (0)
|
||||
|
||||
#define __restore_flags(x) \
|
||||
do { \
|
||||
vcpu_info_t *_vcpu; \
|
||||
barrier(); \
|
||||
preempt_disable(); \
|
||||
_vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
|
||||
if ((_vcpu->evtchn_upcall_mask = (x)) == 0) { \
|
||||
barrier(); /* unmask then check (avoid races) */ \
|
||||
if ( unlikely(_vcpu->evtchn_upcall_pending) ) \
|
||||
force_evtchn_callback(); \
|
||||
preempt_enable(); \
|
||||
} else \
|
||||
preempt_enable_no_resched(); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Add critical_{enter, exit}?
|
||||
*
|
||||
*/
|
||||
#define __save_and_cli(x) \
|
||||
do { \
|
||||
vcpu_info_t *_vcpu; \
|
||||
_vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
|
||||
(x) = _vcpu->evtchn_upcall_mask; \
|
||||
_vcpu->evtchn_upcall_mask = 1; \
|
||||
barrier(); \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define cli() __cli()
|
||||
#define sti() __sti()
|
||||
#define save_flags(x) __save_flags(x)
|
||||
#define restore_flags(x) __restore_flags(x)
|
||||
#define save_and_cli(x) __save_and_cli(x)
|
||||
|
||||
#define local_irq_save(x) __save_and_cli(x)
|
||||
#define local_irq_restore(x) __restore_flags(x)
|
||||
#define local_irq_disable() __cli()
|
||||
#define local_irq_enable() __sti()
|
||||
|
||||
#define mtx_lock_irqsave(lock, x) {local_irq_save((x)); mtx_lock_spin((lock));}
|
||||
#define mtx_unlock_irqrestore(lock, x) {mtx_unlock_spin((lock)); local_irq_restore((x)); }
|
||||
#define spin_lock_irqsave mtx_lock_irqsave
|
||||
#define spin_unlock_irqrestore mtx_unlock_irqrestore
|
||||
|
||||
|
||||
#ifndef mb
|
||||
#define mb() __asm__ __volatile__("lock; addl $0, 0(%%esp)": : :"memory")
|
||||
#endif
|
||||
#ifndef rmb
|
||||
#define rmb() mb()
|
||||
#endif
|
||||
#ifndef wmb
|
||||
#define wmb() barrier()
|
||||
#endif
|
||||
#ifdef SMP
|
||||
#define smp_mb() mb()
|
||||
#define smp_rmb() rmb()
|
||||
#define smp_wmb() wmb()
|
||||
#define smp_read_barrier_depends() read_barrier_depends()
|
||||
#define set_mb(var, value) do { xchg(&var, value); } while (0)
|
||||
#else
|
||||
#define smp_mb() barrier()
|
||||
#define smp_rmb() barrier()
|
||||
#define smp_wmb() barrier()
|
||||
#define smp_read_barrier_depends() do { } while(0)
|
||||
#define set_mb(var, value) do { var = value; barrier(); } while (0)
|
||||
#endif
|
||||
|
||||
|
||||
/* This is a barrier for the compiler only, NOT the processor! */
|
||||
#define barrier() __asm__ __volatile__("": : :"memory")
|
||||
|
||||
#define LOCK_PREFIX ""
|
||||
#define LOCK ""
|
||||
#define ADDR (*(volatile long *) addr)
|
||||
/*
|
||||
* Make sure gcc doesn't try to be clever and move things around
|
||||
* on us. We need to use _exactly_ the address the user gave us,
|
||||
* not some alias that contains the same information.
|
||||
*/
|
||||
typedef struct { volatile int counter; } atomic_t;
|
||||
|
||||
|
||||
|
||||
#define xen_xchg(ptr,v) \
|
||||
((__typeof__(*(ptr)))__xchg((unsigned long)(v),(ptr),sizeof(*(ptr))))
|
||||
struct __xchg_dummy { unsigned long a[100]; };
|
||||
#define __xg(x) ((volatile struct __xchg_dummy *)(x))
|
||||
static __inline unsigned long __xchg(unsigned long x, volatile void * ptr,
|
||||
int size)
|
||||
{
|
||||
switch (size) {
|
||||
case 1:
|
||||
__asm__ __volatile__("xchgb %b0,%1"
|
||||
:"=q" (x)
|
||||
:"m" (*__xg(ptr)), "0" (x)
|
||||
:"memory");
|
||||
break;
|
||||
case 2:
|
||||
__asm__ __volatile__("xchgw %w0,%1"
|
||||
:"=r" (x)
|
||||
:"m" (*__xg(ptr)), "0" (x)
|
||||
:"memory");
|
||||
break;
|
||||
case 4:
|
||||
__asm__ __volatile__("xchgl %0,%1"
|
||||
:"=r" (x)
|
||||
:"m" (*__xg(ptr)), "0" (x)
|
||||
:"memory");
|
||||
break;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
/**
|
||||
* test_and_clear_bit - Clear a bit and return its old value
|
||||
* @nr: Bit to set
|
||||
* @addr: Address to count from
|
||||
*
|
||||
* This operation is atomic and cannot be reordered.
|
||||
* It also implies a memory barrier.
|
||||
*/
|
||||
static __inline int test_and_clear_bit(int nr, volatile void * addr)
|
||||
{
|
||||
int oldbit;
|
||||
|
||||
__asm__ __volatile__( LOCK_PREFIX
|
||||
"btrl %2,%1\n\tsbbl %0,%0"
|
||||
:"=r" (oldbit),"=m" (ADDR)
|
||||
:"Ir" (nr) : "memory");
|
||||
return oldbit;
|
||||
}
|
||||
|
||||
static __inline int constant_test_bit(int nr, const volatile void * addr)
|
||||
{
|
||||
return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0;
|
||||
}
|
||||
|
||||
static __inline int variable_test_bit(int nr, volatile void * addr)
|
||||
{
|
||||
int oldbit;
|
||||
|
||||
__asm__ __volatile__(
|
||||
"btl %2,%1\n\tsbbl %0,%0"
|
||||
:"=r" (oldbit)
|
||||
:"m" (ADDR),"Ir" (nr));
|
||||
return oldbit;
|
||||
}
|
||||
|
||||
#define test_bit(nr,addr) \
|
||||
(__builtin_constant_p(nr) ? \
|
||||
constant_test_bit((nr),(addr)) : \
|
||||
variable_test_bit((nr),(addr)))
|
||||
|
||||
|
||||
/**
|
||||
* set_bit - Atomically set a bit in memory
|
||||
* @nr: the bit to set
|
||||
* @addr: the address to start counting from
|
||||
*
|
||||
* This function is atomic and may not be reordered. See __set_bit()
|
||||
* if you do not require the atomic guarantees.
|
||||
* Note that @nr may be almost arbitrarily large; this function is not
|
||||
* restricted to acting on a single-word quantity.
|
||||
*/
|
||||
static __inline__ void set_bit(int nr, volatile void * addr)
|
||||
{
|
||||
__asm__ __volatile__( LOCK_PREFIX
|
||||
"btsl %1,%0"
|
||||
:"=m" (ADDR)
|
||||
:"Ir" (nr));
|
||||
}
|
||||
|
||||
/**
|
||||
* clear_bit - Clears a bit in memory
|
||||
* @nr: Bit to clear
|
||||
* @addr: Address to start counting from
|
||||
*
|
||||
* clear_bit() is atomic and may not be reordered. However, it does
|
||||
* not contain a memory barrier, so if it is used for locking purposes,
|
||||
* you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit()
|
||||
* in order to ensure changes are visible on other processors.
|
||||
*/
|
||||
static __inline__ void clear_bit(int nr, volatile void * addr)
|
||||
{
|
||||
__asm__ __volatile__( LOCK_PREFIX
|
||||
"btrl %1,%0"
|
||||
:"=m" (ADDR)
|
||||
:"Ir" (nr));
|
||||
}
|
||||
|
||||
/**
|
||||
* atomic_inc - increment atomic variable
|
||||
* @v: pointer of type atomic_t
|
||||
*
|
||||
* Atomically increments @v by 1. Note that the guaranteed
|
||||
* useful range of an atomic_t is only 24 bits.
|
||||
*/
|
||||
static __inline__ void atomic_inc(atomic_t *v)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
LOCK "incl %0"
|
||||
:"=m" (v->counter)
|
||||
:"m" (v->counter));
|
||||
}
|
||||
|
||||
|
||||
#define rdtscll(val) \
|
||||
__asm__ __volatile__("rdtsc" : "=A" (val))
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Kernel pointers have redundant information, so we can use a
|
||||
* scheme where we can return either an error code or a dentry
|
||||
* pointer with the same return value.
|
||||
*
|
||||
* This should be a per-architecture thing, to allow different
|
||||
* error and pointer decisions.
|
||||
*/
|
||||
#define IS_ERR_VALUE(x) unlikely((x) > (unsigned long)-1000L)
|
||||
|
||||
static inline void *ERR_PTR(long error)
|
||||
{
|
||||
return (void *) error;
|
||||
}
|
||||
|
||||
static inline long PTR_ERR(const void *ptr)
|
||||
{
|
||||
return (long) ptr;
|
||||
}
|
||||
|
||||
static inline long IS_ERR(const void *ptr)
|
||||
{
|
||||
return IS_ERR_VALUE((unsigned long)ptr);
|
||||
}
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#endif /* _OS_H_ */
|
71
sys/i386/include/xen/xen_intr.h
Normal file
71
sys/i386/include/xen/xen_intr.h
Normal file
@ -0,0 +1,71 @@
|
||||
/* -*- Mode:C; c-basic-offset:4; tab-width:4 -*- */
|
||||
#ifndef _XEN_INTR_H_
|
||||
#define _XEN_INTR_H_
|
||||
|
||||
/*
|
||||
* The flat IRQ space is divided into two regions:
|
||||
* 1. A one-to-one mapping of real physical IRQs. This space is only used
|
||||
* if we have physical device-access privilege. This region is at the
|
||||
* start of the IRQ space so that existing device drivers do not need
|
||||
* to be modified to translate physical IRQ numbers into our IRQ space.
|
||||
* 3. A dynamic mapping of inter-domain and Xen-sourced virtual IRQs. These
|
||||
* are bound using the provided bind/unbind functions.
|
||||
*
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#define PIRQ_BASE 0
|
||||
#define NR_PIRQS 128
|
||||
|
||||
#define DYNIRQ_BASE (PIRQ_BASE + NR_PIRQS)
|
||||
#define NR_DYNIRQS 128
|
||||
|
||||
#define NR_IRQS (NR_PIRQS + NR_DYNIRQS)
|
||||
|
||||
#define pirq_to_irq(_x) ((_x) + PIRQ_BASE)
|
||||
#define irq_to_pirq(_x) ((_x) - PIRQ_BASE)
|
||||
|
||||
#define dynirq_to_irq(_x) ((_x) + DYNIRQ_BASE)
|
||||
#define irq_to_dynirq(_x) ((_x) - DYNIRQ_BASE)
|
||||
|
||||
/* Dynamic binding of event channels and VIRQ sources to Linux IRQ space. */
|
||||
extern void unbind_from_irq(int irq);
|
||||
|
||||
extern void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu);
|
||||
extern int bind_caller_port_to_irqhandler(unsigned int caller_port,
|
||||
const char *devname, driver_intr_t handler, void *arg,
|
||||
unsigned long irqflags, void **cookiep);
|
||||
extern int bind_listening_port_to_irqhandler(unsigned int remote_domain,
|
||||
const char *devname, driver_intr_t handler, void *arg, unsigned long irqflags,
|
||||
void **cookiep);
|
||||
extern int bind_virq_to_irqhandler(unsigned int virq, unsigned int cpu, const char *devname,
|
||||
driver_filter_t filter, driver_intr_t handler, unsigned long irqflags);
|
||||
extern int bind_ipi_to_irqhandler(unsigned int ipi, unsigned int cpu, const char *devname,
|
||||
driver_intr_t handler, unsigned long irqflags);
|
||||
extern int bind_interdomain_evtchn_to_irqhandler(unsigned int remote_domain,
|
||||
unsigned int remote_port,
|
||||
const char *devname,
|
||||
driver_filter_t filter,
|
||||
driver_intr_t handler,
|
||||
unsigned long irqflags);
|
||||
|
||||
|
||||
|
||||
extern void unbind_from_irqhandler(unsigned int evtchn, void *dev_id);
|
||||
static __inline__ int irq_cannonicalize(int irq)
|
||||
{
|
||||
return (irq == 2) ? 9 : irq;
|
||||
}
|
||||
|
||||
extern void disable_irq(unsigned int);
|
||||
extern void disable_irq_nosync(unsigned int);
|
||||
extern void enable_irq(unsigned int);
|
||||
|
||||
extern void irq_suspend(void);
|
||||
extern void irq_resume(void);
|
||||
|
||||
extern void idle_block(void);
|
||||
|
||||
|
||||
#endif /* _XEN_INTR_H_ */
|
287
sys/i386/include/xen/xenbus.h
Normal file
287
sys/i386/include/xen/xenbus.h
Normal file
@ -0,0 +1,287 @@
|
||||
/******************************************************************************
|
||||
* xenbus.h
|
||||
*
|
||||
* Talks to Xen Store to figure out what devices we have.
|
||||
*
|
||||
* Copyright (C) 2005 Rusty Russell, IBM Corporation
|
||||
* Copyright (C) 2005 XenSource Ltd.
|
||||
*
|
||||
* This file may be 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _ASM_XEN_XENBUS_H
|
||||
#define _ASM_XEN_XENBUS_H
|
||||
|
||||
#include <sys/queue.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/eventhandler.h>
|
||||
#include <xen/interface/io/xenbus.h>
|
||||
#include <xen/interface/io/xs_wire.h>
|
||||
|
||||
LIST_HEAD(xendev_list_head, xenbus_device);
|
||||
|
||||
/* Register callback to watch this node. */
|
||||
struct xenbus_watch
|
||||
{
|
||||
LIST_ENTRY(xenbus_watch) list;
|
||||
|
||||
/* Path being watched. */
|
||||
char *node;
|
||||
|
||||
/* Callback (executed in a process context with no locks held). */
|
||||
void (*callback)(struct xenbus_watch *,
|
||||
const char **vec, unsigned int len);
|
||||
};
|
||||
|
||||
|
||||
/* A xenbus device. */
|
||||
struct xenbus_device {
|
||||
struct xenbus_watch otherend_watch; /* must be first */
|
||||
const char *devicetype;
|
||||
const char *nodename;
|
||||
const char *otherend;
|
||||
int otherend_id;
|
||||
struct xendev_list_head *bus;
|
||||
struct xenbus_driver *driver;
|
||||
int has_error;
|
||||
enum xenbus_state state;
|
||||
void *dev_driver_data;
|
||||
LIST_ENTRY(xenbus_device) list;
|
||||
};
|
||||
|
||||
static inline struct xenbus_device *to_xenbus_device(device_t dev)
|
||||
{
|
||||
return device_get_softc(dev);
|
||||
}
|
||||
|
||||
struct xenbus_device_id
|
||||
{
|
||||
/* .../device/<device_type>/<identifier> */
|
||||
char devicetype[32]; /* General class of device. */
|
||||
};
|
||||
|
||||
/* A xenbus driver. */
|
||||
struct xenbus_driver {
|
||||
char *name;
|
||||
struct module *owner;
|
||||
const struct xenbus_device_id *ids;
|
||||
int (*probe)(struct xenbus_device *dev,
|
||||
const struct xenbus_device_id *id);
|
||||
void (*otherend_changed)(struct xenbus_device *dev,
|
||||
XenbusState backend_state);
|
||||
int (*remove)(struct xenbus_device *dev);
|
||||
int (*suspend)(struct xenbus_device *dev);
|
||||
int (*resume)(struct xenbus_device *dev);
|
||||
int (*hotplug)(struct xenbus_device *, char **, int, char *, int);
|
||||
#if 0
|
||||
struct device_driver driver;
|
||||
#endif
|
||||
driver_t driver;
|
||||
int (*read_otherend_details)(struct xenbus_device *dev);
|
||||
int (*watch_otherend)(struct xenbus_device *dev);
|
||||
int (*cleanup_device)(struct xenbus_device *dev);
|
||||
int (*is_ready)(struct xenbus_device *dev);
|
||||
LIST_ENTRY(xenbus_driver) list;
|
||||
};
|
||||
|
||||
static inline struct xenbus_driver *to_xenbus_driver(driver_t *drv)
|
||||
{
|
||||
#if 0
|
||||
return container_of(drv, struct xenbus_driver, driver);
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
typedef int (*xenstore_event_handler_t)(void *);
|
||||
|
||||
int xenbus_register_frontend(struct xenbus_driver *drv);
|
||||
int xenbus_register_backend(struct xenbus_driver *drv);
|
||||
void xenbus_unregister_driver(struct xenbus_driver *drv);
|
||||
|
||||
int xenbus_remove_device(struct xenbus_device *dev);
|
||||
|
||||
struct xenbus_transaction
|
||||
{
|
||||
uint32_t id;
|
||||
};
|
||||
|
||||
#define XBT_NIL ((struct xenbus_transaction) { 0 })
|
||||
|
||||
char **xenbus_directory(struct xenbus_transaction t,
|
||||
const char *dir, const char *node, unsigned int *num);
|
||||
void *xenbus_read(struct xenbus_transaction t,
|
||||
const char *dir, const char *node, unsigned int *len);
|
||||
int xenbus_write(struct xenbus_transaction t,
|
||||
const char *dir, const char *node, const char *string);
|
||||
int xenbus_mkdir(struct xenbus_transaction t,
|
||||
const char *dir, const char *node);
|
||||
int xenbus_exists(struct xenbus_transaction t,
|
||||
const char *dir, const char *node);
|
||||
int xenbus_rm(struct xenbus_transaction t, const char *dir, const char *node);
|
||||
int xenbus_transaction_start(struct xenbus_transaction *t);
|
||||
int xenbus_transaction_end(struct xenbus_transaction t, int abort);
|
||||
|
||||
/* Single read and scanf: returns -errno or num scanned if > 0. */
|
||||
int xenbus_scanf(struct xenbus_transaction t,
|
||||
const char *dir, const char *node, const char *fmt, ...)
|
||||
__attribute__((format(scanf, 4, 5)));
|
||||
|
||||
/* Single printf and write: returns -errno or 0. */
|
||||
int xenbus_printf(struct xenbus_transaction t,
|
||||
const char *dir, const char *node, const char *fmt, ...)
|
||||
__attribute__((format(printf, 4, 5)));
|
||||
|
||||
/* Generic read function: NULL-terminated triples of name,
|
||||
* sprintf-style type string, and pointer. Returns 0 or errno.*/
|
||||
int xenbus_gather(struct xenbus_transaction t, const char *dir, ...);
|
||||
|
||||
/* notifer routines for when the xenstore comes up */
|
||||
int register_xenstore_notifier(xenstore_event_handler_t func, void *arg, int priority);
|
||||
#if 0
|
||||
void unregister_xenstore_notifier();
|
||||
#endif
|
||||
int register_xenbus_watch(struct xenbus_watch *watch);
|
||||
void unregister_xenbus_watch(struct xenbus_watch *watch);
|
||||
void xs_suspend(void);
|
||||
void xs_resume(void);
|
||||
|
||||
/* Used by xenbus_dev to borrow kernel's store connection. */
|
||||
void *xenbus_dev_request_and_reply(struct xsd_sockmsg *msg);
|
||||
|
||||
/* Called from xen core code. */
|
||||
void xenbus_suspend(void);
|
||||
void xenbus_resume(void);
|
||||
|
||||
#define XENBUS_IS_ERR_READ(str) ({ \
|
||||
if (!IS_ERR(str) && strlen(str) == 0) { \
|
||||
free(str, M_DEVBUF); \
|
||||
str = ERR_PTR(-ERANGE); \
|
||||
} \
|
||||
IS_ERR(str); \
|
||||
})
|
||||
|
||||
#define XENBUS_EXIST_ERR(err) ((err) == -ENOENT || (err) == -ERANGE)
|
||||
|
||||
|
||||
/**
|
||||
* Register a watch on the given path, using the given xenbus_watch structure
|
||||
* for storage, and the given callback function as the callback. Return 0 on
|
||||
* success, or -errno on error. On success, the given path will be saved as
|
||||
* watch->node, and remains the caller's to free. On error, watch->node will
|
||||
* be NULL, the device will switch to XenbusStateClosing, and the error will
|
||||
* be saved in the store.
|
||||
*/
|
||||
int xenbus_watch_path(struct xenbus_device *dev, char *path,
|
||||
struct xenbus_watch *watch,
|
||||
void (*callback)(struct xenbus_watch *,
|
||||
const char **, unsigned int));
|
||||
|
||||
|
||||
/**
|
||||
* Register a watch on the given path/path2, using the given xenbus_watch
|
||||
* structure for storage, and the given callback function as the callback.
|
||||
* Return 0 on success, or -errno on error. On success, the watched path
|
||||
* (path/path2) will be saved as watch->node, and becomes the caller's to
|
||||
* kfree(). On error, watch->node will be NULL, so the caller has nothing to
|
||||
* free, the device will switch to XenbusStateClosing, and the error will be
|
||||
* saved in the store.
|
||||
*/
|
||||
int xenbus_watch_path2(struct xenbus_device *dev, const char *path,
|
||||
const char *path2, struct xenbus_watch *watch,
|
||||
void (*callback)(struct xenbus_watch *,
|
||||
const char **, unsigned int));
|
||||
|
||||
|
||||
/**
|
||||
* Advertise in the store a change of the given driver to the given new_state.
|
||||
* which case this is performed inside its own transaction. Return 0 on
|
||||
* success, or -errno on error. On error, the device will switch to
|
||||
* XenbusStateClosing, and the error will be saved in the store.
|
||||
*/
|
||||
int xenbus_switch_state(struct xenbus_device *dev,
|
||||
XenbusState new_state);
|
||||
|
||||
|
||||
/**
|
||||
* Grant access to the given ring_mfn to the peer of the given device. Return
|
||||
* 0 on success, or -errno on error. On error, the device will switch to
|
||||
* XenbusStateClosing, and the error will be saved in the store.
|
||||
*/
|
||||
int xenbus_grant_ring(struct xenbus_device *dev, unsigned long ring_mfn);
|
||||
|
||||
|
||||
/**
|
||||
* Allocate an event channel for the given xenbus_device, assigning the newly
|
||||
* created local port to *port. Return 0 on success, or -errno on error. On
|
||||
* error, the device will switch to XenbusStateClosing, and the error will be
|
||||
* saved in the store.
|
||||
*/
|
||||
int xenbus_alloc_evtchn(struct xenbus_device *dev, int *port);
|
||||
|
||||
|
||||
/**
|
||||
* Free an existing event channel. Returns 0 on success or -errno on error.
|
||||
*/
|
||||
int xenbus_free_evtchn(struct xenbus_device *dev, int port);
|
||||
|
||||
|
||||
/**
|
||||
* Return the state of the driver rooted at the given store path, or
|
||||
* XenbusStateClosed if no state can be read.
|
||||
*/
|
||||
XenbusState xenbus_read_driver_state(const char *path);
|
||||
|
||||
|
||||
/***
|
||||
* Report the given negative errno into the store, along with the given
|
||||
* formatted message.
|
||||
*/
|
||||
void xenbus_dev_error(struct xenbus_device *dev, int err, const char *fmt,
|
||||
...);
|
||||
|
||||
|
||||
/***
|
||||
* Equivalent to xenbus_dev_error(dev, err, fmt, args), followed by
|
||||
* xenbus_switch_state(dev, NULL, XenbusStateClosing) to schedule an orderly
|
||||
* closedown of this driver and its peer.
|
||||
*/
|
||||
void xenbus_dev_fatal(struct xenbus_device *dev, int err, const char *fmt,
|
||||
...);
|
||||
|
||||
int xenbus_dev_init(void);
|
||||
|
||||
const char *xenbus_strstate(enum xenbus_state state);
|
||||
int xenbus_dev_is_online(struct xenbus_device *dev);
|
||||
int xenbus_frontend_closed(struct xenbus_device *dev);
|
||||
|
||||
#endif /* _ASM_XEN_XENBUS_H */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* c-file-style: "bsd"
|
||||
* indent-tabs-mode: t
|
||||
* c-indent-level: 4
|
||||
* c-basic-offset: 8
|
||||
* tab-width: 4
|
||||
* End:
|
||||
*/
|
83
sys/i386/include/xen/xenfunc.h
Normal file
83
sys/i386/include/xen/xenfunc.h
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2004,2005 Kip Macy
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 4. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _XEN_XENFUNC_H_
|
||||
#define _XEN_XENFUNC_H_
|
||||
|
||||
#include <machine/xen/xen-os.h>
|
||||
#include <machine/xen/hypervisor.h>
|
||||
#include <machine/xen/xenpmap.h>
|
||||
#include <machine/segments.h>
|
||||
#include <sys/pcpu.h>
|
||||
#define BKPT __asm__("int3");
|
||||
#define XPQ_CALL_DEPTH 5
|
||||
#define XPQ_CALL_COUNT 2
|
||||
#define PG_PRIV PG_AVAIL3
|
||||
typedef struct {
|
||||
unsigned long pt_ref;
|
||||
unsigned long pt_eip[XPQ_CALL_COUNT][XPQ_CALL_DEPTH];
|
||||
} pteinfo_t;
|
||||
|
||||
extern pteinfo_t *pteinfo_list;
|
||||
#ifdef XENDEBUG_LOW
|
||||
#define __PRINTK(x) printk x
|
||||
#else
|
||||
#define __PRINTK(x)
|
||||
#endif
|
||||
|
||||
char *xen_setbootenv(char *cmd_line);
|
||||
|
||||
int xen_boothowto(char *envp);
|
||||
|
||||
void _xen_machphys_update(unsigned long, unsigned long, char *file, int line);
|
||||
|
||||
#ifdef INVARIANTS
|
||||
#define xen_machphys_update(a, b) _xen_machphys_update((a), (b), __FILE__, __LINE__)
|
||||
#else
|
||||
#define xen_machphys_update(a, b) _xen_machphys_update((a), (b), NULL, 0)
|
||||
#endif
|
||||
|
||||
void xen_update_descriptor(union descriptor *, union descriptor *);
|
||||
|
||||
void ap_cpu_initclocks(void);
|
||||
|
||||
extern struct mtx balloon_lock;
|
||||
#if 0
|
||||
#define balloon_lock(__flags) mtx_lock_irqsave(&balloon_lock, __flags)
|
||||
#define balloon_unlock(__flags) mtx_unlock_irqrestore(&balloon_lock, __flags)
|
||||
#else
|
||||
#define balloon_lock(__flags) __flags = 1
|
||||
#define balloon_unlock(__flags) __flags = 0
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif /* _XEN_XENFUNC_H_ */
|
243
sys/i386/include/xen/xenpmap.h
Normal file
243
sys/i386/include/xen/xenpmap.h
Normal file
@ -0,0 +1,243 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2004 Christian Limpach.
|
||||
* Copyright (c) 2004,2005 Kip Macy
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Christian Limpach.
|
||||
* 4. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _XEN_XENPMAP_H_
|
||||
#define _XEN_XENPMAP_H_
|
||||
void xen_invlpg(vm_offset_t);
|
||||
void xen_load_cr3(vm_paddr_t);
|
||||
void _xen_queue_pt_update(vm_paddr_t, vm_paddr_t, char *, int);
|
||||
void xen_pt_switch(vm_paddr_t);
|
||||
void xen_set_ldt(vm_paddr_t, unsigned long);
|
||||
void xen_tlb_flush(void);
|
||||
void xen_pgdpt_pin(vm_paddr_t);
|
||||
void xen_pgd_pin(vm_paddr_t);
|
||||
void xen_pgd_unpin(vm_paddr_t);
|
||||
void xen_pt_pin(vm_paddr_t);
|
||||
void xen_pt_unpin(vm_paddr_t);
|
||||
void xen_flush_queue(void);
|
||||
void pmap_ref(pt_entry_t *pte, vm_paddr_t ma);
|
||||
void xen_check_queue(void);
|
||||
|
||||
#ifdef INVARIANTS
|
||||
#define xen_queue_pt_update(a, b) _xen_queue_pt_update((a), (b), __FILE__, __LINE__)
|
||||
#else
|
||||
#define xen_queue_pt_update(a, b) _xen_queue_pt_update((a), (b), NULL, 0)
|
||||
#endif
|
||||
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/pcpu.h>
|
||||
|
||||
#ifdef PMAP_DEBUG
|
||||
#define PMAP_REF pmap_ref
|
||||
#define PMAP_DEC_REF_PAGE pmap_dec_ref_page
|
||||
#define PMAP_MARK_PRIV pmap_mark_privileged
|
||||
#define PMAP_MARK_UNPRIV pmap_mark_unprivileged
|
||||
#else
|
||||
#define PMAP_MARK_PRIV(a)
|
||||
#define PMAP_MARK_UNPRIV(a)
|
||||
#define PMAP_REF(a, b)
|
||||
#define PMAP_DEC_REF_PAGE(a)
|
||||
#endif
|
||||
|
||||
#define ALWAYS_SYNC 0
|
||||
|
||||
#ifdef PT_DEBUG
|
||||
#define PT_LOG() printk("WP PT_SET %s:%d\n", __FILE__, __LINE__)
|
||||
#else
|
||||
#define PT_LOG()
|
||||
#endif
|
||||
|
||||
#define INVALID_P2M_ENTRY (~0UL)
|
||||
|
||||
#define pmap_valid_entry(E) ((E) & PG_V) /* is PDE or PTE valid? */
|
||||
|
||||
#define SH_PD_SET_VA 1
|
||||
#define SH_PD_SET_VA_MA 2
|
||||
#define SH_PD_SET_VA_CLEAR 3
|
||||
|
||||
struct pmap;
|
||||
void pd_set(struct pmap *pmap, int ptepindex, vm_paddr_t val, int type);
|
||||
#ifdef notyet
|
||||
static vm_paddr_t
|
||||
vptetomachpte(vm_paddr_t *pte)
|
||||
{
|
||||
vm_offset_t offset, ppte;
|
||||
vm_paddr_t pgoffset, retval, *pdir_shadow_ptr;
|
||||
int pgindex;
|
||||
|
||||
ppte = (vm_offset_t)pte;
|
||||
pgoffset = (ppte & PAGE_MASK);
|
||||
offset = ppte - (vm_offset_t)PTmap;
|
||||
pgindex = ppte >> PDRSHIFT;
|
||||
|
||||
pdir_shadow_ptr = (vm_paddr_t *)PCPU_GET(pdir_shadow);
|
||||
retval = (pdir_shadow_ptr[pgindex] & ~PAGE_MASK) + pgoffset;
|
||||
return (retval);
|
||||
}
|
||||
#endif
|
||||
#define PT_GET(_ptp) \
|
||||
(pmap_valid_entry(*(_ptp)) ? xpmap_mtop(*(_ptp)) : (0))
|
||||
|
||||
#ifdef WRITABLE_PAGETABLES
|
||||
|
||||
#define PT_SET_VA(_ptp,_npte,sync) do { \
|
||||
PMAP_REF((_ptp), xpmap_ptom(_npte)); \
|
||||
PT_LOG(); \
|
||||
*(_ptp) = xpmap_ptom((_npte)); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
#define PT_SET_VA_MA(_ptp,_npte,sync) do { \
|
||||
PMAP_REF((_ptp), (_npte)); \
|
||||
PT_LOG(); \
|
||||
*(_ptp) = (_npte); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
#define PT_CLEAR_VA(_ptp, sync) do { \
|
||||
PMAP_REF((pt_entry_t *)(_ptp), 0); \
|
||||
PT_LOG(); \
|
||||
*(_ptp) = 0; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define PD_SET_VA(_pmap, _ptp, _npte, sync) do { \
|
||||
PMAP_REF((_ptp), xpmap_ptom(_npte)); \
|
||||
pd_set((_pmap),(_ptp),(_npte), SH_PD_SET_VA); \
|
||||
if (sync || ALWAYS_SYNC) xen_flush_queue(); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
#define PD_SET_VA_MA(_pmap, _ptp, _npte, sync) do { \
|
||||
PMAP_REF((_ptp), (_npte)); \
|
||||
pd_set((_pmap),(_ptp),(_npte), SH_PD_SET_VA_MA); \
|
||||
if (sync || ALWAYS_SYNC) xen_flush_queue(); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
#define PD_CLEAR_VA(_pmap, _ptp, sync) do { \
|
||||
PMAP_REF((pt_entry_t *)(_ptp), 0); \
|
||||
pd_set((_pmap),(_ptp), 0, SH_PD_SET_VA_CLEAR); \
|
||||
if (sync || ALWAYS_SYNC) xen_flush_queue(); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#else /* !WRITABLE_PAGETABLES */
|
||||
|
||||
#define PT_SET_VA(_ptp,_npte,sync) do { \
|
||||
PMAP_REF((_ptp), xpmap_ptom(_npte)); \
|
||||
xen_queue_pt_update(vtomach(_ptp), \
|
||||
xpmap_ptom(_npte)); \
|
||||
if (sync || ALWAYS_SYNC) xen_flush_queue(); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
#define PT_SET_VA_MA(_ptp,_npte,sync) do { \
|
||||
PMAP_REF((_ptp), (_npte)); \
|
||||
xen_queue_pt_update(vtomach(_ptp), _npte); \
|
||||
if (sync || ALWAYS_SYNC) xen_flush_queue(); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
#define PT_CLEAR_VA(_ptp, sync) do { \
|
||||
PMAP_REF((pt_entry_t *)(_ptp), 0); \
|
||||
xen_queue_pt_update(vtomach(_ptp), 0); \
|
||||
if (sync || ALWAYS_SYNC) \
|
||||
xen_flush_queue(); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#define PD_SET_VA(_pmap, _ptepindex,_npte,sync) do { \
|
||||
PMAP_REF((_ptp), xpmap_ptom(_npte)); \
|
||||
pd_set((_pmap),(_ptepindex),(_npte), SH_PD_SET_VA); \
|
||||
if (sync || ALWAYS_SYNC) xen_flush_queue(); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
#define PD_SET_VA_MA(_pmap, _ptepindex,_npte,sync) do { \
|
||||
PMAP_REF((_ptp), (_npte)); \
|
||||
pd_set((_pmap),(_ptepindex),(_npte), SH_PD_SET_VA_MA); \
|
||||
if (sync || ALWAYS_SYNC) xen_flush_queue(); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
#define PD_CLEAR_VA(_pmap, _ptepindex, sync) do { \
|
||||
PMAP_REF((pt_entry_t *)(_ptp), 0); \
|
||||
pd_set((_pmap),(_ptepindex), 0, SH_PD_SET_VA_CLEAR); \
|
||||
if (sync || ALWAYS_SYNC) xen_flush_queue(); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef PAE
|
||||
#define PT_SET_MA(_va, _ma) \
|
||||
do { \
|
||||
PANIC_IF(HYPERVISOR_update_va_mapping(((unsigned long)(_va)),\
|
||||
(_ma), \
|
||||
UVMF_INVLPG| UVMF_LOCAL) < 0); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#else
|
||||
|
||||
#define PT_SET_MA(_va, _ma) \
|
||||
do { \
|
||||
PANIC_IF(HYPERVISOR_update_va_mapping(((unsigned long)(_va)),\
|
||||
(_ma), \
|
||||
UVMF_INVLPG| UVMF_LOCAL) < 0); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
#endif
|
||||
|
||||
#define PT_UPDATES_FLUSH() do { \
|
||||
xen_flush_queue(); \
|
||||
} while (/*CONSTCOND*/0)
|
||||
|
||||
static __inline vm_paddr_t
|
||||
xpmap_mtop(vm_paddr_t mpa)
|
||||
{
|
||||
vm_paddr_t tmp = (mpa & PG_FRAME);
|
||||
|
||||
return machtophys(tmp) | (mpa & ~PG_FRAME);
|
||||
}
|
||||
|
||||
static __inline vm_paddr_t
|
||||
xpmap_ptom(vm_paddr_t ppa)
|
||||
{
|
||||
vm_paddr_t tmp = (ppa & PG_FRAME);
|
||||
|
||||
return phystomach(tmp) | (ppa & ~PG_FRAME);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
set_phys_to_machine(unsigned long pfn, unsigned long mfn)
|
||||
{
|
||||
#ifdef notyet
|
||||
PANIC_IF(max_mapnr && pfn >= max_mapnr);
|
||||
#endif
|
||||
if (xen_feature(XENFEAT_auto_translated_physmap)) {
|
||||
#ifdef notyet
|
||||
PANIC_IF((pfn != mfn && mfn != INVALID_P2M_ENTRY));
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
xen_phys_machine[pfn] = mfn;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* _XEN_XENPMAP_H_ */
|
89
sys/i386/include/xen/xenstored.h
Normal file
89
sys/i386/include/xen/xenstored.h
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Simple prototyle Xen Store Daemon providing simple tree-like database.
|
||||
* Copyright (C) 2005 Rusty Russell IBM Corporation
|
||||
*
|
||||
* This file may be 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 _XENSTORED_H
|
||||
#define _XENSTORED_H
|
||||
|
||||
enum xsd_sockmsg_type
|
||||
{
|
||||
XS_DEBUG,
|
||||
XS_SHUTDOWN,
|
||||
XS_DIRECTORY,
|
||||
XS_READ,
|
||||
XS_GET_PERMS,
|
||||
XS_WATCH,
|
||||
XS_WATCH_ACK,
|
||||
XS_UNWATCH,
|
||||
XS_TRANSACTION_START,
|
||||
XS_TRANSACTION_END,
|
||||
XS_OP_READ_ONLY = XS_TRANSACTION_END,
|
||||
XS_INTRODUCE,
|
||||
XS_RELEASE,
|
||||
XS_GETDOMAINPATH,
|
||||
XS_WRITE,
|
||||
XS_MKDIR,
|
||||
XS_RM,
|
||||
XS_SET_PERMS,
|
||||
XS_WATCH_EVENT,
|
||||
XS_ERROR,
|
||||
};
|
||||
|
||||
#define XS_WRITE_NONE "NONE"
|
||||
#define XS_WRITE_CREATE "CREATE"
|
||||
#define XS_WRITE_CREATE_EXCL "CREATE|EXCL"
|
||||
|
||||
/* We hand errors as strings, for portability. */
|
||||
struct xsd_errors
|
||||
{
|
||||
int errnum;
|
||||
const char *errstring;
|
||||
};
|
||||
#define XSD_ERROR(x) { x, #x }
|
||||
static struct xsd_errors xsd_errors[] __attribute__((unused)) = {
|
||||
XSD_ERROR(EINVAL),
|
||||
XSD_ERROR(EACCES),
|
||||
XSD_ERROR(EEXIST),
|
||||
XSD_ERROR(EISDIR),
|
||||
XSD_ERROR(ENOENT),
|
||||
XSD_ERROR(ENOMEM),
|
||||
XSD_ERROR(ENOSPC),
|
||||
XSD_ERROR(EIO),
|
||||
XSD_ERROR(ENOTEMPTY),
|
||||
XSD_ERROR(ENOSYS),
|
||||
XSD_ERROR(EROFS),
|
||||
XSD_ERROR(EBUSY),
|
||||
XSD_ERROR(ETIMEDOUT),
|
||||
XSD_ERROR(EISCONN),
|
||||
};
|
||||
struct xsd_sockmsg
|
||||
{
|
||||
uint32_t type;
|
||||
uint32_t len; /* Length of data following this. */
|
||||
|
||||
/* Generally followed by nul-terminated string(s). */
|
||||
};
|
||||
|
||||
#endif /* _XENSTORED_H */
|
103
sys/i386/include/xen/xenvar.h
Normal file
103
sys/i386/include/xen/xenvar.h
Normal file
@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (c) 2008 Kip Macy
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#ifndef XENVAR_H_
|
||||
#define XENVAR_H_
|
||||
#define XBOOTUP 0x1
|
||||
#define XPMAP 0x2
|
||||
extern int xendebug_flags;
|
||||
#ifndef NOXENDEBUG
|
||||
#define XENPRINTF printk
|
||||
#else
|
||||
#define XENPRINTF printf
|
||||
#endif
|
||||
#include <machine/xen/features.h>
|
||||
|
||||
extern xen_pfn_t *xen_phys_machine;
|
||||
|
||||
#if 0
|
||||
#define TRACE_ENTER XENPRINTF("(file=%s, line=%d) entered %s\n", __FILE__, __LINE__, __FUNCTION__)
|
||||
#define TRACE_EXIT XENPRINTF("(file=%s, line=%d) exiting %s\n", __FILE__, __LINE__, __FUNCTION__)
|
||||
#define TRACE_DEBUG(argflags, _f, _a...) \
|
||||
if (xendebug_flags & argflags) XENPRINTF("(file=%s, line=%d) " _f "\n", __FILE__, __LINE__, ## _a);
|
||||
#else
|
||||
#define TRACE_ENTER
|
||||
#define TRACE_EXIT
|
||||
#define TRACE_DEBUG(argflags, _f, _a...)
|
||||
#endif
|
||||
|
||||
extern xen_pfn_t *xen_machine_phys;
|
||||
/* Xen starts physical pages after the 4MB ISA hole -
|
||||
* FreeBSD doesn't
|
||||
*/
|
||||
|
||||
|
||||
#undef ADD_ISA_HOLE /* XXX */
|
||||
|
||||
#ifdef ADD_ISA_HOLE
|
||||
#define ISA_INDEX_OFFSET 1024
|
||||
#define ISA_PDR_OFFSET 1
|
||||
#else
|
||||
#define ISA_INDEX_OFFSET 0
|
||||
#define ISA_PDR_OFFSET 0
|
||||
#endif
|
||||
|
||||
|
||||
#define PFNTOMFN(i) (xen_phys_machine[((xen_pfn_t)i)])
|
||||
#define MFNTOPFN(i) (xen_machine_phys[((xen_pfn_t)i)])
|
||||
|
||||
#define VTOP(x) ((uintptr_t)(((uint8_t *)(x)) - KERNBASE))
|
||||
#define PTOV(x) ((x) + KERNBASE)
|
||||
|
||||
#define VTOPFN(x) (VTOP(x) >> PAGE_SHIFT)
|
||||
#define PFNTOV(x) PTOV((vm_paddr_t)(x) << PAGE_SHIFT)
|
||||
|
||||
#define VTOMFN(va) (vtomach(va) >> PAGE_SHIFT)
|
||||
#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
|
||||
|
||||
#define phystomach(pa) (PFNTOMFN((pa) >> PAGE_SHIFT) << PAGE_SHIFT)
|
||||
#define machtophys(ma) (MFNTOPFN((ma) >> PAGE_SHIFT) << PAGE_SHIFT)
|
||||
|
||||
|
||||
void xpq_init(void);
|
||||
|
||||
#define BITS_PER_LONG 32
|
||||
#define NR_CPUS MAX_VIRT_CPUS
|
||||
|
||||
#define BITS_TO_LONGS(bits) \
|
||||
(((bits)+BITS_PER_LONG-1)/BITS_PER_LONG)
|
||||
#define DECLARE_BITMAP(name,bits) \
|
||||
unsigned long name[BITS_TO_LONGS(bits)]
|
||||
typedef struct { DECLARE_BITMAP(bits, NR_CPUS); } xen_cpumask_t;
|
||||
|
||||
int xen_create_contiguous_region(vm_page_t pages, int npages);
|
||||
|
||||
void xen_destroy_contiguous_region(void * addr, int npages);
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user