1 1.1 riastrad /* $NetBSD: mpt.h,v 1.2 2021/12/18 23:45:31 riastradh Exp $ */ 2 1.1 riastrad 3 1.1 riastrad /* 4 1.1 riastrad * Copyright(c) 2011-2016 Intel Corporation. All rights reserved. 5 1.1 riastrad * 6 1.1 riastrad * Permission is hereby granted, free of charge, to any person obtaining a 7 1.1 riastrad * copy of this software and associated documentation files (the "Software"), 8 1.1 riastrad * to deal in the Software without restriction, including without limitation 9 1.1 riastrad * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 1.1 riastrad * and/or sell copies of the Software, and to permit persons to whom the 11 1.1 riastrad * Software is furnished to do so, subject to the following conditions: 12 1.1 riastrad * 13 1.1 riastrad * The above copyright notice and this permission notice (including the next 14 1.1 riastrad * paragraph) shall be included in all copies or substantial portions of the 15 1.1 riastrad * Software. 16 1.1 riastrad * 17 1.1 riastrad * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 1.1 riastrad * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 1.1 riastrad * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 1.1 riastrad * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 1.1 riastrad * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 1.1 riastrad * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 1.1 riastrad * SOFTWARE. 24 1.1 riastrad * 25 1.1 riastrad * Authors: 26 1.1 riastrad * Eddie Dong <eddie.dong (at) intel.com> 27 1.1 riastrad * Dexuan Cui 28 1.1 riastrad * Jike Song <jike.song (at) intel.com> 29 1.1 riastrad * 30 1.1 riastrad * Contributors: 31 1.1 riastrad * Zhi Wang <zhi.a.wang (at) intel.com> 32 1.1 riastrad * 33 1.1 riastrad */ 34 1.1 riastrad 35 1.1 riastrad #ifndef _GVT_MPT_H_ 36 1.1 riastrad #define _GVT_MPT_H_ 37 1.1 riastrad 38 1.1 riastrad /** 39 1.1 riastrad * DOC: Hypervisor Service APIs for GVT-g Core Logic 40 1.1 riastrad * 41 1.1 riastrad * This is the glue layer between specific hypervisor MPT modules and GVT-g core 42 1.1 riastrad * logic. Each kind of hypervisor MPT module provides a collection of function 43 1.1 riastrad * callbacks and will be attached to GVT host when the driver is loading. 44 1.1 riastrad * GVT-g core logic will call these APIs to request specific services from 45 1.1 riastrad * hypervisor. 46 1.1 riastrad */ 47 1.1 riastrad 48 1.1 riastrad /** 49 1.1 riastrad * intel_gvt_hypervisor_host_init - init GVT-g host side 50 1.1 riastrad * 51 1.1 riastrad * Returns: 52 1.1 riastrad * Zero on success, negative error code if failed 53 1.1 riastrad */ 54 1.1 riastrad static inline int intel_gvt_hypervisor_host_init(struct device *dev, 55 1.1 riastrad void *gvt, const void *ops) 56 1.1 riastrad { 57 1.1 riastrad if (!intel_gvt_host.mpt->host_init) 58 1.1 riastrad return -ENODEV; 59 1.1 riastrad 60 1.1 riastrad return intel_gvt_host.mpt->host_init(dev, gvt, ops); 61 1.1 riastrad } 62 1.1 riastrad 63 1.1 riastrad /** 64 1.1 riastrad * intel_gvt_hypervisor_host_exit - exit GVT-g host side 65 1.1 riastrad */ 66 1.1 riastrad static inline void intel_gvt_hypervisor_host_exit(struct device *dev) 67 1.1 riastrad { 68 1.1 riastrad /* optional to provide */ 69 1.1 riastrad if (!intel_gvt_host.mpt->host_exit) 70 1.1 riastrad return; 71 1.1 riastrad 72 1.1 riastrad intel_gvt_host.mpt->host_exit(dev); 73 1.1 riastrad } 74 1.1 riastrad 75 1.1 riastrad /** 76 1.1 riastrad * intel_gvt_hypervisor_attach_vgpu - call hypervisor to initialize vGPU 77 1.1 riastrad * related stuffs inside hypervisor. 78 1.1 riastrad * 79 1.1 riastrad * Returns: 80 1.1 riastrad * Zero on success, negative error code if failed. 81 1.1 riastrad */ 82 1.1 riastrad static inline int intel_gvt_hypervisor_attach_vgpu(struct intel_vgpu *vgpu) 83 1.1 riastrad { 84 1.1 riastrad /* optional to provide */ 85 1.1 riastrad if (!intel_gvt_host.mpt->attach_vgpu) 86 1.1 riastrad return 0; 87 1.1 riastrad 88 1.1 riastrad return intel_gvt_host.mpt->attach_vgpu(vgpu, &vgpu->handle); 89 1.1 riastrad } 90 1.1 riastrad 91 1.1 riastrad /** 92 1.1 riastrad * intel_gvt_hypervisor_detach_vgpu - call hypervisor to release vGPU 93 1.1 riastrad * related stuffs inside hypervisor. 94 1.1 riastrad * 95 1.1 riastrad * Returns: 96 1.1 riastrad * Zero on success, negative error code if failed. 97 1.1 riastrad */ 98 1.1 riastrad static inline void intel_gvt_hypervisor_detach_vgpu(struct intel_vgpu *vgpu) 99 1.1 riastrad { 100 1.1 riastrad /* optional to provide */ 101 1.1 riastrad if (!intel_gvt_host.mpt->detach_vgpu) 102 1.1 riastrad return; 103 1.1 riastrad 104 1.1 riastrad intel_gvt_host.mpt->detach_vgpu(vgpu); 105 1.1 riastrad } 106 1.1 riastrad 107 1.1 riastrad #define MSI_CAP_CONTROL(offset) (offset + 2) 108 1.1 riastrad #define MSI_CAP_ADDRESS(offset) (offset + 4) 109 1.1 riastrad #define MSI_CAP_DATA(offset) (offset + 8) 110 1.1 riastrad #define MSI_CAP_EN 0x1 111 1.1 riastrad 112 1.1 riastrad /** 113 1.1 riastrad * intel_gvt_hypervisor_inject_msi - inject a MSI interrupt into vGPU 114 1.1 riastrad * 115 1.1 riastrad * Returns: 116 1.1 riastrad * Zero on success, negative error code if failed. 117 1.1 riastrad */ 118 1.1 riastrad static inline int intel_gvt_hypervisor_inject_msi(struct intel_vgpu *vgpu) 119 1.1 riastrad { 120 1.1 riastrad unsigned long offset = vgpu->gvt->device_info.msi_cap_offset; 121 1.1 riastrad u16 control, data; 122 1.1 riastrad u32 addr; 123 1.1 riastrad int ret; 124 1.1 riastrad 125 1.1 riastrad control = *(u16 *)(vgpu_cfg_space(vgpu) + MSI_CAP_CONTROL(offset)); 126 1.1 riastrad addr = *(u32 *)(vgpu_cfg_space(vgpu) + MSI_CAP_ADDRESS(offset)); 127 1.1 riastrad data = *(u16 *)(vgpu_cfg_space(vgpu) + MSI_CAP_DATA(offset)); 128 1.1 riastrad 129 1.1 riastrad /* Do not generate MSI if MSIEN is disable */ 130 1.1 riastrad if (!(control & MSI_CAP_EN)) 131 1.1 riastrad return 0; 132 1.1 riastrad 133 1.1 riastrad if (WARN(control & GENMASK(15, 1), "only support one MSI format\n")) 134 1.1 riastrad return -EINVAL; 135 1.1 riastrad 136 1.1 riastrad trace_inject_msi(vgpu->id, addr, data); 137 1.1 riastrad 138 1.1 riastrad ret = intel_gvt_host.mpt->inject_msi(vgpu->handle, addr, data); 139 1.1 riastrad if (ret) 140 1.1 riastrad return ret; 141 1.1 riastrad return 0; 142 1.1 riastrad } 143 1.1 riastrad 144 1.1 riastrad /** 145 1.1 riastrad * intel_gvt_hypervisor_set_wp_page - translate a host VA into MFN 146 1.1 riastrad * @p: host kernel virtual address 147 1.1 riastrad * 148 1.1 riastrad * Returns: 149 1.1 riastrad * MFN on success, INTEL_GVT_INVALID_ADDR if failed. 150 1.1 riastrad */ 151 1.1 riastrad static inline unsigned long intel_gvt_hypervisor_virt_to_mfn(void *p) 152 1.1 riastrad { 153 1.1 riastrad return intel_gvt_host.mpt->from_virt_to_mfn(p); 154 1.1 riastrad } 155 1.1 riastrad 156 1.1 riastrad /** 157 1.1 riastrad * intel_gvt_hypervisor_enable_page_track - track a guest page 158 1.1 riastrad * @vgpu: a vGPU 159 1.1 riastrad * @gfn: the gfn of guest 160 1.1 riastrad * 161 1.1 riastrad * Returns: 162 1.1 riastrad * Zero on success, negative error code if failed. 163 1.1 riastrad */ 164 1.1 riastrad static inline int intel_gvt_hypervisor_enable_page_track( 165 1.1 riastrad struct intel_vgpu *vgpu, unsigned long gfn) 166 1.1 riastrad { 167 1.1 riastrad return intel_gvt_host.mpt->enable_page_track(vgpu->handle, gfn); 168 1.1 riastrad } 169 1.1 riastrad 170 1.1 riastrad /** 171 1.1 riastrad * intel_gvt_hypervisor_disable_page_track - untrack a guest page 172 1.1 riastrad * @vgpu: a vGPU 173 1.1 riastrad * @gfn: the gfn of guest 174 1.1 riastrad * 175 1.1 riastrad * Returns: 176 1.1 riastrad * Zero on success, negative error code if failed. 177 1.1 riastrad */ 178 1.1 riastrad static inline int intel_gvt_hypervisor_disable_page_track( 179 1.1 riastrad struct intel_vgpu *vgpu, unsigned long gfn) 180 1.1 riastrad { 181 1.1 riastrad return intel_gvt_host.mpt->disable_page_track(vgpu->handle, gfn); 182 1.1 riastrad } 183 1.1 riastrad 184 1.1 riastrad /** 185 1.1 riastrad * intel_gvt_hypervisor_read_gpa - copy data from GPA to host data buffer 186 1.1 riastrad * @vgpu: a vGPU 187 1.1 riastrad * @gpa: guest physical address 188 1.1 riastrad * @buf: host data buffer 189 1.1 riastrad * @len: data length 190 1.1 riastrad * 191 1.1 riastrad * Returns: 192 1.1 riastrad * Zero on success, negative error code if failed. 193 1.1 riastrad */ 194 1.1 riastrad static inline int intel_gvt_hypervisor_read_gpa(struct intel_vgpu *vgpu, 195 1.1 riastrad unsigned long gpa, void *buf, unsigned long len) 196 1.1 riastrad { 197 1.1 riastrad return intel_gvt_host.mpt->read_gpa(vgpu->handle, gpa, buf, len); 198 1.1 riastrad } 199 1.1 riastrad 200 1.1 riastrad /** 201 1.1 riastrad * intel_gvt_hypervisor_write_gpa - copy data from host data buffer to GPA 202 1.1 riastrad * @vgpu: a vGPU 203 1.1 riastrad * @gpa: guest physical address 204 1.1 riastrad * @buf: host data buffer 205 1.1 riastrad * @len: data length 206 1.1 riastrad * 207 1.1 riastrad * Returns: 208 1.1 riastrad * Zero on success, negative error code if failed. 209 1.1 riastrad */ 210 1.1 riastrad static inline int intel_gvt_hypervisor_write_gpa(struct intel_vgpu *vgpu, 211 1.1 riastrad unsigned long gpa, void *buf, unsigned long len) 212 1.1 riastrad { 213 1.1 riastrad return intel_gvt_host.mpt->write_gpa(vgpu->handle, gpa, buf, len); 214 1.1 riastrad } 215 1.1 riastrad 216 1.1 riastrad /** 217 1.1 riastrad * intel_gvt_hypervisor_gfn_to_mfn - translate a GFN to MFN 218 1.1 riastrad * @vgpu: a vGPU 219 1.1 riastrad * @gpfn: guest pfn 220 1.1 riastrad * 221 1.1 riastrad * Returns: 222 1.1 riastrad * MFN on success, INTEL_GVT_INVALID_ADDR if failed. 223 1.1 riastrad */ 224 1.1 riastrad static inline unsigned long intel_gvt_hypervisor_gfn_to_mfn( 225 1.1 riastrad struct intel_vgpu *vgpu, unsigned long gfn) 226 1.1 riastrad { 227 1.1 riastrad return intel_gvt_host.mpt->gfn_to_mfn(vgpu->handle, gfn); 228 1.1 riastrad } 229 1.1 riastrad 230 1.1 riastrad /** 231 1.1 riastrad * intel_gvt_hypervisor_dma_map_guest_page - setup dma map for guest page 232 1.1 riastrad * @vgpu: a vGPU 233 1.1 riastrad * @gfn: guest pfn 234 1.1 riastrad * @size: page size 235 1.1 riastrad * @dma_addr: retrieve allocated dma addr 236 1.1 riastrad * 237 1.1 riastrad * Returns: 238 1.1 riastrad * 0 on success, negative error code if failed. 239 1.1 riastrad */ 240 1.1 riastrad static inline int intel_gvt_hypervisor_dma_map_guest_page( 241 1.1 riastrad struct intel_vgpu *vgpu, unsigned long gfn, unsigned long size, 242 1.1 riastrad dma_addr_t *dma_addr) 243 1.1 riastrad { 244 1.1 riastrad return intel_gvt_host.mpt->dma_map_guest_page(vgpu->handle, gfn, size, 245 1.1 riastrad dma_addr); 246 1.1 riastrad } 247 1.1 riastrad 248 1.1 riastrad /** 249 1.1 riastrad * intel_gvt_hypervisor_dma_unmap_guest_page - cancel dma map for guest page 250 1.1 riastrad * @vgpu: a vGPU 251 1.1 riastrad * @dma_addr: the mapped dma addr 252 1.1 riastrad */ 253 1.1 riastrad static inline void intel_gvt_hypervisor_dma_unmap_guest_page( 254 1.1 riastrad struct intel_vgpu *vgpu, dma_addr_t dma_addr) 255 1.1 riastrad { 256 1.1 riastrad intel_gvt_host.mpt->dma_unmap_guest_page(vgpu->handle, dma_addr); 257 1.1 riastrad } 258 1.1 riastrad 259 1.1 riastrad /** 260 1.1 riastrad * intel_gvt_hypervisor_dma_pin_guest_page - pin guest dma buf 261 1.1 riastrad * @vgpu: a vGPU 262 1.1 riastrad * @dma_addr: guest dma addr 263 1.1 riastrad * 264 1.1 riastrad * Returns: 265 1.1 riastrad * 0 on success, negative error code if failed. 266 1.1 riastrad */ 267 1.1 riastrad static inline int 268 1.1 riastrad intel_gvt_hypervisor_dma_pin_guest_page(struct intel_vgpu *vgpu, 269 1.1 riastrad dma_addr_t dma_addr) 270 1.1 riastrad { 271 1.1 riastrad return intel_gvt_host.mpt->dma_pin_guest_page(vgpu->handle, dma_addr); 272 1.1 riastrad } 273 1.1 riastrad 274 1.1 riastrad /** 275 1.1 riastrad * intel_gvt_hypervisor_map_gfn_to_mfn - map a GFN region to MFN 276 1.1 riastrad * @vgpu: a vGPU 277 1.1 riastrad * @gfn: guest PFN 278 1.1 riastrad * @mfn: host PFN 279 1.1 riastrad * @nr: amount of PFNs 280 1.1 riastrad * @map: map or unmap 281 1.1 riastrad * 282 1.1 riastrad * Returns: 283 1.1 riastrad * Zero on success, negative error code if failed. 284 1.1 riastrad */ 285 1.1 riastrad static inline int intel_gvt_hypervisor_map_gfn_to_mfn( 286 1.1 riastrad struct intel_vgpu *vgpu, unsigned long gfn, 287 1.1 riastrad unsigned long mfn, unsigned int nr, 288 1.1 riastrad bool map) 289 1.1 riastrad { 290 1.1 riastrad /* a MPT implementation could have MMIO mapped elsewhere */ 291 1.1 riastrad if (!intel_gvt_host.mpt->map_gfn_to_mfn) 292 1.1 riastrad return 0; 293 1.1 riastrad 294 1.1 riastrad return intel_gvt_host.mpt->map_gfn_to_mfn(vgpu->handle, gfn, mfn, nr, 295 1.1 riastrad map); 296 1.1 riastrad } 297 1.1 riastrad 298 1.1 riastrad /** 299 1.1 riastrad * intel_gvt_hypervisor_set_trap_area - Trap a guest PA region 300 1.1 riastrad * @vgpu: a vGPU 301 1.1 riastrad * @start: the beginning of the guest physical address region 302 1.1 riastrad * @end: the end of the guest physical address region 303 1.1 riastrad * @map: map or unmap 304 1.1 riastrad * 305 1.1 riastrad * Returns: 306 1.1 riastrad * Zero on success, negative error code if failed. 307 1.1 riastrad */ 308 1.1 riastrad static inline int intel_gvt_hypervisor_set_trap_area( 309 1.1 riastrad struct intel_vgpu *vgpu, u64 start, u64 end, bool map) 310 1.1 riastrad { 311 1.1 riastrad /* a MPT implementation could have MMIO trapped elsewhere */ 312 1.1 riastrad if (!intel_gvt_host.mpt->set_trap_area) 313 1.1 riastrad return 0; 314 1.1 riastrad 315 1.1 riastrad return intel_gvt_host.mpt->set_trap_area(vgpu->handle, start, end, map); 316 1.1 riastrad } 317 1.1 riastrad 318 1.1 riastrad /** 319 1.1 riastrad * intel_gvt_hypervisor_set_opregion - Set opregion for guest 320 1.1 riastrad * @vgpu: a vGPU 321 1.1 riastrad * 322 1.1 riastrad * Returns: 323 1.1 riastrad * Zero on success, negative error code if failed. 324 1.1 riastrad */ 325 1.1 riastrad static inline int intel_gvt_hypervisor_set_opregion(struct intel_vgpu *vgpu) 326 1.1 riastrad { 327 1.1 riastrad if (!intel_gvt_host.mpt->set_opregion) 328 1.1 riastrad return 0; 329 1.1 riastrad 330 1.1 riastrad return intel_gvt_host.mpt->set_opregion(vgpu); 331 1.1 riastrad } 332 1.1 riastrad 333 1.1 riastrad /** 334 1.1 riastrad * intel_gvt_hypervisor_set_edid - Set EDID region for guest 335 1.1 riastrad * @vgpu: a vGPU 336 1.1 riastrad * @port_num: display port number 337 1.1 riastrad * 338 1.1 riastrad * Returns: 339 1.1 riastrad * Zero on success, negative error code if failed. 340 1.1 riastrad */ 341 1.1 riastrad static inline int intel_gvt_hypervisor_set_edid(struct intel_vgpu *vgpu, 342 1.1 riastrad int port_num) 343 1.1 riastrad { 344 1.1 riastrad if (!intel_gvt_host.mpt->set_edid) 345 1.1 riastrad return 0; 346 1.1 riastrad 347 1.1 riastrad return intel_gvt_host.mpt->set_edid(vgpu, port_num); 348 1.1 riastrad } 349 1.1 riastrad 350 1.1 riastrad /** 351 1.1 riastrad * intel_gvt_hypervisor_get_vfio_device - increase vfio device ref count 352 1.1 riastrad * @vgpu: a vGPU 353 1.1 riastrad * 354 1.1 riastrad * Returns: 355 1.1 riastrad * Zero on success, negative error code if failed. 356 1.1 riastrad */ 357 1.1 riastrad static inline int intel_gvt_hypervisor_get_vfio_device(struct intel_vgpu *vgpu) 358 1.1 riastrad { 359 1.1 riastrad if (!intel_gvt_host.mpt->get_vfio_device) 360 1.1 riastrad return 0; 361 1.1 riastrad 362 1.1 riastrad return intel_gvt_host.mpt->get_vfio_device(vgpu); 363 1.1 riastrad } 364 1.1 riastrad 365 1.1 riastrad /** 366 1.1 riastrad * intel_gvt_hypervisor_put_vfio_device - decrease vfio device ref count 367 1.1 riastrad * @vgpu: a vGPU 368 1.1 riastrad * 369 1.1 riastrad * Returns: 370 1.1 riastrad * Zero on success, negative error code if failed. 371 1.1 riastrad */ 372 1.1 riastrad static inline void intel_gvt_hypervisor_put_vfio_device(struct intel_vgpu *vgpu) 373 1.1 riastrad { 374 1.1 riastrad if (!intel_gvt_host.mpt->put_vfio_device) 375 1.1 riastrad return; 376 1.1 riastrad 377 1.1 riastrad intel_gvt_host.mpt->put_vfio_device(vgpu); 378 1.1 riastrad } 379 1.1 riastrad 380 1.1 riastrad /** 381 1.1 riastrad * intel_gvt_hypervisor_is_valid_gfn - check if a visible gfn 382 1.1 riastrad * @vgpu: a vGPU 383 1.1 riastrad * @gfn: guest PFN 384 1.1 riastrad * 385 1.1 riastrad * Returns: 386 1.1 riastrad * true on valid gfn, false on not. 387 1.1 riastrad */ 388 1.1 riastrad static inline bool intel_gvt_hypervisor_is_valid_gfn( 389 1.1 riastrad struct intel_vgpu *vgpu, unsigned long gfn) 390 1.1 riastrad { 391 1.1 riastrad if (!intel_gvt_host.mpt->is_valid_gfn) 392 1.1 riastrad return true; 393 1.1 riastrad 394 1.1 riastrad return intel_gvt_host.mpt->is_valid_gfn(vgpu->handle, gfn); 395 1.1 riastrad } 396 1.1 riastrad 397 1.1 riastrad int intel_gvt_register_hypervisor(struct intel_gvt_mpt *); 398 1.1 riastrad void intel_gvt_unregister_hypervisor(void); 399 1.1 riastrad 400 1.1 riastrad #endif /* _GVT_MPT_H_ */ 401