1 /*
2  * pv/domain.h
3  *
4  * PV guest interface definitions
5  *
6  * Copyright (C) 2017 Wei Liu <wei.liu2@citrix.com>
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms and conditions of the GNU General Public
10  * License, version 2, as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public
18  * License along with this program; If not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 #ifndef __X86_PV_DOMAIN_H__
22 #define __X86_PV_DOMAIN_H__
23 
24 #include <xen/sched.h>
25 
26 #ifdef CONFIG_PV32
27 extern int8_t opt_pv32;
28 #else
29 # define opt_pv32 false
30 #endif
31 
32 /*
33  * PCID values for the address spaces of 64-bit pv domains:
34  *
35  * We are using 4 PCID values for a 64 bit pv domain subject to XPTI:
36  * - hypervisor active and guest in kernel mode   PCID 0
37  * - hypervisor active and guest in user mode     PCID 1
38  * - guest active and in kernel mode              PCID 2
39  * - guest active and in user mode                PCID 3
40  *
41  * Without XPTI only 2 values are used:
42  * - guest in kernel mode                         PCID 0
43  * - guest in user mode                           PCID 1
44  */
45 
46 #define PCID_PV_PRIV      0x0000    /* Used for other domains, too. */
47 #define PCID_PV_USER      0x0001
48 #define PCID_PV_XPTI      0x0002    /* To be ORed to above values. */
49 
50 /*
51  * Return additional PCID specific cr3 bits.
52  *
53  * Note that X86_CR3_NOFLUSH will not be readable in cr3. Anyone consuming
54  * v->arch.cr3 should mask away X86_CR3_NOFLUSH and X86_CR3_PCIDMASK in case
55  * the value is used to address the root page table.
56  */
get_pcid_bits(const struct vcpu * v,bool is_xpti)57 static inline unsigned long get_pcid_bits(const struct vcpu *v, bool is_xpti)
58 {
59 #ifdef CONFIG_PV
60     return X86_CR3_NOFLUSH | (is_xpti ? PCID_PV_XPTI : 0) |
61            ((v->arch.flags & TF_kernel_mode) ? PCID_PV_PRIV : PCID_PV_USER);
62 #else
63     ASSERT_UNREACHABLE();
64     return 0;
65 #endif
66 }
67 
68 #ifdef CONFIG_PV
69 
70 void pv_vcpu_destroy(struct vcpu *v);
71 int pv_vcpu_initialise(struct vcpu *v);
72 void pv_domain_destroy(struct domain *d);
73 int pv_domain_initialise(struct domain *d);
74 
75 /*
76  * Bits which a PV guest can toggle in its view of cr4.  Some are loaded into
77  * hardware, while some are fully emulated.
78  */
79 #define PV_CR4_GUEST_MASK \
80     (X86_CR4_TSD | X86_CR4_DE | X86_CR4_FSGSBASE | X86_CR4_OSXSAVE)
81 
82 /* Bits which a PV guest may observe from the real hardware settings. */
83 #define PV_CR4_GUEST_VISIBLE_MASK \
84     (X86_CR4_PAE | X86_CR4_MCE | X86_CR4_OSFXSR | X86_CR4_OSXMMEXCPT)
85 
86 /* Given a new cr4 value, construct the resulting guest-visible cr4 value. */
87 unsigned long pv_fixup_guest_cr4(const struct vcpu *v, unsigned long cr4);
88 
89 /* Create a cr4 value to load into hardware, based on vcpu settings. */
90 unsigned long pv_make_cr4(const struct vcpu *v);
91 
92 bool xpti_pcid_enabled(void);
93 
94 #else  /* !CONFIG_PV */
95 
96 #include <xen/errno.h>
97 
pv_vcpu_destroy(struct vcpu * v)98 static inline void pv_vcpu_destroy(struct vcpu *v) {}
pv_vcpu_initialise(struct vcpu * v)99 static inline int pv_vcpu_initialise(struct vcpu *v) { return -EOPNOTSUPP; }
pv_domain_destroy(struct domain * d)100 static inline void pv_domain_destroy(struct domain *d) {}
pv_domain_initialise(struct domain * d)101 static inline int pv_domain_initialise(struct domain *d) { return -EOPNOTSUPP; }
102 
pv_make_cr4(const struct vcpu * v)103 static inline unsigned long pv_make_cr4(const struct vcpu *v) { return ~0ul; }
104 
105 #endif	/* CONFIG_PV */
106 
107 void paravirt_ctxt_switch_from(struct vcpu *v);
108 void paravirt_ctxt_switch_to(struct vcpu *v);
109 
110 #endif	/* __X86_PV_DOMAIN_H__ */
111 
112 /*
113  * Local variables:
114  * mode: C
115  * c-file-style: "BSD"
116  * c-basic-offset: 4
117  * tab-width: 4
118  * indent-tabs-mode: nil
119  * End:
120  */
121