aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/include/asm/xen
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/include/asm/xen')
-rw-r--r--arch/x86/include/asm/xen/hypercall.h39
-rw-r--r--arch/x86/include/asm/xen/hypervisor.h35
-rw-r--r--arch/x86/include/asm/xen/interface.h8
-rw-r--r--arch/x86/include/asm/xen/interface_32.h5
-rw-r--r--arch/x86/include/asm/xen/interface_64.h13
-rw-r--r--arch/x86/include/asm/xen/page.h67
-rw-r--r--arch/x86/include/asm/xen/pci.h81
7 files changed, 218 insertions, 30 deletions
diff --git a/arch/x86/include/asm/xen/hypercall.h b/arch/x86/include/asm/xen/hypercall.h
index 7fda040a76cd..d240ea950519 100644
--- a/arch/x86/include/asm/xen/hypercall.h
+++ b/arch/x86/include/asm/xen/hypercall.h
@@ -200,6 +200,23 @@ extern struct { char _entry[32]; } hypercall_page[];
200 (type)__res; \ 200 (type)__res; \
201}) 201})
202 202
203static inline long
204privcmd_call(unsigned call,
205 unsigned long a1, unsigned long a2,
206 unsigned long a3, unsigned long a4,
207 unsigned long a5)
208{
209 __HYPERCALL_DECLS;
210 __HYPERCALL_5ARG(a1, a2, a3, a4, a5);
211
212 asm volatile("call *%[call]"
213 : __HYPERCALL_5PARAM
214 : [call] "a" (&hypercall_page[call])
215 : __HYPERCALL_CLOBBER5);
216
217 return (long)__res;
218}
219
203static inline int 220static inline int
204HYPERVISOR_set_trap_table(struct trap_info *table) 221HYPERVISOR_set_trap_table(struct trap_info *table)
205{ 222{
@@ -270,7 +287,7 @@ HYPERVISOR_fpu_taskswitch(int set)
270static inline int 287static inline int
271HYPERVISOR_sched_op(int cmd, void *arg) 288HYPERVISOR_sched_op(int cmd, void *arg)
272{ 289{
273 return _hypercall2(int, sched_op_new, cmd, arg); 290 return _hypercall2(int, sched_op, cmd, arg);
274} 291}
275 292
276static inline long 293static inline long
@@ -405,10 +422,17 @@ HYPERVISOR_set_segment_base(int reg, unsigned long value)
405#endif 422#endif
406 423
407static inline int 424static inline int
408HYPERVISOR_suspend(unsigned long srec) 425HYPERVISOR_suspend(unsigned long start_info_mfn)
409{ 426{
410 return _hypercall3(int, sched_op, SCHEDOP_shutdown, 427 struct sched_shutdown r = { .reason = SHUTDOWN_suspend };
411 SHUTDOWN_suspend, srec); 428
429 /*
430 * For a PV guest the tools require that the start_info mfn be
431 * present in rdx/edx when the hypercall is made. Per the
432 * hypercall calling convention this is the third hypercall
433 * argument, which is start_info_mfn here.
434 */
435 return _hypercall3(int, sched_op, SCHEDOP_shutdown, &r, start_info_mfn);
412} 436}
413 437
414static inline int 438static inline int
@@ -423,6 +447,13 @@ HYPERVISOR_hvm_op(int op, void *arg)
423 return _hypercall2(unsigned long, hvm_op, op, arg); 447 return _hypercall2(unsigned long, hvm_op, op, arg);
424} 448}
425 449
450static inline int
451HYPERVISOR_tmem_op(
452 struct tmem_op *op)
453{
454 return _hypercall1(int, tmem_op, op);
455}
456
426static inline void 457static inline void
427MULTI_fpu_taskswitch(struct multicall_entry *mcl, int set) 458MULTI_fpu_taskswitch(struct multicall_entry *mcl, int set)
428{ 459{
diff --git a/arch/x86/include/asm/xen/hypervisor.h b/arch/x86/include/asm/xen/hypervisor.h
index 396ff4cc8ed4..66d0fff1ee84 100644
--- a/arch/x86/include/asm/xen/hypervisor.h
+++ b/arch/x86/include/asm/xen/hypervisor.h
@@ -37,4 +37,39 @@
37extern struct shared_info *HYPERVISOR_shared_info; 37extern struct shared_info *HYPERVISOR_shared_info;
38extern struct start_info *xen_start_info; 38extern struct start_info *xen_start_info;
39 39
40#include <asm/processor.h>
41
42static inline uint32_t xen_cpuid_base(void)
43{
44 uint32_t base, eax, ebx, ecx, edx;
45 char signature[13];
46
47 for (base = 0x40000000; base < 0x40010000; base += 0x100) {
48 cpuid(base, &eax, &ebx, &ecx, &edx);
49 *(uint32_t *)(signature + 0) = ebx;
50 *(uint32_t *)(signature + 4) = ecx;
51 *(uint32_t *)(signature + 8) = edx;
52 signature[12] = 0;
53
54 if (!strcmp("XenVMMXenVMM", signature) && ((eax - base) >= 2))
55 return base;
56 }
57
58 return 0;
59}
60
61#ifdef CONFIG_XEN
62extern bool xen_hvm_need_lapic(void);
63
64static inline bool xen_x2apic_para_available(void)
65{
66 return xen_hvm_need_lapic();
67}
68#else
69static inline bool xen_x2apic_para_available(void)
70{
71 return (xen_cpuid_base() != 0);
72}
73#endif
74
40#endif /* _ASM_X86_XEN_HYPERVISOR_H */ 75#endif /* _ASM_X86_XEN_HYPERVISOR_H */
diff --git a/arch/x86/include/asm/xen/interface.h b/arch/x86/include/asm/xen/interface.h
index e8506c1f0c55..5d4922ad4b9b 100644
--- a/arch/x86/include/asm/xen/interface.h
+++ b/arch/x86/include/asm/xen/interface.h
@@ -61,9 +61,9 @@ DEFINE_GUEST_HANDLE(void);
61#define HYPERVISOR_VIRT_START mk_unsigned_long(__HYPERVISOR_VIRT_START) 61#define HYPERVISOR_VIRT_START mk_unsigned_long(__HYPERVISOR_VIRT_START)
62#endif 62#endif
63 63
64#ifndef machine_to_phys_mapping 64#define MACH2PHYS_VIRT_START mk_unsigned_long(__MACH2PHYS_VIRT_START)
65#define machine_to_phys_mapping ((unsigned long *)HYPERVISOR_VIRT_START) 65#define MACH2PHYS_VIRT_END mk_unsigned_long(__MACH2PHYS_VIRT_END)
66#endif 66#define MACH2PHYS_NR_ENTRIES ((MACH2PHYS_VIRT_END-MACH2PHYS_VIRT_START)>>__MACH2PHYS_SHIFT)
67 67
68/* Maximum number of virtual CPUs in multi-processor guests. */ 68/* Maximum number of virtual CPUs in multi-processor guests. */
69#define MAX_VIRT_CPUS 32 69#define MAX_VIRT_CPUS 32
@@ -86,7 +86,7 @@ DEFINE_GUEST_HANDLE(void);
86 * The privilege level specifies which modes may enter a trap via a software 86 * The privilege level specifies which modes may enter a trap via a software
87 * interrupt. On x86/64, since rings 1 and 2 are unavailable, we allocate 87 * interrupt. On x86/64, since rings 1 and 2 are unavailable, we allocate
88 * privilege levels as follows: 88 * privilege levels as follows:
89 * Level == 0: Noone may enter 89 * Level == 0: No one may enter
90 * Level == 1: Kernel may enter 90 * Level == 1: Kernel may enter
91 * Level == 2: Kernel may enter 91 * Level == 2: Kernel may enter
92 * Level == 3: Everyone may enter 92 * Level == 3: Everyone may enter
diff --git a/arch/x86/include/asm/xen/interface_32.h b/arch/x86/include/asm/xen/interface_32.h
index 42a7e004ae5c..8413688b2571 100644
--- a/arch/x86/include/asm/xen/interface_32.h
+++ b/arch/x86/include/asm/xen/interface_32.h
@@ -32,6 +32,11 @@
32/* And the trap vector is... */ 32/* And the trap vector is... */
33#define TRAP_INSTR "int $0x82" 33#define TRAP_INSTR "int $0x82"
34 34
35#define __MACH2PHYS_VIRT_START 0xF5800000
36#define __MACH2PHYS_VIRT_END 0xF6800000
37
38#define __MACH2PHYS_SHIFT 2
39
35/* 40/*
36 * Virtual addresses beyond this are not modifiable by guest OSes. The 41 * Virtual addresses beyond this are not modifiable by guest OSes. The
37 * machine->physical mapping table starts at this address, read-only. 42 * machine->physical mapping table starts at this address, read-only.
diff --git a/arch/x86/include/asm/xen/interface_64.h b/arch/x86/include/asm/xen/interface_64.h
index 100d2662b97c..839a4811cf98 100644
--- a/arch/x86/include/asm/xen/interface_64.h
+++ b/arch/x86/include/asm/xen/interface_64.h
@@ -39,18 +39,7 @@
39#define __HYPERVISOR_VIRT_END 0xFFFF880000000000 39#define __HYPERVISOR_VIRT_END 0xFFFF880000000000
40#define __MACH2PHYS_VIRT_START 0xFFFF800000000000 40#define __MACH2PHYS_VIRT_START 0xFFFF800000000000
41#define __MACH2PHYS_VIRT_END 0xFFFF804000000000 41#define __MACH2PHYS_VIRT_END 0xFFFF804000000000
42 42#define __MACH2PHYS_SHIFT 3
43#ifndef HYPERVISOR_VIRT_START
44#define HYPERVISOR_VIRT_START mk_unsigned_long(__HYPERVISOR_VIRT_START)
45#define HYPERVISOR_VIRT_END mk_unsigned_long(__HYPERVISOR_VIRT_END)
46#endif
47
48#define MACH2PHYS_VIRT_START mk_unsigned_long(__MACH2PHYS_VIRT_START)
49#define MACH2PHYS_VIRT_END mk_unsigned_long(__MACH2PHYS_VIRT_END)
50#define MACH2PHYS_NR_ENTRIES ((MACH2PHYS_VIRT_END-MACH2PHYS_VIRT_START)>>3)
51#ifndef machine_to_phys_mapping
52#define machine_to_phys_mapping ((unsigned long *)HYPERVISOR_VIRT_START)
53#endif
54 43
55/* 44/*
56 * int HYPERVISOR_set_segment_base(unsigned int which, unsigned long base) 45 * int HYPERVISOR_set_segment_base(unsigned int which, unsigned long base)
diff --git a/arch/x86/include/asm/xen/page.h b/arch/x86/include/asm/xen/page.h
index bf5f7d32bd08..64a619d47d34 100644
--- a/arch/x86/include/asm/xen/page.h
+++ b/arch/x86/include/asm/xen/page.h
@@ -5,6 +5,7 @@
5#include <linux/types.h> 5#include <linux/types.h>
6#include <linux/spinlock.h> 6#include <linux/spinlock.h>
7#include <linux/pfn.h> 7#include <linux/pfn.h>
8#include <linux/mm.h>
8 9
9#include <asm/uaccess.h> 10#include <asm/uaccess.h>
10#include <asm/page.h> 11#include <asm/page.h>
@@ -28,23 +29,46 @@ typedef struct xpaddr {
28 29
29/**** MACHINE <-> PHYSICAL CONVERSION MACROS ****/ 30/**** MACHINE <-> PHYSICAL CONVERSION MACROS ****/
30#define INVALID_P2M_ENTRY (~0UL) 31#define INVALID_P2M_ENTRY (~0UL)
31#define FOREIGN_FRAME_BIT (1UL<<31) 32#define FOREIGN_FRAME_BIT (1UL<<(BITS_PER_LONG-1))
33#define IDENTITY_FRAME_BIT (1UL<<(BITS_PER_LONG-2))
32#define FOREIGN_FRAME(m) ((m) | FOREIGN_FRAME_BIT) 34#define FOREIGN_FRAME(m) ((m) | FOREIGN_FRAME_BIT)
35#define IDENTITY_FRAME(m) ((m) | IDENTITY_FRAME_BIT)
33 36
34/* Maximum amount of memory we can handle in a domain in pages */ 37/* Maximum amount of memory we can handle in a domain in pages */
35#define MAX_DOMAIN_PAGES \ 38#define MAX_DOMAIN_PAGES \
36 ((unsigned long)((u64)CONFIG_XEN_MAX_DOMAIN_MEMORY * 1024 * 1024 * 1024 / PAGE_SIZE)) 39 ((unsigned long)((u64)CONFIG_XEN_MAX_DOMAIN_MEMORY * 1024 * 1024 * 1024 / PAGE_SIZE))
37 40
41extern unsigned long *machine_to_phys_mapping;
42extern unsigned int machine_to_phys_order;
38 43
39extern unsigned long get_phys_to_machine(unsigned long pfn); 44extern unsigned long get_phys_to_machine(unsigned long pfn);
40extern void set_phys_to_machine(unsigned long pfn, unsigned long mfn); 45extern bool set_phys_to_machine(unsigned long pfn, unsigned long mfn);
41 46extern bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn);
47extern unsigned long set_phys_range_identity(unsigned long pfn_s,
48 unsigned long pfn_e);
49
50extern int m2p_add_override(unsigned long mfn, struct page *page,
51 bool clear_pte);
52extern int m2p_remove_override(struct page *page, bool clear_pte);
53extern struct page *m2p_find_override(unsigned long mfn);
54extern unsigned long m2p_find_override_pfn(unsigned long mfn, unsigned long pfn);
55
56#ifdef CONFIG_XEN_DEBUG_FS
57extern int p2m_dump_show(struct seq_file *m, void *v);
58#endif
42static inline unsigned long pfn_to_mfn(unsigned long pfn) 59static inline unsigned long pfn_to_mfn(unsigned long pfn)
43{ 60{
61 unsigned long mfn;
62
44 if (xen_feature(XENFEAT_auto_translated_physmap)) 63 if (xen_feature(XENFEAT_auto_translated_physmap))
45 return pfn; 64 return pfn;
46 65
47 return get_phys_to_machine(pfn) & ~FOREIGN_FRAME_BIT; 66 mfn = get_phys_to_machine(pfn);
67
68 if (mfn != INVALID_P2M_ENTRY)
69 mfn &= ~(FOREIGN_FRAME_BIT | IDENTITY_FRAME_BIT);
70
71 return mfn;
48} 72}
49 73
50static inline int phys_to_machine_mapping_valid(unsigned long pfn) 74static inline int phys_to_machine_mapping_valid(unsigned long pfn)
@@ -58,22 +82,44 @@ static inline int phys_to_machine_mapping_valid(unsigned long pfn)
58static inline unsigned long mfn_to_pfn(unsigned long mfn) 82static inline unsigned long mfn_to_pfn(unsigned long mfn)
59{ 83{
60 unsigned long pfn; 84 unsigned long pfn;
85 int ret = 0;
61 86
62 if (xen_feature(XENFEAT_auto_translated_physmap)) 87 if (xen_feature(XENFEAT_auto_translated_physmap))
63 return mfn; 88 return mfn;
64 89
65#if 0 90 if (unlikely((mfn >> machine_to_phys_order) != 0)) {
66 if (unlikely((mfn >> machine_to_phys_order) != 0)) 91 pfn = ~0;
67 return max_mapnr; 92 goto try_override;
68#endif 93 }
69
70 pfn = 0; 94 pfn = 0;
71 /* 95 /*
72 * The array access can fail (e.g., device space beyond end of RAM). 96 * The array access can fail (e.g., device space beyond end of RAM).
73 * In such cases it doesn't matter what we return (we return garbage), 97 * In such cases it doesn't matter what we return (we return garbage),
74 * but we must handle the fault without crashing! 98 * but we must handle the fault without crashing!
75 */ 99 */
76 __get_user(pfn, &machine_to_phys_mapping[mfn]); 100 ret = __get_user(pfn, &machine_to_phys_mapping[mfn]);
101try_override:
102 /* ret might be < 0 if there are no entries in the m2p for mfn */
103 if (ret < 0)
104 pfn = ~0;
105 else if (get_phys_to_machine(pfn) != mfn)
106 /*
107 * If this appears to be a foreign mfn (because the pfn
108 * doesn't map back to the mfn), then check the local override
109 * table to see if there's a better pfn to use.
110 *
111 * m2p_find_override_pfn returns ~0 if it doesn't find anything.
112 */
113 pfn = m2p_find_override_pfn(mfn, ~0);
114
115 /*
116 * pfn is ~0 if there are no entries in the m2p for mfn or if the
117 * entry doesn't map back to the mfn and m2p_override doesn't have a
118 * valid entry for it.
119 */
120 if (pfn == ~0 &&
121 get_phys_to_machine(mfn) == IDENTITY_FRAME(mfn))
122 pfn = mfn;
77 123
78 return pfn; 124 return pfn;
79} 125}
@@ -159,6 +205,7 @@ static inline pte_t __pte_ma(pteval_t x)
159 205
160#define pgd_val_ma(x) ((x).pgd) 206#define pgd_val_ma(x) ((x).pgd)
161 207
208void xen_set_domain_pte(pte_t *ptep, pte_t pteval, unsigned domid);
162 209
163xmaddr_t arbitrary_virt_to_machine(void *address); 210xmaddr_t arbitrary_virt_to_machine(void *address);
164unsigned long arbitrary_virt_to_mfn(void *vaddr); 211unsigned long arbitrary_virt_to_mfn(void *vaddr);
diff --git a/arch/x86/include/asm/xen/pci.h b/arch/x86/include/asm/xen/pci.h
new file mode 100644
index 000000000000..4fbda9a3f339
--- /dev/null
+++ b/arch/x86/include/asm/xen/pci.h
@@ -0,0 +1,81 @@
1#ifndef _ASM_X86_XEN_PCI_H
2#define _ASM_X86_XEN_PCI_H
3
4#if defined(CONFIG_PCI_XEN)
5extern int __init pci_xen_init(void);
6extern int __init pci_xen_hvm_init(void);
7#define pci_xen 1
8#else
9#define pci_xen 0
10#define pci_xen_init (0)
11static inline int pci_xen_hvm_init(void)
12{
13 return -1;
14}
15#endif
16#if defined(CONFIG_XEN_DOM0)
17void __init xen_setup_pirqs(void);
18int xen_find_device_domain_owner(struct pci_dev *dev);
19int xen_register_device_domain_owner(struct pci_dev *dev, uint16_t domain);
20int xen_unregister_device_domain_owner(struct pci_dev *dev);
21#else
22static inline void __init xen_setup_pirqs(void)
23{
24}
25static inline int xen_find_device_domain_owner(struct pci_dev *dev)
26{
27 return -1;
28}
29static inline int xen_register_device_domain_owner(struct pci_dev *dev,
30 uint16_t domain)
31{
32 return -1;
33}
34static inline int xen_unregister_device_domain_owner(struct pci_dev *dev)
35{
36 return -1;
37}
38#endif
39
40#if defined(CONFIG_PCI_MSI)
41#if defined(CONFIG_PCI_XEN)
42/* The drivers/pci/xen-pcifront.c sets this structure to
43 * its own functions.
44 */
45struct xen_pci_frontend_ops {
46 int (*enable_msi)(struct pci_dev *dev, int vectors[]);
47 void (*disable_msi)(struct pci_dev *dev);
48 int (*enable_msix)(struct pci_dev *dev, int vectors[], int nvec);
49 void (*disable_msix)(struct pci_dev *dev);
50};
51
52extern struct xen_pci_frontend_ops *xen_pci_frontend;
53
54static inline int xen_pci_frontend_enable_msi(struct pci_dev *dev,
55 int vectors[])
56{
57 if (xen_pci_frontend && xen_pci_frontend->enable_msi)
58 return xen_pci_frontend->enable_msi(dev, vectors);
59 return -ENODEV;
60}
61static inline void xen_pci_frontend_disable_msi(struct pci_dev *dev)
62{
63 if (xen_pci_frontend && xen_pci_frontend->disable_msi)
64 xen_pci_frontend->disable_msi(dev);
65}
66static inline int xen_pci_frontend_enable_msix(struct pci_dev *dev,
67 int vectors[], int nvec)
68{
69 if (xen_pci_frontend && xen_pci_frontend->enable_msix)
70 return xen_pci_frontend->enable_msix(dev, vectors, nvec);
71 return -ENODEV;
72}
73static inline void xen_pci_frontend_disable_msix(struct pci_dev *dev)
74{
75 if (xen_pci_frontend && xen_pci_frontend->disable_msix)
76 xen_pci_frontend->disable_msix(dev);
77}
78#endif /* CONFIG_PCI_XEN */
79#endif /* CONFIG_PCI_MSI */
80
81#endif /* _ASM_X86_XEN_PCI_H */