David Brazdil | 0f672f6 | 2019-12-10 10:32:29 +0000 | [diff] [blame^] | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
Andrew Scull | b4b6d4a | 2019-01-02 15:54:55 +0000 | [diff] [blame] | 2 | /* |
| 3 | * Copyright (C) 2016,2017 ARM Limited, All Rights Reserved. |
| 4 | * Author: Marc Zyngier <marc.zyngier@arm.com> |
Andrew Scull | b4b6d4a | 2019-01-02 15:54:55 +0000 | [diff] [blame] | 5 | */ |
| 6 | |
| 7 | #ifndef __LINUX_IRQCHIP_ARM_GIC_V4_H |
| 8 | #define __LINUX_IRQCHIP_ARM_GIC_V4_H |
| 9 | |
| 10 | struct its_vpe; |
| 11 | |
| 12 | /* |
| 13 | * Maximum number of ITTs when GITS_TYPER.VMOVP == 0, using the |
| 14 | * ITSList mechanism to perform inter-ITS synchronization. |
| 15 | */ |
| 16 | #define GICv4_ITS_LIST_MAX 16 |
| 17 | |
| 18 | /* Embedded in kvm.arch */ |
| 19 | struct its_vm { |
| 20 | struct fwnode_handle *fwnode; |
| 21 | struct irq_domain *domain; |
| 22 | struct page *vprop_page; |
| 23 | struct its_vpe **vpes; |
| 24 | int nr_vpes; |
| 25 | irq_hw_number_t db_lpi_base; |
| 26 | unsigned long *db_bitmap; |
| 27 | int nr_db_lpis; |
| 28 | u32 vlpi_count[GICv4_ITS_LIST_MAX]; |
| 29 | }; |
| 30 | |
| 31 | /* Embedded in kvm_vcpu.arch */ |
| 32 | struct its_vpe { |
| 33 | struct page *vpt_page; |
| 34 | struct its_vm *its_vm; |
| 35 | /* Doorbell interrupt */ |
| 36 | int irq; |
| 37 | irq_hw_number_t vpe_db_lpi; |
| 38 | /* VPE proxy mapping */ |
| 39 | int vpe_proxy_event; |
| 40 | /* |
| 41 | * This collection ID is used to indirect the target |
| 42 | * redistributor for this VPE. The ID itself isn't involved in |
| 43 | * programming of the ITS. |
| 44 | */ |
| 45 | u16 col_idx; |
| 46 | /* Unique (system-wide) VPE identifier */ |
| 47 | u16 vpe_id; |
| 48 | /* Implementation Defined Area Invalid */ |
| 49 | bool idai; |
| 50 | /* Pending VLPIs on schedule out? */ |
| 51 | bool pending_last; |
| 52 | }; |
| 53 | |
| 54 | /* |
| 55 | * struct its_vlpi_map: structure describing the mapping of a |
| 56 | * VLPI. Only to be interpreted in the context of a physical interrupt |
| 57 | * it complements. To be used as the vcpu_info passed to |
| 58 | * irq_set_vcpu_affinity(). |
| 59 | * |
| 60 | * @vm: Pointer to the GICv4 notion of a VM |
| 61 | * @vpe: Pointer to the GICv4 notion of a virtual CPU (VPE) |
| 62 | * @vintid: Virtual LPI number |
| 63 | * @properties: Priority and enable bits (as written in the prop table) |
| 64 | * @db_enabled: Is the VPE doorbell to be generated? |
| 65 | */ |
| 66 | struct its_vlpi_map { |
| 67 | struct its_vm *vm; |
| 68 | struct its_vpe *vpe; |
| 69 | u32 vintid; |
| 70 | u8 properties; |
| 71 | bool db_enabled; |
| 72 | }; |
| 73 | |
| 74 | enum its_vcpu_info_cmd_type { |
| 75 | MAP_VLPI, |
| 76 | GET_VLPI, |
| 77 | PROP_UPDATE_VLPI, |
| 78 | PROP_UPDATE_AND_INV_VLPI, |
| 79 | SCHEDULE_VPE, |
| 80 | DESCHEDULE_VPE, |
| 81 | INVALL_VPE, |
| 82 | }; |
| 83 | |
| 84 | struct its_cmd_info { |
| 85 | enum its_vcpu_info_cmd_type cmd_type; |
| 86 | union { |
| 87 | struct its_vlpi_map *map; |
| 88 | u8 config; |
| 89 | }; |
| 90 | }; |
| 91 | |
| 92 | int its_alloc_vcpu_irqs(struct its_vm *vm); |
| 93 | void its_free_vcpu_irqs(struct its_vm *vm); |
| 94 | int its_schedule_vpe(struct its_vpe *vpe, bool on); |
| 95 | int its_invall_vpe(struct its_vpe *vpe); |
| 96 | int its_map_vlpi(int irq, struct its_vlpi_map *map); |
| 97 | int its_get_vlpi(int irq, struct its_vlpi_map *map); |
| 98 | int its_unmap_vlpi(int irq); |
| 99 | int its_prop_update_vlpi(int irq, u8 config, bool inv); |
| 100 | |
| 101 | struct irq_domain_ops; |
| 102 | int its_init_v4(struct irq_domain *domain, const struct irq_domain_ops *ops); |
| 103 | |
| 104 | #endif |