forked from torvalds/linux
Permalink
Show file tree
Hide file tree
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
RISC-V: KVM: Initial skeletal support for in-kernel AIA irqchip
To incrementally implement in-kernel AIA irqchip support, we first add minimal skeletal support which only compiles and detects AIA hardware support at boot-time but does not provide any in-kernel irqchip support. Signed-off-by: Anup Patel <anup.patel@wdc.com>
- Loading branch information
Showing
11 changed files
with
452 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,112 @@ | ||
| /* SPDX-License-Identifier: GPL-2.0-only */ | ||
| /* | ||
| * Copyright (C) 2021 Western Digital Corporation or its affiliates. | ||
| * | ||
| * Authors: | ||
| * Anup Patel <anup.patel@wdc.com> | ||
| */ | ||
|
|
||
| #ifndef __KVM_RISCV_AIA_H | ||
| #define __KVM_RISCV_AIA_H | ||
|
|
||
| #include <linux/jump_label.h> | ||
| #include <linux/kvm_types.h> | ||
|
|
||
| struct kvm_aia { | ||
| bool in_kernel; | ||
| }; | ||
|
|
||
| struct kvm_vcpu_aia { | ||
| }; | ||
|
|
||
| #define irqchip_in_kernel(k) (!!((k)->arch.aia.in_kernel)) | ||
|
|
||
| extern unsigned int kvm_riscv_aia_nr_guests; | ||
| extern unsigned int kvm_riscv_aia_max_ids; | ||
| DECLARE_STATIC_KEY_FALSE(kvm_riscv_aia_available); | ||
| #define kvm_riscv_aia_available() \ | ||
| static_branch_unlikely(&kvm_riscv_aia_available) | ||
|
|
||
| static inline void kvm_riscv_vcpu_aia_flush_interrupts(struct kvm_vcpu *vcpu) | ||
| { | ||
| } | ||
|
|
||
| static inline void kvm_riscv_vcpu_aia_sync_interrupts(struct kvm_vcpu *vcpu) | ||
| { | ||
| } | ||
|
|
||
| static inline bool kvm_riscv_vcpu_aia_has_interrupts(struct kvm_vcpu *vcpu, | ||
| u64 mask) | ||
| { | ||
| return false; | ||
| } | ||
|
|
||
| static inline void kvm_riscv_vcpu_aia_update_hvip(struct kvm_vcpu *vcpu) | ||
| { | ||
| } | ||
|
|
||
| static inline void kvm_riscv_vcpu_aia_reset(struct kvm_vcpu *vcpu) | ||
| { | ||
| } | ||
|
|
||
| static inline int kvm_riscv_vcpu_aia_init(struct kvm_vcpu *vcpu) | ||
| { | ||
| return 0; | ||
| } | ||
|
|
||
| static inline void kvm_riscv_vcpu_aia_deinit(struct kvm_vcpu *vcpu) | ||
| { | ||
| } | ||
|
|
||
| static inline void kvm_riscv_vcpu_aia_load(struct kvm_vcpu *vcpu, int cpu) | ||
| { | ||
| } | ||
|
|
||
| static inline void kvm_riscv_vcpu_aia_put(struct kvm_vcpu *vcpu) | ||
| { | ||
| } | ||
|
|
||
| static inline int kvm_riscv_vcpu_aia_get_csr(struct kvm_vcpu *vcpu, | ||
| unsigned long reg_num, | ||
| unsigned long *out_val) | ||
| { | ||
| *out_val = 0; | ||
| return 0; | ||
| } | ||
|
|
||
| static inline int kvm_riscv_vcpu_aia_set_csr(struct kvm_vcpu *vcpu, | ||
| unsigned long reg_num, | ||
| unsigned long val) | ||
| { | ||
| return 0; | ||
| } | ||
|
|
||
| #define KVM_RISCV_VCPU_AIA_CSR_FUNCS | ||
|
|
||
| static inline int kvm_riscv_aia_inject_msi(struct kvm *kvm, | ||
| struct kvm_msi *msi) | ||
| { | ||
| return 0; | ||
| } | ||
|
|
||
| static inline int kvm_riscv_aia_inject_irq(struct kvm *kvm, | ||
| unsigned int irq, bool level) | ||
| { | ||
| return 0; | ||
| } | ||
|
|
||
| static inline void kvm_riscv_aia_init_vm(struct kvm *kvm) | ||
| { | ||
| } | ||
|
|
||
| static inline void kvm_riscv_aia_destroy_vm(struct kvm *kvm) | ||
| { | ||
| } | ||
|
|
||
| unsigned long kvm_riscv_aia_config(void); | ||
| void kvm_riscv_aia_enable(void); | ||
| void kvm_riscv_aia_disable(void); | ||
| int kvm_riscv_aia_init(void); | ||
| void kvm_riscv_aia_exit(void); | ||
|
|
||
| #endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,101 @@ | ||
| // SPDX-License-Identifier: GPL-2.0 | ||
| /* | ||
| * Copyright (C) 2021 Western Digital Corporation or its affiliates. | ||
| * | ||
| * Authors: | ||
| * Anup Patel <anup.patel@wdc.com> | ||
| */ | ||
|
|
||
| #include <linux/bitops.h> | ||
| #include <linux/irqchip/riscv-imsic.h> | ||
| #include <linux/kvm_host.h> | ||
| #include <asm/hwcap.h> | ||
|
|
||
| unsigned int kvm_riscv_aia_nr_guests; | ||
| unsigned int kvm_riscv_aia_max_ids; | ||
| DEFINE_STATIC_KEY_FALSE(kvm_riscv_aia_available); | ||
|
|
||
| static inline void aia_set_hvictl(bool ext_irq_pending) | ||
| { | ||
| unsigned long hvictl; | ||
|
|
||
| /* | ||
| * HVICTL.IID == 9 and HVICTL.IPRIO == 0 represents | ||
| * no interupt in HVICTL. | ||
| */ | ||
|
|
||
| hvictl = (IRQ_S_EXT << HVICTL_IID_SHIFT) & HVICTL_IID; | ||
| hvictl |= (ext_irq_pending) ? 1 : 0; | ||
| csr_write(CSR_HVICTL, hvictl); | ||
| } | ||
|
|
||
| unsigned long kvm_riscv_aia_config(void) | ||
| { | ||
| unsigned long ret = 0; | ||
|
|
||
| if (!kvm_riscv_aia_available()) | ||
| return 0; | ||
|
|
||
| ret = KVM_REG_RISCV_CONFIG_AIA_SUPPORTED; | ||
| ret |= (kvm_riscv_aia_nr_guests & | ||
| KVM_REG_RISCV_CONFIG_AIA_NR_GUESTS_MASK) << | ||
| KVM_REG_RISCV_CONFIG_AIA_NR_GUESTS_SHIFT; | ||
|
|
||
| return ret; | ||
| } | ||
|
|
||
| void kvm_riscv_aia_enable(void) | ||
| { | ||
| if (!kvm_riscv_aia_available()) | ||
| return; | ||
|
|
||
| aia_set_hvictl(false); | ||
| csr_write(CSR_HVIPRIO1, 0x0); | ||
| csr_write(CSR_HVIPRIO2, 0x0); | ||
| #ifndef CONFIG_64BIT | ||
| csr_write(CSR_HVIPH, 0x0); | ||
| csr_write(CSR_HIDELEGH, 0x0); | ||
| csr_write(CSR_HVIPRIO1H, 0x0); | ||
| csr_write(CSR_HVIPRIO2H, 0x0); | ||
| #endif | ||
| } | ||
|
|
||
| void kvm_riscv_aia_disable(void) | ||
| { | ||
| if (!kvm_riscv_aia_available()) | ||
| return; | ||
|
|
||
| aia_set_hvictl(false); | ||
| } | ||
|
|
||
| int kvm_riscv_aia_init(void) | ||
| { | ||
| unsigned int hgeie_bits; | ||
|
|
||
| if (!riscv_aia_available) | ||
| return -ENODEV; | ||
|
|
||
| /* Figure-out number of bits in HGEIE */ | ||
| csr_write(CSR_HGEIE, -1UL); | ||
| hgeie_bits = fls_long(csr_read(CSR_HGEIE)); | ||
| csr_write(CSR_HGEIE, 0); | ||
|
|
||
| /* Find number of guest files */ | ||
| kvm_riscv_aia_nr_guests = min(imsic_num_cpu_pages(), hgeie_bits); | ||
| if (kvm_riscv_aia_nr_guests) | ||
| kvm_riscv_aia_nr_guests--; | ||
|
|
||
| /* Find number of guest MSI IDs */ | ||
| kvm_riscv_aia_max_ids = IMSIC_MAX_ID; | ||
| if (kvm_riscv_aia_nr_guests) | ||
| kvm_riscv_aia_max_ids = imsic_num_ids() + 1; | ||
|
|
||
| /* Enable KVM AIA support */ | ||
| static_branch_enable(&kvm_riscv_aia_available); | ||
|
|
||
| return 0; | ||
| } | ||
|
|
||
| void kvm_riscv_aia_exit(void) | ||
| { | ||
| } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| /* SPDX-License-Identifier: GPL-2.0-only */ | ||
| /* | ||
| * irq.h: in kernel interrupt controller related definitions | ||
| * Copyright (C) 2021 Western Digital Corporation or its affiliates. | ||
| * | ||
| * This header is included by irqchip.c. | ||
| */ | ||
|
|
||
| #ifndef __IRQ_H | ||
| #define __IRQ_H | ||
|
|
||
| #include <asm/kvm_aia.h> | ||
|
|
||
| #endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.