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