1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright © 2019 Oracle and/or its affiliates. All rights reserved. 4 * Copyright © 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. 5 * 6 * KVM Xen emulation 7 */ 8 9 #ifndef __ARCH_X86_KVM_XEN_H__ 10 #define __ARCH_X86_KVM_XEN_H__ 11 12 #include <asm/xen/hypervisor.h> 13 14 #ifdef CONFIG_KVM_XEN 15 #include <linux/jump_label_ratelimit.h> 16 17 extern struct static_key_false_deferred kvm_xen_enabled; 18 19 int __kvm_xen_has_interrupt(struct kvm_vcpu *vcpu); 20 void kvm_xen_inject_pending_events(struct kvm_vcpu *vcpu); 21 int kvm_xen_vcpu_set_attr(struct kvm_vcpu *vcpu, struct kvm_xen_vcpu_attr *data); 22 int kvm_xen_vcpu_get_attr(struct kvm_vcpu *vcpu, struct kvm_xen_vcpu_attr *data); 23 int kvm_xen_hvm_set_attr(struct kvm *kvm, struct kvm_xen_hvm_attr *data); 24 int kvm_xen_hvm_get_attr(struct kvm *kvm, struct kvm_xen_hvm_attr *data); 25 int kvm_xen_hvm_evtchn_send(struct kvm *kvm, struct kvm_irq_routing_xen_evtchn *evt); 26 int kvm_xen_write_hypercall_page(struct kvm_vcpu *vcpu, u64 data); 27 int kvm_xen_hvm_config(struct kvm *kvm, struct kvm_xen_hvm_config *xhc); 28 void kvm_xen_init_vm(struct kvm *kvm); 29 void kvm_xen_destroy_vm(struct kvm *kvm); 30 void kvm_xen_init_vcpu(struct kvm_vcpu *vcpu); 31 void kvm_xen_destroy_vcpu(struct kvm_vcpu *vcpu); 32 int kvm_xen_set_evtchn_fast(struct kvm_xen_evtchn *xe, 33 struct kvm *kvm); 34 int kvm_xen_setup_evtchn(struct kvm *kvm, 35 struct kvm_kernel_irq_routing_entry *e, 36 const struct kvm_irq_routing_entry *ue); 37 void kvm_xen_update_tsc_info(struct kvm_vcpu *vcpu); 38 39 static inline bool kvm_xen_msr_enabled(struct kvm *kvm) 40 { 41 return static_branch_unlikely(&kvm_xen_enabled.key) && 42 kvm->arch.xen_hvm_config.msr; 43 } 44 45 static inline bool kvm_xen_hypercall_enabled(struct kvm *kvm) 46 { 47 return static_branch_unlikely(&kvm_xen_enabled.key) && 48 (kvm->arch.xen_hvm_config.flags & 49 KVM_XEN_HVM_CONFIG_INTERCEPT_HCALL); 50 } 51 52 static inline int kvm_xen_has_interrupt(struct kvm_vcpu *vcpu) 53 { 54 if (static_branch_unlikely(&kvm_xen_enabled.key) && 55 vcpu->arch.xen.vcpu_info_cache.active && 56 vcpu->kvm->arch.xen.upcall_vector) 57 return __kvm_xen_has_interrupt(vcpu); 58 59 return 0; 60 } 61 62 static inline bool kvm_xen_has_pending_events(struct kvm_vcpu *vcpu) 63 { 64 return static_branch_unlikely(&kvm_xen_enabled.key) && 65 vcpu->arch.xen.evtchn_pending_sel; 66 } 67 68 static inline bool kvm_xen_timer_enabled(struct kvm_vcpu *vcpu) 69 { 70 return !!vcpu->arch.xen.timer_virq; 71 } 72 73 static inline int kvm_xen_has_pending_timer(struct kvm_vcpu *vcpu) 74 { 75 if (kvm_xen_hypercall_enabled(vcpu->kvm) && kvm_xen_timer_enabled(vcpu)) 76 return atomic_read(&vcpu->arch.xen.timer_pending); 77 78 return 0; 79 } 80 81 void kvm_xen_inject_timer_irqs(struct kvm_vcpu *vcpu); 82 #else 83 static inline int kvm_xen_write_hypercall_page(struct kvm_vcpu *vcpu, u64 data) 84 { 85 return 1; 86 } 87 88 static inline void kvm_xen_init_vm(struct kvm *kvm) 89 { 90 } 91 92 static inline void kvm_xen_destroy_vm(struct kvm *kvm) 93 { 94 } 95 96 static inline void kvm_xen_init_vcpu(struct kvm_vcpu *vcpu) 97 { 98 } 99 100 static inline void kvm_xen_destroy_vcpu(struct kvm_vcpu *vcpu) 101 { 102 } 103 104 static inline bool kvm_xen_msr_enabled(struct kvm *kvm) 105 { 106 return false; 107 } 108 109 static inline bool kvm_xen_hypercall_enabled(struct kvm *kvm) 110 { 111 return false; 112 } 113 114 static inline int kvm_xen_has_interrupt(struct kvm_vcpu *vcpu) 115 { 116 return 0; 117 } 118 119 static inline void kvm_xen_inject_pending_events(struct kvm_vcpu *vcpu) 120 { 121 } 122 123 static inline bool kvm_xen_has_pending_events(struct kvm_vcpu *vcpu) 124 { 125 return false; 126 } 127 128 static inline int kvm_xen_has_pending_timer(struct kvm_vcpu *vcpu) 129 { 130 return 0; 131 } 132 133 static inline void kvm_xen_inject_timer_irqs(struct kvm_vcpu *vcpu) 134 { 135 } 136 137 static inline bool kvm_xen_timer_enabled(struct kvm_vcpu *vcpu) 138 { 139 return false; 140 } 141 142 static inline void kvm_xen_update_tsc_info(struct kvm_vcpu *vcpu) 143 { 144 } 145 #endif 146 147 int kvm_xen_hypercall(struct kvm_vcpu *vcpu); 148 149 #include <asm/pvclock-abi.h> 150 #include <asm/xen/interface.h> 151 #include <xen/interface/vcpu.h> 152 153 void kvm_xen_update_runstate(struct kvm_vcpu *vcpu, int state); 154 155 static inline void kvm_xen_runstate_set_running(struct kvm_vcpu *vcpu) 156 { 157 kvm_xen_update_runstate(vcpu, RUNSTATE_running); 158 } 159 160 static inline void kvm_xen_runstate_set_preempted(struct kvm_vcpu *vcpu) 161 { 162 /* 163 * If the vCPU wasn't preempted but took a normal exit for 164 * some reason (hypercalls, I/O, etc.), that is accounted as 165 * still RUNSTATE_running, as the VMM is still operating on 166 * behalf of the vCPU. Only if the VMM does actually block 167 * does it need to enter RUNSTATE_blocked. 168 */ 169 if (WARN_ON_ONCE(!vcpu->preempted)) 170 return; 171 172 kvm_xen_update_runstate(vcpu, RUNSTATE_runnable); 173 } 174 175 /* 32-bit compatibility definitions, also used natively in 32-bit build */ 176 struct compat_arch_vcpu_info { 177 unsigned int cr2; 178 unsigned int pad[5]; 179 }; 180 181 struct compat_vcpu_info { 182 uint8_t evtchn_upcall_pending; 183 uint8_t evtchn_upcall_mask; 184 uint16_t pad; 185 uint32_t evtchn_pending_sel; 186 struct compat_arch_vcpu_info arch; 187 struct pvclock_vcpu_time_info time; 188 }; /* 64 bytes (x86) */ 189 190 struct compat_arch_shared_info { 191 unsigned int max_pfn; 192 unsigned int pfn_to_mfn_frame_list_list; 193 unsigned int nmi_reason; 194 unsigned int p2m_cr3; 195 unsigned int p2m_vaddr; 196 unsigned int p2m_generation; 197 uint32_t wc_sec_hi; 198 }; 199 200 struct compat_shared_info { 201 struct compat_vcpu_info vcpu_info[MAX_VIRT_CPUS]; 202 uint32_t evtchn_pending[32]; 203 uint32_t evtchn_mask[32]; 204 struct pvclock_wall_clock wc; 205 struct compat_arch_shared_info arch; 206 }; 207 208 #define COMPAT_EVTCHN_2L_NR_CHANNELS (8 * \ 209 sizeof_field(struct compat_shared_info, \ 210 evtchn_pending)) 211 struct compat_vcpu_runstate_info { 212 int state; 213 uint64_t state_entry_time; 214 uint64_t time[4]; 215 } __attribute__((packed)); 216 217 struct compat_sched_poll { 218 /* This is actually a guest virtual address which points to ports. */ 219 uint32_t ports; 220 unsigned int nr_ports; 221 uint64_t timeout; 222 }; 223 224 #endif /* __ARCH_X86_KVM_XEN_H__ */ 225