mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-24 13:44:26 -04:00
Merge branches 'x86/urgent', 'x86/amd-iommu', 'x86/apic', 'x86/cleanups', 'x86/core', 'x86/cpu', 'x86/fixmap', 'x86/gart', 'x86/kprobes', 'x86/memtest', 'x86/modules', 'x86/nmi', 'x86/pat', 'x86/reboot', 'x86/setup', 'x86/step', 'x86/unify-pci', 'x86/uv', 'x86/xen' and 'xen-64bit' into x86/for-linus
This commit is contained in:
139 changed files with 3891 additions and 1716 deletions
|
|
@ -27,13 +27,12 @@
|
|||
/*
|
||||
* some size calculation constants
|
||||
*/
|
||||
#define DEV_TABLE_ENTRY_SIZE 256
|
||||
#define DEV_TABLE_ENTRY_SIZE 32
|
||||
#define ALIAS_TABLE_ENTRY_SIZE 2
|
||||
#define RLOOKUP_TABLE_ENTRY_SIZE (sizeof(void *))
|
||||
|
||||
/* helper macros */
|
||||
#define LOW_U32(x) ((x) & ((1ULL << 32)-1))
|
||||
#define HIGH_U32(x) (LOW_U32((x) >> 32))
|
||||
|
||||
/* Length of the MMIO region for the AMD IOMMU */
|
||||
#define MMIO_REGION_LENGTH 0x4000
|
||||
|
|
@ -158,78 +157,170 @@
|
|||
|
||||
#define MAX_DOMAIN_ID 65536
|
||||
|
||||
/*
|
||||
* This structure contains generic data for IOMMU protection domains
|
||||
* independent of their use.
|
||||
*/
|
||||
struct protection_domain {
|
||||
spinlock_t lock;
|
||||
u16 id;
|
||||
int mode;
|
||||
u64 *pt_root;
|
||||
void *priv;
|
||||
spinlock_t lock; /* mostly used to lock the page table*/
|
||||
u16 id; /* the domain id written to the device table */
|
||||
int mode; /* paging mode (0-6 levels) */
|
||||
u64 *pt_root; /* page table root pointer */
|
||||
void *priv; /* private data */
|
||||
};
|
||||
|
||||
/*
|
||||
* Data container for a dma_ops specific protection domain
|
||||
*/
|
||||
struct dma_ops_domain {
|
||||
struct list_head list;
|
||||
|
||||
/* generic protection domain information */
|
||||
struct protection_domain domain;
|
||||
|
||||
/* size of the aperture for the mappings */
|
||||
unsigned long aperture_size;
|
||||
|
||||
/* address we start to search for free addresses */
|
||||
unsigned long next_bit;
|
||||
|
||||
/* address allocation bitmap */
|
||||
unsigned long *bitmap;
|
||||
|
||||
/*
|
||||
* Array of PTE pages for the aperture. In this array we save all the
|
||||
* leaf pages of the domain page table used for the aperture. This way
|
||||
* we don't need to walk the page table to find a specific PTE. We can
|
||||
* just calculate its address in constant time.
|
||||
*/
|
||||
u64 **pte_pages;
|
||||
};
|
||||
|
||||
/*
|
||||
* Structure where we save information about one hardware AMD IOMMU in the
|
||||
* system.
|
||||
*/
|
||||
struct amd_iommu {
|
||||
struct list_head list;
|
||||
|
||||
/* locks the accesses to the hardware */
|
||||
spinlock_t lock;
|
||||
|
||||
/* device id of this IOMMU */
|
||||
u16 devid;
|
||||
/*
|
||||
* Capability pointer. There could be more than one IOMMU per PCI
|
||||
* device function if there are more than one AMD IOMMU capability
|
||||
* pointers.
|
||||
*/
|
||||
u16 cap_ptr;
|
||||
|
||||
/* physical address of MMIO space */
|
||||
u64 mmio_phys;
|
||||
/* virtual address of MMIO space */
|
||||
u8 *mmio_base;
|
||||
|
||||
/* capabilities of that IOMMU read from ACPI */
|
||||
u32 cap;
|
||||
|
||||
/* first device this IOMMU handles. read from PCI */
|
||||
u16 first_device;
|
||||
/* last device this IOMMU handles. read from PCI */
|
||||
u16 last_device;
|
||||
|
||||
/* start of exclusion range of that IOMMU */
|
||||
u64 exclusion_start;
|
||||
/* length of exclusion range of that IOMMU */
|
||||
u64 exclusion_length;
|
||||
|
||||
/* command buffer virtual address */
|
||||
u8 *cmd_buf;
|
||||
/* size of command buffer */
|
||||
u32 cmd_buf_size;
|
||||
|
||||
/* if one, we need to send a completion wait command */
|
||||
int need_sync;
|
||||
|
||||
/* default dma_ops domain for that IOMMU */
|
||||
struct dma_ops_domain *default_dom;
|
||||
};
|
||||
|
||||
/*
|
||||
* List with all IOMMUs in the system. This list is not locked because it is
|
||||
* only written and read at driver initialization or suspend time
|
||||
*/
|
||||
extern struct list_head amd_iommu_list;
|
||||
|
||||
/*
|
||||
* Structure defining one entry in the device table
|
||||
*/
|
||||
struct dev_table_entry {
|
||||
u32 data[8];
|
||||
};
|
||||
|
||||
/*
|
||||
* One entry for unity mappings parsed out of the ACPI table.
|
||||
*/
|
||||
struct unity_map_entry {
|
||||
struct list_head list;
|
||||
|
||||
/* starting device id this entry is used for (including) */
|
||||
u16 devid_start;
|
||||
/* end device id this entry is used for (including) */
|
||||
u16 devid_end;
|
||||
|
||||
/* start address to unity map (including) */
|
||||
u64 address_start;
|
||||
/* end address to unity map (including) */
|
||||
u64 address_end;
|
||||
|
||||
/* required protection */
|
||||
int prot;
|
||||
};
|
||||
|
||||
/*
|
||||
* List of all unity mappings. It is not locked because as runtime it is only
|
||||
* read. It is created at ACPI table parsing time.
|
||||
*/
|
||||
extern struct list_head amd_iommu_unity_map;
|
||||
|
||||
/* data structures for device handling */
|
||||
/*
|
||||
* Data structures for device handling
|
||||
*/
|
||||
|
||||
/*
|
||||
* Device table used by hardware. Read and write accesses by software are
|
||||
* locked with the amd_iommu_pd_table lock.
|
||||
*/
|
||||
extern struct dev_table_entry *amd_iommu_dev_table;
|
||||
|
||||
/*
|
||||
* Alias table to find requestor ids to device ids. Not locked because only
|
||||
* read on runtime.
|
||||
*/
|
||||
extern u16 *amd_iommu_alias_table;
|
||||
|
||||
/*
|
||||
* Reverse lookup table to find the IOMMU which translates a specific device.
|
||||
*/
|
||||
extern struct amd_iommu **amd_iommu_rlookup_table;
|
||||
|
||||
/* size of the dma_ops aperture as power of 2 */
|
||||
extern unsigned amd_iommu_aperture_order;
|
||||
|
||||
/* largest PCI device id we expect translation requests for */
|
||||
extern u16 amd_iommu_last_bdf;
|
||||
|
||||
/* data structures for protection domain handling */
|
||||
extern struct protection_domain **amd_iommu_pd_table;
|
||||
|
||||
/* allocation bitmap for domain ids */
|
||||
extern unsigned long *amd_iommu_pd_alloc_bitmap;
|
||||
|
||||
/* will be 1 if device isolation is enabled */
|
||||
extern int amd_iommu_isolate;
|
||||
|
||||
/* takes a PCI device id and prints it out in a readable form */
|
||||
static inline void print_devid(u16 devid, int nl)
|
||||
{
|
||||
int bus = devid >> 8;
|
||||
|
|
@ -241,4 +332,11 @@ static inline void print_devid(u16 devid, int nl)
|
|||
printk("\n");
|
||||
}
|
||||
|
||||
/* takes bus and device/function and returns the device id
|
||||
* FIXME: should that be in generic PCI code? */
|
||||
static inline u16 calc_devid(u8 bus, u8 devfn)
|
||||
{
|
||||
return (((u16)bus) << 8) | devfn;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
#include <linux/pm.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include <asm/alternative.h>
|
||||
#include <asm/fixmap.h>
|
||||
#include <asm/apicdef.h>
|
||||
#include <asm/processor.h>
|
||||
|
|
@ -10,7 +12,7 @@
|
|||
|
||||
#define ARCH_APICTIMER_STOPS_ON_C3 1
|
||||
|
||||
#define Dprintk(x...)
|
||||
#define Dprintk printk
|
||||
|
||||
/*
|
||||
* Debugging macros
|
||||
|
|
@ -35,7 +37,7 @@ extern void generic_apic_probe(void);
|
|||
|
||||
#ifdef CONFIG_X86_LOCAL_APIC
|
||||
|
||||
extern int apic_verbosity;
|
||||
extern unsigned int apic_verbosity;
|
||||
extern int local_apic_timer_c2_ok;
|
||||
|
||||
extern int ioapic_force;
|
||||
|
|
@ -48,7 +50,6 @@ extern int disable_apic;
|
|||
#include <asm/paravirt.h>
|
||||
#else
|
||||
#define apic_write native_apic_write
|
||||
#define apic_write_atomic native_apic_write_atomic
|
||||
#define apic_read native_apic_read
|
||||
#define setup_boot_clock setup_boot_APIC_clock
|
||||
#define setup_secondary_clock setup_secondary_APIC_clock
|
||||
|
|
@ -58,12 +59,11 @@ extern int is_vsmp_box(void);
|
|||
|
||||
static inline void native_apic_write(unsigned long reg, u32 v)
|
||||
{
|
||||
*((volatile u32 *)(APIC_BASE + reg)) = v;
|
||||
}
|
||||
volatile u32 *addr = (volatile u32 *)(APIC_BASE + reg);
|
||||
|
||||
static inline void native_apic_write_atomic(unsigned long reg, u32 v)
|
||||
{
|
||||
(void)xchg((u32 *)(APIC_BASE + reg), v);
|
||||
alternative_io("movl %0, %1", "xchgl %0, %1", X86_FEATURE_11AP,
|
||||
ASM_OUTPUT2("=r" (v), "=m" (*addr)),
|
||||
ASM_OUTPUT2("0" (v), "m" (*addr)));
|
||||
}
|
||||
|
||||
static inline u32 native_apic_read(unsigned long reg)
|
||||
|
|
@ -75,16 +75,6 @@ extern void apic_wait_icr_idle(void);
|
|||
extern u32 safe_apic_wait_icr_idle(void);
|
||||
extern int get_physical_broadcast(void);
|
||||
|
||||
#ifdef CONFIG_X86_GOOD_APIC
|
||||
# define FORCE_READ_AROUND_WRITE 0
|
||||
# define apic_read_around(x)
|
||||
# define apic_write_around(x, y) apic_write((x), (y))
|
||||
#else
|
||||
# define FORCE_READ_AROUND_WRITE 1
|
||||
# define apic_read_around(x) apic_read(x)
|
||||
# define apic_write_around(x, y) apic_write_atomic((x), (y))
|
||||
#endif
|
||||
|
||||
static inline void ack_APIC_irq(void)
|
||||
{
|
||||
/*
|
||||
|
|
@ -95,7 +85,7 @@ static inline void ack_APIC_irq(void)
|
|||
*/
|
||||
|
||||
/* Docs say use 0 for future compatibility */
|
||||
apic_write_around(APIC_EOI, 0);
|
||||
apic_write(APIC_EOI, 0);
|
||||
}
|
||||
|
||||
extern int lapic_get_maxlvt(void);
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ extern void intr_init_hook(void);
|
|||
extern void pre_intr_init_hook(void);
|
||||
extern void pre_setup_arch_hook(void);
|
||||
extern void trap_init_hook(void);
|
||||
extern void pre_time_init_hook(void);
|
||||
extern void time_init_hook(void);
|
||||
extern void mca_nmi_hook(void);
|
||||
|
||||
|
|
|
|||
|
|
@ -356,7 +356,7 @@ static inline unsigned long ffz(unsigned long word)
|
|||
* __fls: find last set bit in word
|
||||
* @word: The word to search
|
||||
*
|
||||
* Undefined if no zero exists, so code should check against ~0UL first.
|
||||
* Undefined if no set bit exists, so code should check against 0 first.
|
||||
*/
|
||||
static inline unsigned long __fls(unsigned long word)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@
|
|||
.endif
|
||||
.endm
|
||||
|
||||
.macro LOAD_ARGS offset
|
||||
.macro LOAD_ARGS offset, skiprax=0
|
||||
movq \offset(%rsp), %r11
|
||||
movq \offset+8(%rsp), %r10
|
||||
movq \offset+16(%rsp), %r9
|
||||
|
|
@ -113,7 +113,10 @@
|
|||
movq \offset+48(%rsp), %rdx
|
||||
movq \offset+56(%rsp), %rsi
|
||||
movq \offset+64(%rsp), %rdi
|
||||
.if \skiprax
|
||||
.else
|
||||
movq \offset+72(%rsp), %rax
|
||||
.endif
|
||||
.endm
|
||||
|
||||
#define REST_SKIP 6*8
|
||||
|
|
@ -165,4 +168,3 @@
|
|||
.macro icebp
|
||||
.byte 0xf1
|
||||
.endm
|
||||
|
||||
|
|
|
|||
|
|
@ -79,6 +79,7 @@
|
|||
#define X86_FEATURE_REP_GOOD (3*32+16) /* rep microcode works well on this CPU */
|
||||
#define X86_FEATURE_MFENCE_RDTSC (3*32+17) /* Mfence synchronizes RDTSC */
|
||||
#define X86_FEATURE_LFENCE_RDTSC (3*32+18) /* Lfence synchronizes RDTSC */
|
||||
#define X86_FEATURE_11AP (3*32+19) /* Bad local APIC aka 11AP */
|
||||
|
||||
/* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
|
||||
#define X86_FEATURE_XMM3 (4*32+ 0) /* Streaming SIMD Extensions-3 */
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ extern dma_addr_t bad_dma_address;
|
|||
extern int iommu_merge;
|
||||
extern struct device fallback_dev;
|
||||
extern int panic_on_overflow;
|
||||
extern int forbid_dac;
|
||||
extern int force_iommu;
|
||||
|
||||
struct dma_mapping_ops {
|
||||
|
|
|
|||
|
|
@ -90,6 +90,14 @@ static inline void e820_mark_nosave_regions(unsigned long limit_pfn)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MEMTEST
|
||||
extern void early_memtest(unsigned long start, unsigned long end);
|
||||
#else
|
||||
static inline void early_memtest(unsigned long start, unsigned long end)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
extern unsigned long end_user_pfn;
|
||||
|
||||
extern u64 find_e820_area(u64 start, u64 end, u64 size, u64 align);
|
||||
|
|
|
|||
|
|
@ -90,13 +90,13 @@ enum fixed_addresses {
|
|||
* 256 temporary boot-time mappings, used by early_ioremap(),
|
||||
* before ioremap() is functional.
|
||||
*
|
||||
* We round it up to the next 512 pages boundary so that we
|
||||
* We round it up to the next 256 pages boundary so that we
|
||||
* can have a single pgd entry and a single pte table:
|
||||
*/
|
||||
#define NR_FIX_BTMAPS 64
|
||||
#define FIX_BTMAPS_NESTING 4
|
||||
FIX_BTMAP_END = __end_of_permanent_fixed_addresses + 512 -
|
||||
(__end_of_permanent_fixed_addresses & 511),
|
||||
FIX_BTMAP_END = __end_of_permanent_fixed_addresses + 256 -
|
||||
(__end_of_permanent_fixed_addresses & 255),
|
||||
FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS*FIX_BTMAPS_NESTING - 1,
|
||||
FIX_WP_TEST,
|
||||
#ifdef CONFIG_ACPI
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
#define _ASM_X8664_GART_H 1
|
||||
|
||||
#include <asm/e820.h>
|
||||
#include <asm/iommu.h>
|
||||
|
||||
extern void set_up_gart_resume(u32, u32);
|
||||
|
||||
|
|
|
|||
|
|
@ -25,10 +25,18 @@ extern void gart_iommu_hole_init(void);
|
|||
static inline void early_gart_iommu_check(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void gart_iommu_init(void)
|
||||
{
|
||||
}
|
||||
static inline void gart_iommu_shutdown(void)
|
||||
{
|
||||
}
|
||||
static inline void gart_parse_options(char *options)
|
||||
{
|
||||
}
|
||||
static inline void gart_iommu_hole_init(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -63,9 +63,9 @@ static inline void init_apic_ldr(void)
|
|||
unsigned long val;
|
||||
int cpu = smp_processor_id();
|
||||
|
||||
apic_write_around(APIC_DFR, APIC_DFR_VALUE);
|
||||
apic_write(APIC_DFR, APIC_DFR_VALUE);
|
||||
val = calculate_ldr(cpu);
|
||||
apic_write_around(APIC_LDR, val);
|
||||
apic_write(APIC_LDR, val);
|
||||
}
|
||||
|
||||
static inline void setup_apic_routing(void)
|
||||
|
|
|
|||
|
|
@ -46,10 +46,10 @@ static inline void init_apic_ldr(void)
|
|||
{
|
||||
unsigned long val;
|
||||
|
||||
apic_write_around(APIC_DFR, APIC_DFR_VALUE);
|
||||
apic_write(APIC_DFR, APIC_DFR_VALUE);
|
||||
val = apic_read(APIC_LDR) & ~APIC_LDR_MASK;
|
||||
val |= SET_APIC_LOGICAL_ID(1UL << smp_processor_id());
|
||||
apic_write_around(APIC_LDR, val);
|
||||
apic_write(APIC_LDR, val);
|
||||
}
|
||||
|
||||
static inline int apic_id_registered(void)
|
||||
|
|
|
|||
|
|
@ -66,9 +66,9 @@ static inline void init_apic_ldr(void)
|
|||
unsigned long val;
|
||||
int cpu = smp_processor_id();
|
||||
|
||||
apic_write_around(APIC_DFR, APIC_DFR_VALUE);
|
||||
apic_write(APIC_DFR, APIC_DFR_VALUE);
|
||||
val = calculate_ldr(cpu);
|
||||
apic_write_around(APIC_LDR, val);
|
||||
apic_write(APIC_LDR, val);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_X86_GENERICARCH
|
||||
|
|
|
|||
|
|
@ -7,4 +7,6 @@
|
|||
/* Maximum 256 PCI busses, plus 1 ISA bus in each of 4 cabinets. */
|
||||
#define MAX_MP_BUSSES 260
|
||||
|
||||
extern void numaq_mps_oem_check(struct mp_config_table *mpc, char *oem,
|
||||
char *productid);
|
||||
#endif /* __ASM_MACH_MPSPEC_H */
|
||||
|
|
|
|||
|
|
@ -63,10 +63,10 @@ static inline void init_apic_ldr(void)
|
|||
* BIOS puts 5 CPUs in one APIC cluster, we're hosed. */
|
||||
BUG_ON(count >= XAPIC_DEST_CPUS_SHIFT);
|
||||
id = my_cluster | (1UL << count);
|
||||
apic_write_around(APIC_DFR, APIC_DFR_VALUE);
|
||||
apic_write(APIC_DFR, APIC_DFR_VALUE);
|
||||
val = apic_read(APIC_LDR) & ~APIC_LDR_MASK;
|
||||
val |= SET_APIC_LOGICAL_ID(id);
|
||||
apic_write_around(APIC_LDR, val);
|
||||
apic_write(APIC_LDR, val);
|
||||
}
|
||||
|
||||
static inline int multi_timer_check(int apic, int irq)
|
||||
|
|
|
|||
|
|
@ -1,5 +0,0 @@
|
|||
/*
|
||||
* VISWS uses the standard Linux entry points:
|
||||
*/
|
||||
|
||||
#include "../mach-default/entry_arch.h"
|
||||
|
|
@ -1 +0,0 @@
|
|||
#include "../mach-default/mach_apic.h"
|
||||
|
|
@ -1 +0,0 @@
|
|||
#include "../mach-default/mach_apicdef.h"
|
||||
|
|
@ -1 +0,0 @@
|
|||
#include "../mach-default/setup_arch.h"
|
||||
|
|
@ -1 +0,0 @@
|
|||
#include "../mach-default/smpboot_hooks.h"
|
||||
|
|
@ -205,7 +205,6 @@ struct pv_apic_ops {
|
|||
* these shouldn't be in this interface.
|
||||
*/
|
||||
void (*apic_write)(unsigned long reg, u32 v);
|
||||
void (*apic_write_atomic)(unsigned long reg, u32 v);
|
||||
u32 (*apic_read)(unsigned long reg);
|
||||
void (*setup_boot_clock)(void);
|
||||
void (*setup_secondary_clock)(void);
|
||||
|
|
@ -896,11 +895,6 @@ static inline void apic_write(unsigned long reg, u32 v)
|
|||
PVOP_VCALL2(pv_apic_ops.apic_write, reg, v);
|
||||
}
|
||||
|
||||
static inline void apic_write_atomic(unsigned long reg, u32 v)
|
||||
{
|
||||
PVOP_VCALL2(pv_apic_ops.apic_write_atomic, reg, v);
|
||||
}
|
||||
|
||||
static inline u32 apic_read(unsigned long reg)
|
||||
{
|
||||
return PVOP_CALL1(unsigned long, pv_apic_ops.apic_read, reg);
|
||||
|
|
@ -1396,8 +1390,8 @@ extern struct paravirt_patch_site __parainstructions[],
|
|||
* caller saved registers but the argument parameter */
|
||||
#define PV_SAVE_REGS "pushq %%rdi;"
|
||||
#define PV_RESTORE_REGS "popq %%rdi;"
|
||||
#define PV_EXTRA_CLOBBERS EXTRA_CLOBBERS, "rcx" , "rdx"
|
||||
#define PV_VEXTRA_CLOBBERS EXTRA_CLOBBERS, "rdi", "rcx" , "rdx"
|
||||
#define PV_EXTRA_CLOBBERS EXTRA_CLOBBERS, "rcx" , "rdx", "rsi"
|
||||
#define PV_VEXTRA_CLOBBERS EXTRA_CLOBBERS, "rdi", "rcx" , "rdx", "rsi"
|
||||
#define PV_FLAGS_ARG "D"
|
||||
#endif
|
||||
|
||||
|
|
@ -1489,8 +1483,26 @@ static inline unsigned long __raw_local_irq_save(void)
|
|||
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
#define PV_SAVE_REGS pushq %rax; pushq %rdi; pushq %rcx; pushq %rdx
|
||||
#define PV_RESTORE_REGS popq %rdx; popq %rcx; popq %rdi; popq %rax
|
||||
#define PV_SAVE_REGS \
|
||||
push %rax; \
|
||||
push %rcx; \
|
||||
push %rdx; \
|
||||
push %rsi; \
|
||||
push %rdi; \
|
||||
push %r8; \
|
||||
push %r9; \
|
||||
push %r10; \
|
||||
push %r11
|
||||
#define PV_RESTORE_REGS \
|
||||
pop %r11; \
|
||||
pop %r10; \
|
||||
pop %r9; \
|
||||
pop %r8; \
|
||||
pop %rdi; \
|
||||
pop %rsi; \
|
||||
pop %rdx; \
|
||||
pop %rcx; \
|
||||
pop %rax
|
||||
#define PARA_PATCH(struct, off) ((PARAVIRT_PATCH_##struct + (off)) / 8)
|
||||
#define PARA_SITE(ptype, clobbers, ops) _PVSITE(ptype, clobbers, ops, .quad, 8)
|
||||
#define PARA_INDIRECT(addr) *addr(%rip)
|
||||
|
|
|
|||
|
|
@ -22,6 +22,32 @@
|
|||
|
||||
DECLARE_PER_CPU(struct x8664_pda, pda);
|
||||
|
||||
/*
|
||||
* These are supposed to be implemented as a single instruction which
|
||||
* operates on the per-cpu data base segment. x86-64 doesn't have
|
||||
* that yet, so this is a fairly inefficient workaround for the
|
||||
* meantime. The single instruction is atomic with respect to
|
||||
* preemption and interrupts, so we need to explicitly disable
|
||||
* interrupts here to achieve the same effect. However, because it
|
||||
* can be used from within interrupt-disable/enable, we can't actually
|
||||
* disable interrupts; disabling preemption is enough.
|
||||
*/
|
||||
#define x86_read_percpu(var) \
|
||||
({ \
|
||||
typeof(per_cpu_var(var)) __tmp; \
|
||||
preempt_disable(); \
|
||||
__tmp = __get_cpu_var(var); \
|
||||
preempt_enable(); \
|
||||
__tmp; \
|
||||
})
|
||||
|
||||
#define x86_write_percpu(var, val) \
|
||||
do { \
|
||||
preempt_disable(); \
|
||||
__get_cpu_var(var) = (val); \
|
||||
preempt_enable(); \
|
||||
} while(0)
|
||||
|
||||
#else /* CONFIG_X86_64 */
|
||||
|
||||
#ifdef __ASSEMBLY__
|
||||
|
|
|
|||
|
|
@ -302,6 +302,14 @@ int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn,
|
|||
/* Install a pte for a particular vaddr in kernel space. */
|
||||
void set_pte_vaddr(unsigned long vaddr, pte_t pte);
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
extern void native_pagetable_setup_start(pgd_t *base);
|
||||
extern void native_pagetable_setup_done(pgd_t *base);
|
||||
#else
|
||||
static inline void native_pagetable_setup_start(pgd_t *base) {}
|
||||
static inline void native_pagetable_setup_done(pgd_t *base) {}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PARAVIRT
|
||||
#include <asm/paravirt.h>
|
||||
#else /* !CONFIG_PARAVIRT */
|
||||
|
|
@ -333,6 +341,16 @@ void set_pte_vaddr(unsigned long vaddr, pte_t pte);
|
|||
|
||||
#define pte_update(mm, addr, ptep) do { } while (0)
|
||||
#define pte_update_defer(mm, addr, ptep) do { } while (0)
|
||||
|
||||
static inline void __init paravirt_pagetable_setup_start(pgd_t *base)
|
||||
{
|
||||
native_pagetable_setup_start(base);
|
||||
}
|
||||
|
||||
static inline void __init paravirt_pagetable_setup_done(pgd_t *base)
|
||||
{
|
||||
native_pagetable_setup_done(base);
|
||||
}
|
||||
#endif /* CONFIG_PARAVIRT */
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
|
|
|||
|
|
@ -171,21 +171,6 @@ do { \
|
|||
*/
|
||||
#define update_mmu_cache(vma, address, pte) do { } while (0)
|
||||
|
||||
extern void native_pagetable_setup_start(pgd_t *base);
|
||||
extern void native_pagetable_setup_done(pgd_t *base);
|
||||
|
||||
#ifndef CONFIG_PARAVIRT
|
||||
static inline void __init paravirt_pagetable_setup_start(pgd_t *base)
|
||||
{
|
||||
native_pagetable_setup_start(base);
|
||||
}
|
||||
|
||||
static inline void __init paravirt_pagetable_setup_done(pgd_t *base)
|
||||
{
|
||||
native_pagetable_setup_done(base);
|
||||
}
|
||||
#endif /* !CONFIG_PARAVIRT */
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@
|
|||
extern pud_t level3_kernel_pgt[512];
|
||||
extern pud_t level3_ident_pgt[512];
|
||||
extern pmd_t level2_kernel_pgt[512];
|
||||
extern pmd_t level2_fixmap_pgt[512];
|
||||
extern pmd_t level2_ident_pgt[512];
|
||||
extern pgd_t init_level4_pgt[];
|
||||
|
||||
#define swapper_pg_dir init_level4_pgt
|
||||
|
|
|
|||
|
|
@ -722,8 +722,6 @@ static inline void __sti_mwait(unsigned long eax, unsigned long ecx)
|
|||
|
||||
extern void mwait_idle_with_hints(unsigned long eax, unsigned long ecx);
|
||||
|
||||
extern int force_mwait;
|
||||
|
||||
extern void select_idle_routine(const struct cpuinfo_x86 *c);
|
||||
|
||||
extern unsigned long boot_option_idle_override;
|
||||
|
|
|
|||
|
|
@ -73,11 +73,11 @@
|
|||
|
||||
#ifdef __x86_64__
|
||||
# define PTRACE_ARCH_PRCTL 30
|
||||
#else
|
||||
# define PTRACE_SYSEMU 31
|
||||
# define PTRACE_SYSEMU_SINGLESTEP 32
|
||||
#endif
|
||||
|
||||
#define PTRACE_SYSEMU 31
|
||||
#define PTRACE_SYSEMU_SINGLESTEP 32
|
||||
|
||||
#define PTRACE_SINGLEBLOCK 33 /* resume execution until next branch */
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
|
|
|||
|
|
@ -1,6 +1,15 @@
|
|||
#ifndef _ASM_X86_SEGMENT_H_
|
||||
#define _ASM_X86_SEGMENT_H_
|
||||
|
||||
/* Constructor for a conventional segment GDT (or LDT) entry */
|
||||
/* This is a macro so it can be used in initializers */
|
||||
#define GDT_ENTRY(flags, base, limit) \
|
||||
((((base) & 0xff000000ULL) << (56-24)) | \
|
||||
(((flags) & 0x0000f0ffULL) << 40) | \
|
||||
(((limit) & 0x000f0000ULL) << (48-16)) | \
|
||||
(((base) & 0x00ffffffULL) << 16) | \
|
||||
(((limit) & 0x0000ffffULL)))
|
||||
|
||||
/* Simple and small GDT entries for booting only */
|
||||
|
||||
#define GDT_ENTRY_BOOT_CS 2
|
||||
|
|
|
|||
|
|
@ -19,13 +19,28 @@ static inline int is_visws_box(void) { return 0; }
|
|||
/*
|
||||
* Any setup quirks to be performed?
|
||||
*/
|
||||
extern int (*arch_time_init_quirk)(void);
|
||||
extern int (*arch_pre_intr_init_quirk)(void);
|
||||
extern int (*arch_intr_init_quirk)(void);
|
||||
extern int (*arch_trap_init_quirk)(void);
|
||||
extern char * (*arch_memory_setup_quirk)(void);
|
||||
extern int (*mach_get_smp_config_quirk)(unsigned int early);
|
||||
extern int (*mach_find_smp_config_quirk)(unsigned int reserve);
|
||||
struct mpc_config_processor;
|
||||
struct mpc_config_bus;
|
||||
struct mp_config_oemtable;
|
||||
struct x86_quirks {
|
||||
int (*arch_pre_time_init)(void);
|
||||
int (*arch_time_init)(void);
|
||||
int (*arch_pre_intr_init)(void);
|
||||
int (*arch_intr_init)(void);
|
||||
int (*arch_trap_init)(void);
|
||||
char * (*arch_memory_setup)(void);
|
||||
int (*mach_get_smp_config)(unsigned int early);
|
||||
int (*mach_find_smp_config)(unsigned int reserve);
|
||||
|
||||
int *mpc_record;
|
||||
int (*mpc_apic_id)(struct mpc_config_processor *m);
|
||||
void (*mpc_oem_bus_info)(struct mpc_config_bus *m, char *name);
|
||||
void (*mpc_oem_pci_bus)(struct mpc_config_bus *m);
|
||||
void (*smp_read_mpc_oem)(struct mp_config_oemtable *oemtable,
|
||||
unsigned short oemsize);
|
||||
};
|
||||
|
||||
extern struct x86_quirks *x86_quirks;
|
||||
|
||||
#ifndef CONFIG_PARAVIRT
|
||||
#define paravirt_post_allocator_init() do {} while (0)
|
||||
|
|
@ -76,6 +91,7 @@ extern unsigned long init_pg_tables_start;
|
|||
extern unsigned long init_pg_tables_end;
|
||||
|
||||
#else
|
||||
void __init x86_64_init_pda(void);
|
||||
void __init x86_64_start_kernel(char *real_mode);
|
||||
void __init x86_64_start_reservations(char *real_mode_data);
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ extern cpumask_t cpu_callin_map;
|
|||
extern void (*mtrr_hook)(void);
|
||||
extern void zap_low_mappings(void);
|
||||
|
||||
extern int __cpuinit get_local_pda(int cpu);
|
||||
|
||||
extern int smp_num_siblings;
|
||||
extern unsigned int num_processors;
|
||||
extern cpumask_t cpu_initialized;
|
||||
|
|
|
|||
|
|
@ -45,12 +45,14 @@ extern int swiotlb_force;
|
|||
|
||||
#ifdef CONFIG_SWIOTLB
|
||||
extern int swiotlb;
|
||||
extern void pci_swiotlb_init(void);
|
||||
#else
|
||||
#define swiotlb 0
|
||||
static inline void pci_swiotlb_init(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
extern void pci_swiotlb_init(void);
|
||||
|
||||
static inline void dma_mark_clean(void *addr, size_t size) {}
|
||||
|
||||
#endif /* _ASM_SWIOTLB_H */
|
||||
|
|
|
|||
|
|
@ -75,9 +75,7 @@ struct thread_info {
|
|||
#define TIF_NEED_RESCHED 3 /* rescheduling necessary */
|
||||
#define TIF_SINGLESTEP 4 /* reenable singlestep on user return*/
|
||||
#define TIF_IRET 5 /* force IRET */
|
||||
#ifdef CONFIG_X86_32
|
||||
#define TIF_SYSCALL_EMU 6 /* syscall emulation active */
|
||||
#endif
|
||||
#define TIF_SYSCALL_AUDIT 7 /* syscall auditing active */
|
||||
#define TIF_SECCOMP 8 /* secure computing */
|
||||
#define TIF_MCE_NOTIFY 10 /* notify userspace of an MCE */
|
||||
|
|
@ -100,11 +98,7 @@ struct thread_info {
|
|||
#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP)
|
||||
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
|
||||
#define _TIF_IRET (1 << TIF_IRET)
|
||||
#ifdef CONFIG_X86_32
|
||||
#define _TIF_SYSCALL_EMU (1 << TIF_SYSCALL_EMU)
|
||||
#else
|
||||
#define _TIF_SYSCALL_EMU 0
|
||||
#endif
|
||||
#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
|
||||
#define _TIF_SECCOMP (1 << TIF_SECCOMP)
|
||||
#define _TIF_MCE_NOTIFY (1 << TIF_MCE_NOTIFY)
|
||||
|
|
@ -121,18 +115,27 @@ struct thread_info {
|
|||
#define _TIF_DS_AREA_MSR (1 << TIF_DS_AREA_MSR)
|
||||
#define _TIF_BTS_TRACE_TS (1 << TIF_BTS_TRACE_TS)
|
||||
|
||||
/* work to do in syscall_trace_enter() */
|
||||
#define _TIF_WORK_SYSCALL_ENTRY \
|
||||
(_TIF_SYSCALL_TRACE | _TIF_SYSCALL_EMU | \
|
||||
_TIF_SYSCALL_AUDIT | _TIF_SECCOMP | _TIF_SINGLESTEP)
|
||||
|
||||
/* work to do in syscall_trace_leave() */
|
||||
#define _TIF_WORK_SYSCALL_EXIT \
|
||||
(_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SINGLESTEP)
|
||||
|
||||
/* work to do on interrupt/exception return */
|
||||
#define _TIF_WORK_MASK \
|
||||
(0x0000FFFF & \
|
||||
~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP| \
|
||||
_TIF_SECCOMP|_TIF_SYSCALL_EMU))
|
||||
~(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT| \
|
||||
_TIF_SINGLESTEP|_TIF_SECCOMP|_TIF_SYSCALL_EMU))
|
||||
|
||||
/* work to do on any return to user space */
|
||||
#define _TIF_ALLWORK_MASK (0x0000FFFF & ~_TIF_SECCOMP)
|
||||
|
||||
/* Only used for 64 bit */
|
||||
#define _TIF_DO_NOTIFY_MASK \
|
||||
(_TIF_SIGPENDING|_TIF_SINGLESTEP|_TIF_MCE_NOTIFY|_TIF_HRTICK_RESCHED)
|
||||
(_TIF_SIGPENDING|_TIF_MCE_NOTIFY|_TIF_HRTICK_RESCHED)
|
||||
|
||||
/* flags to check in __switch_to() */
|
||||
#define _TIF_WORK_CTXSW \
|
||||
|
|
|
|||
66
include/asm-x86/traps.h
Normal file
66
include/asm-x86/traps.h
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
#ifndef _ASM_X86_TRAPS_H
|
||||
#define _ASM_X86_TRAPS_H
|
||||
|
||||
/* Common in X86_32 and X86_64 */
|
||||
asmlinkage void divide_error(void);
|
||||
asmlinkage void debug(void);
|
||||
asmlinkage void nmi(void);
|
||||
asmlinkage void int3(void);
|
||||
asmlinkage void overflow(void);
|
||||
asmlinkage void bounds(void);
|
||||
asmlinkage void invalid_op(void);
|
||||
asmlinkage void device_not_available(void);
|
||||
asmlinkage void coprocessor_segment_overrun(void);
|
||||
asmlinkage void invalid_TSS(void);
|
||||
asmlinkage void segment_not_present(void);
|
||||
asmlinkage void stack_segment(void);
|
||||
asmlinkage void general_protection(void);
|
||||
asmlinkage void page_fault(void);
|
||||
asmlinkage void coprocessor_error(void);
|
||||
asmlinkage void simd_coprocessor_error(void);
|
||||
asmlinkage void alignment_check(void);
|
||||
asmlinkage void spurious_interrupt_bug(void);
|
||||
#ifdef CONFIG_X86_MCE
|
||||
asmlinkage void machine_check(void);
|
||||
#endif /* CONFIG_X86_MCE */
|
||||
|
||||
void do_divide_error(struct pt_regs *, long);
|
||||
void do_overflow(struct pt_regs *, long);
|
||||
void do_bounds(struct pt_regs *, long);
|
||||
void do_coprocessor_segment_overrun(struct pt_regs *, long);
|
||||
void do_invalid_TSS(struct pt_regs *, long);
|
||||
void do_segment_not_present(struct pt_regs *, long);
|
||||
void do_stack_segment(struct pt_regs *, long);
|
||||
void do_alignment_check(struct pt_regs *, long);
|
||||
void do_invalid_op(struct pt_regs *, long);
|
||||
void do_general_protection(struct pt_regs *, long);
|
||||
void do_nmi(struct pt_regs *, long);
|
||||
|
||||
extern int panic_on_unrecovered_nmi;
|
||||
extern int kstack_depth_to_print;
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
|
||||
void do_iret_error(struct pt_regs *, long);
|
||||
void do_int3(struct pt_regs *, long);
|
||||
void do_debug(struct pt_regs *, long);
|
||||
void math_error(void __user *);
|
||||
void do_coprocessor_error(struct pt_regs *, long);
|
||||
void do_simd_coprocessor_error(struct pt_regs *, long);
|
||||
void do_spurious_interrupt_bug(struct pt_regs *, long);
|
||||
unsigned long patch_espfix_desc(unsigned long, unsigned long);
|
||||
asmlinkage void math_emulate(long);
|
||||
|
||||
#else /* CONFIG_X86_32 */
|
||||
|
||||
asmlinkage void double_fault(void);
|
||||
|
||||
asmlinkage void do_int3(struct pt_regs *, long);
|
||||
asmlinkage void do_stack_segment(struct pt_regs *, long);
|
||||
asmlinkage void do_debug(struct pt_regs *, unsigned long);
|
||||
asmlinkage void do_coprocessor_error(struct pt_regs *);
|
||||
asmlinkage void do_simd_coprocessor_error(struct pt_regs *);
|
||||
asmlinkage void do_spurious_interrupt_bug(struct pt_regs *);
|
||||
|
||||
#endif /* CONFIG_X86_32 */
|
||||
#endif /* _ASM_X86_TRAPS_H */
|
||||
68
include/asm-x86/uv/bios.h
Normal file
68
include/asm-x86/uv/bios.h
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
#ifndef _ASM_X86_BIOS_H
|
||||
#define _ASM_X86_BIOS_H
|
||||
|
||||
/*
|
||||
* BIOS layer definitions.
|
||||
*
|
||||
* Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <linux/rtc.h>
|
||||
|
||||
#define BIOS_FREQ_BASE 0x01000001
|
||||
|
||||
enum {
|
||||
BIOS_FREQ_BASE_PLATFORM = 0,
|
||||
BIOS_FREQ_BASE_INTERVAL_TIMER = 1,
|
||||
BIOS_FREQ_BASE_REALTIME_CLOCK = 2
|
||||
};
|
||||
|
||||
# define BIOS_CALL(result, a0, a1, a2, a3, a4, a5, a6, a7) \
|
||||
do { \
|
||||
/* XXX - the real call goes here */ \
|
||||
result.status = BIOS_STATUS_UNIMPLEMENTED; \
|
||||
isrv.v0 = 0; \
|
||||
isrv.v1 = 0; \
|
||||
} while (0)
|
||||
|
||||
enum {
|
||||
BIOS_STATUS_SUCCESS = 0,
|
||||
BIOS_STATUS_UNIMPLEMENTED = -1,
|
||||
BIOS_STATUS_EINVAL = -2,
|
||||
BIOS_STATUS_ERROR = -3
|
||||
};
|
||||
|
||||
struct uv_bios_retval {
|
||||
/*
|
||||
* A zero status value indicates call completed without error.
|
||||
* A negative status value indicates reason of call failure.
|
||||
* A positive status value indicates success but an
|
||||
* informational value should be printed (e.g., "reboot for
|
||||
* change to take effect").
|
||||
*/
|
||||
s64 status;
|
||||
u64 v0;
|
||||
u64 v1;
|
||||
u64 v2;
|
||||
};
|
||||
|
||||
extern long
|
||||
x86_bios_freq_base(unsigned long which, unsigned long *ticks_per_second,
|
||||
unsigned long *drift_info);
|
||||
extern const char *x86_bios_strerror(long status);
|
||||
|
||||
#endif /* _ASM_X86_BIOS_H */
|
||||
|
|
@ -36,4 +36,12 @@ extern const char VDSO32_PRELINK[];
|
|||
extern void __user __kernel_sigreturn;
|
||||
extern void __user __kernel_rt_sigreturn;
|
||||
|
||||
/*
|
||||
* These symbols are defined by vdso32.S to mark the bounds
|
||||
* of the ELF DSO images included therein.
|
||||
*/
|
||||
extern const char vdso32_int80_start, vdso32_int80_end;
|
||||
extern const char vdso32_syscall_start, vdso32_syscall_end;
|
||||
extern const char vdso32_sysenter_start, vdso32_sysenter_end;
|
||||
|
||||
#endif /* asm-x86/vdso.h */
|
||||
|
|
|
|||
|
|
@ -40,83 +40,157 @@
|
|||
#include <xen/interface/sched.h>
|
||||
#include <xen/interface/physdev.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) \
|
||||
({ \
|
||||
long __res; \
|
||||
asm volatile ( \
|
||||
"call %[call]" \
|
||||
: "=a" (__res) \
|
||||
: [call] "m" (hypercall_page[__HYPERVISOR_##name]) \
|
||||
: "memory" ); \
|
||||
__HYPERCALL_DECLS; \
|
||||
__HYPERCALL_0ARG(); \
|
||||
asm volatile (__HYPERCALL \
|
||||
: __HYPERCALL_0PARAM \
|
||||
: __HYPERCALL_ENTRY(name) \
|
||||
: __HYPERCALL_CLOBBER0); \
|
||||
(type)__res; \
|
||||
})
|
||||
|
||||
#define _hypercall1(type, name, a1) \
|
||||
({ \
|
||||
long __res, __ign1; \
|
||||
asm volatile ( \
|
||||
"call %[call]" \
|
||||
: "=a" (__res), "=b" (__ign1) \
|
||||
: "1" ((long)(a1)), \
|
||||
[call] "m" (hypercall_page[__HYPERVISOR_##name]) \
|
||||
: "memory" ); \
|
||||
__HYPERCALL_DECLS; \
|
||||
__HYPERCALL_1ARG(a1); \
|
||||
asm volatile (__HYPERCALL \
|
||||
: __HYPERCALL_1PARAM \
|
||||
: __HYPERCALL_ENTRY(name) \
|
||||
: __HYPERCALL_CLOBBER1); \
|
||||
(type)__res; \
|
||||
})
|
||||
|
||||
#define _hypercall2(type, name, a1, a2) \
|
||||
({ \
|
||||
long __res, __ign1, __ign2; \
|
||||
asm volatile ( \
|
||||
"call %[call]" \
|
||||
: "=a" (__res), "=b" (__ign1), "=c" (__ign2) \
|
||||
: "1" ((long)(a1)), "2" ((long)(a2)), \
|
||||
[call] "m" (hypercall_page[__HYPERVISOR_##name]) \
|
||||
: "memory" ); \
|
||||
__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) \
|
||||
({ \
|
||||
long __res, __ign1, __ign2, __ign3; \
|
||||
asm volatile ( \
|
||||
"call %[call]" \
|
||||
: "=a" (__res), "=b" (__ign1), "=c" (__ign2), \
|
||||
"=d" (__ign3) \
|
||||
: "1" ((long)(a1)), "2" ((long)(a2)), \
|
||||
"3" ((long)(a3)), \
|
||||
[call] "m" (hypercall_page[__HYPERVISOR_##name]) \
|
||||
: "memory" ); \
|
||||
__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) \
|
||||
({ \
|
||||
long __res, __ign1, __ign2, __ign3, __ign4; \
|
||||
asm volatile ( \
|
||||
"call %[call]" \
|
||||
: "=a" (__res), "=b" (__ign1), "=c" (__ign2), \
|
||||
"=d" (__ign3), "=S" (__ign4) \
|
||||
: "1" ((long)(a1)), "2" ((long)(a2)), \
|
||||
"3" ((long)(a3)), "4" ((long)(a4)), \
|
||||
[call] "m" (hypercall_page[__HYPERVISOR_##name]) \
|
||||
: "memory" ); \
|
||||
__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) \
|
||||
({ \
|
||||
long __res, __ign1, __ign2, __ign3, __ign4, __ign5; \
|
||||
asm volatile ( \
|
||||
"call %[call]" \
|
||||
: "=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)), \
|
||||
[call] "m" (hypercall_page[__HYPERVISOR_##name]) \
|
||||
: "memory" ); \
|
||||
__HYPERCALL_DECLS; \
|
||||
__HYPERCALL_5ARG(a1, a2, a3, a4, a5); \
|
||||
asm volatile (__HYPERCALL \
|
||||
: __HYPERCALL_5PARAM \
|
||||
: __HYPERCALL_ENTRY(name) \
|
||||
: __HYPERCALL_CLOBBER5); \
|
||||
(type)__res; \
|
||||
})
|
||||
|
||||
|
|
@ -152,6 +226,7 @@ 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,
|
||||
|
|
@ -162,6 +237,17 @@ HYPERVISOR_set_callbacks(unsigned long event_selector,
|
|||
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)
|
||||
|
|
@ -223,12 +309,12 @@ static inline int
|
|||
HYPERVISOR_update_va_mapping(unsigned long va, pte_t new_val,
|
||||
unsigned long flags)
|
||||
{
|
||||
unsigned long pte_hi = 0;
|
||||
#ifdef CONFIG_X86_PAE
|
||||
pte_hi = new_val.pte_high;
|
||||
#endif
|
||||
return _hypercall4(int, update_va_mapping, va,
|
||||
new_val.pte_low, pte_hi, 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);
|
||||
}
|
||||
|
||||
static inline int
|
||||
|
|
@ -281,12 +367,13 @@ static inline int
|
|||
HYPERVISOR_update_va_mapping_otherdomain(unsigned long va, pte_t new_val,
|
||||
unsigned long flags, domid_t domid)
|
||||
{
|
||||
unsigned long pte_hi = 0;
|
||||
#ifdef CONFIG_X86_PAE
|
||||
pte_hi = new_val.pte_high;
|
||||
#endif
|
||||
return _hypercall5(int, update_va_mapping_otherdomain, va,
|
||||
new_val.pte_low, pte_hi, flags, 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
|
||||
|
|
@ -301,6 +388,14 @@ 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 srec)
|
||||
{
|
||||
|
|
@ -327,14 +422,14 @@ MULTI_update_va_mapping(struct multicall_entry *mcl, unsigned long va,
|
|||
{
|
||||
mcl->op = __HYPERVISOR_update_va_mapping;
|
||||
mcl->args[0] = va;
|
||||
#ifdef CONFIG_X86_PAE
|
||||
mcl->args[1] = new_val.pte_low;
|
||||
mcl->args[2] = new_val.pte_high;
|
||||
#else
|
||||
mcl->args[1] = new_val.pte_low;
|
||||
mcl->args[2] = 0;
|
||||
#endif
|
||||
mcl->args[3] = flags;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
|
@ -354,15 +449,16 @@ MULTI_update_va_mapping_otherdomain(struct multicall_entry *mcl, unsigned long v
|
|||
{
|
||||
mcl->op = __HYPERVISOR_update_va_mapping_otherdomain;
|
||||
mcl->args[0] = va;
|
||||
#ifdef CONFIG_X86_PAE
|
||||
mcl->args[1] = new_val.pte_low;
|
||||
mcl->args[2] = new_val.pte_high;
|
||||
#else
|
||||
mcl->args[1] = new_val.pte_low;
|
||||
mcl->args[2] = 0;
|
||||
#endif
|
||||
mcl->args[3] = flags;
|
||||
mcl->args[4] = domid;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
|
@ -370,10 +466,15 @@ MULTI_update_descriptor(struct multicall_entry *mcl, u64 maddr,
|
|||
struct desc_struct desc)
|
||||
{
|
||||
mcl->op = __HYPERVISOR_update_descriptor;
|
||||
mcl->args[0] = maddr;
|
||||
mcl->args[1] = maddr >> 32;
|
||||
mcl->args[2] = desc.a;
|
||||
mcl->args[3] = desc.b;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
/******************************************************************************
|
||||
* arch-x86_32.h
|
||||
*
|
||||
* Guest OS interface to x86 32-bit Xen.
|
||||
* Guest OS interface to x86 Xen.
|
||||
*
|
||||
* Copyright (c) 2004, K A Fraser
|
||||
*/
|
||||
|
||||
#ifndef __XEN_PUBLIC_ARCH_X86_32_H__
|
||||
#define __XEN_PUBLIC_ARCH_X86_32_H__
|
||||
#ifndef __ASM_X86_XEN_INTERFACE_H
|
||||
#define __ASM_X86_XEN_INTERFACE_H
|
||||
|
||||
#ifdef __XEN__
|
||||
#define __DEFINE_GUEST_HANDLE(name, type) \
|
||||
|
|
@ -57,6 +57,17 @@ DEFINE_GUEST_HANDLE(long);
|
|||
DEFINE_GUEST_HANDLE(void);
|
||||
#endif
|
||||
|
||||
#ifndef HYPERVISOR_VIRT_START
|
||||
#define HYPERVISOR_VIRT_START mk_unsigned_long(__HYPERVISOR_VIRT_START)
|
||||
#endif
|
||||
|
||||
#ifndef machine_to_phys_mapping
|
||||
#define machine_to_phys_mapping ((unsigned long *)HYPERVISOR_VIRT_START)
|
||||
#endif
|
||||
|
||||
/* Maximum number of virtual CPUs in multi-processor guests. */
|
||||
#define MAX_VIRT_CPUS 32
|
||||
|
||||
/*
|
||||
* SEGMENT DESCRIPTOR TABLES
|
||||
*/
|
||||
|
|
@ -70,59 +81,22 @@ DEFINE_GUEST_HANDLE(void);
|
|||
#define FIRST_RESERVED_GDT_BYTE (FIRST_RESERVED_GDT_PAGE * 4096)
|
||||
#define FIRST_RESERVED_GDT_ENTRY (FIRST_RESERVED_GDT_BYTE / 8)
|
||||
|
||||
/*
|
||||
* 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"
|
||||
|
||||
/*
|
||||
* Virtual addresses beyond this are not modifiable by guest OSes. The
|
||||
* machine->physical mapping table starts at this address, read-only.
|
||||
*/
|
||||
#ifdef CONFIG_X86_PAE
|
||||
#define __HYPERVISOR_VIRT_START 0xF5800000
|
||||
#else
|
||||
#define __HYPERVISOR_VIRT_START 0xFC000000
|
||||
#endif
|
||||
|
||||
#ifndef HYPERVISOR_VIRT_START
|
||||
#define HYPERVISOR_VIRT_START mk_unsigned_long(__HYPERVISOR_VIRT_START)
|
||||
#endif
|
||||
|
||||
#ifndef machine_to_phys_mapping
|
||||
#define machine_to_phys_mapping ((unsigned long *)HYPERVISOR_VIRT_START)
|
||||
#endif
|
||||
|
||||
/* Maximum number of virtual CPUs in multi-processor guests. */
|
||||
#define MAX_VIRT_CPUS 32
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/*
|
||||
* 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: Noone 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? */
|
||||
|
|
@ -131,32 +105,21 @@ struct trap_info {
|
|||
};
|
||||
DEFINE_GUEST_HANDLE_STRUCT(trap_info);
|
||||
|
||||
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;
|
||||
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;
|
||||
};
|
||||
DEFINE_GUEST_HANDLE_STRUCT(cpu_user_regs);
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
typedef uint64_t tsc_timestamp_t; /* RDTSC timestamp */
|
||||
#ifdef CONFIG_X86_32
|
||||
#include "interface_32.h"
|
||||
#else
|
||||
#include "interface_64.h"
|
||||
#endif
|
||||
|
||||
#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.
|
||||
|
|
@ -173,33 +136,29 @@ struct vcpu_guest_context {
|
|||
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);
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
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;
|
||||
};
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
/*
|
||||
* Prefix forces emulation of some non-trapping instructions.
|
||||
|
|
@ -213,4 +172,4 @@ struct xen_callback {
|
|||
#define XEN_CPUID XEN_EMULATE_PREFIX "cpuid"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif /* __ASM_X86_XEN_INTERFACE_H */
|
||||
|
|
|
|||
97
include/asm-x86/xen/interface_32.h
Normal file
97
include/asm-x86/xen/interface_32.h
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
/******************************************************************************
|
||||
* 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"
|
||||
|
||||
/*
|
||||
* 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 */
|
||||
159
include/asm-x86/xen/interface_64.h
Normal file
159
include/asm-x86/xen/interface_64.h
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
#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
|
||||
|
||||
#ifndef HYPERVISOR_VIRT_START
|
||||
#define HYPERVISOR_VIRT_START mk_unsigned_long(__HYPERVISOR_VIRT_START)
|
||||
#define HYPERVISOR_VIRT_END mk_unsigned_long(__HYPERVISOR_VIRT_END)
|
||||
#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)>>3)
|
||||
#ifndef machine_to_phys_mapping
|
||||
#define machine_to_phys_mapping ((unsigned long *)HYPERVISOR_VIRT_START)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 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 */
|
||||
|
|
@ -148,13 +148,17 @@ static inline pte_t __pte_ma(pteval_t 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)
|
||||
|
||||
|
||||
xmaddr_t arbitrary_virt_to_machine(unsigned long address);
|
||||
xmaddr_t arbitrary_virt_to_machine(void *address);
|
||||
void make_lowmem_page_readonly(void *vaddr);
|
||||
void make_lowmem_page_readwrite(void *vaddr);
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ struct debugfs_blob_wrapper {
|
|||
unsigned long size;
|
||||
};
|
||||
|
||||
extern struct dentry *arch_debugfs_dir;
|
||||
|
||||
#if defined(CONFIG_DEBUG_FS)
|
||||
|
||||
/* declared over in file.c */
|
||||
|
|
|
|||
|
|
@ -5,11 +5,12 @@ extern struct console xenboot_console;
|
|||
|
||||
#ifdef CONFIG_HVC_XEN
|
||||
void xen_console_resume(void);
|
||||
#else
|
||||
static inline void xen_console_resume(void) { }
|
||||
#endif
|
||||
|
||||
void xen_raw_console_write(const char *str);
|
||||
void xen_raw_printk(const char *fmt, ...);
|
||||
#else
|
||||
static inline void xen_console_resume(void) { }
|
||||
static inline void xen_raw_console_write(const char *str) { }
|
||||
static inline void xen_raw_printk(const char *fmt, ...) { }
|
||||
#endif
|
||||
|
||||
#endif /* XEN_HVC_CONSOLE_H */
|
||||
|
|
|
|||
|
|
@ -82,9 +82,9 @@
|
|||
*/
|
||||
#define CALLBACKOP_register 0
|
||||
struct callback_register {
|
||||
uint16_t type;
|
||||
uint16_t flags;
|
||||
struct xen_callback address;
|
||||
uint16_t type;
|
||||
uint16_t flags;
|
||||
xen_callback_t address;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -11,4 +11,7 @@ void xen_post_suspend(int suspend_cancelled);
|
|||
void xen_mm_pin_all(void);
|
||||
void xen_mm_unpin_all(void);
|
||||
|
||||
void xen_timer_resume(void);
|
||||
void xen_arch_resume(void);
|
||||
|
||||
#endif /* INCLUDE_XEN_OPS_H */
|
||||
|
|
|
|||
Loading…
Reference in a new issue