99#include <linux/kvm_host.h>
1010#include <linux/interrupt.h>
1111#include <linux/irq.h>
12+ #include <linux/irqdomain.h>
1213#include <linux/uaccess.h>
1314
1415#include <clocksource/arm_arch_timer.h>
@@ -973,6 +974,77 @@ static int kvm_timer_dying_cpu(unsigned int cpu)
973974 return 0 ;
974975}
975976
977+ static int timer_irq_set_vcpu_affinity (struct irq_data * d , void * vcpu )
978+ {
979+ if (vcpu )
980+ irqd_set_forwarded_to_vcpu (d );
981+ else
982+ irqd_clr_forwarded_to_vcpu (d );
983+
984+ return 0 ;
985+ }
986+
987+ static int timer_irq_set_irqchip_state (struct irq_data * d ,
988+ enum irqchip_irq_state which , bool val )
989+ {
990+ if (which != IRQCHIP_STATE_ACTIVE || !irqd_is_forwarded_to_vcpu (d ))
991+ return irq_chip_set_parent_state (d , which , val );
992+
993+ if (val )
994+ irq_chip_mask_parent (d );
995+ else
996+ irq_chip_unmask_parent (d );
997+
998+ return 0 ;
999+ }
1000+
1001+ static void timer_irq_eoi (struct irq_data * d )
1002+ {
1003+ if (!irqd_is_forwarded_to_vcpu (d ))
1004+ irq_chip_eoi_parent (d );
1005+ }
1006+
1007+ static void timer_irq_ack (struct irq_data * d )
1008+ {
1009+ d = d -> parent_data ;
1010+ if (d -> chip -> irq_ack )
1011+ d -> chip -> irq_ack (d );
1012+ }
1013+
1014+ static struct irq_chip timer_chip = {
1015+ .name = "KVM" ,
1016+ .irq_ack = timer_irq_ack ,
1017+ .irq_mask = irq_chip_mask_parent ,
1018+ .irq_unmask = irq_chip_unmask_parent ,
1019+ .irq_eoi = timer_irq_eoi ,
1020+ .irq_set_type = irq_chip_set_type_parent ,
1021+ .irq_set_vcpu_affinity = timer_irq_set_vcpu_affinity ,
1022+ .irq_set_irqchip_state = timer_irq_set_irqchip_state ,
1023+ };
1024+
1025+ static int timer_irq_domain_alloc (struct irq_domain * domain , unsigned int virq ,
1026+ unsigned int nr_irqs , void * arg )
1027+ {
1028+ irq_hw_number_t hwirq = (uintptr_t )arg ;
1029+
1030+ return irq_domain_set_hwirq_and_chip (domain , virq , hwirq ,
1031+ & timer_chip , NULL );
1032+ }
1033+
1034+ static void timer_irq_domain_free (struct irq_domain * domain , unsigned int virq ,
1035+ unsigned int nr_irqs )
1036+ {
1037+ }
1038+
1039+ static const struct irq_domain_ops timer_domain_ops = {
1040+ .alloc = timer_irq_domain_alloc ,
1041+ .free = timer_irq_domain_free ,
1042+ };
1043+
1044+ static struct irq_ops arch_timer_irq_ops = {
1045+ .get_input_level = kvm_arch_timer_get_input_level ,
1046+ };
1047+
9761048static void kvm_irq_fixup_flags (unsigned int virq , u32 * flags )
9771049{
9781050 * flags = irq_get_trigger_type (virq );
@@ -985,6 +1057,8 @@ static void kvm_irq_fixup_flags(unsigned int virq, u32 *flags)
9851057
9861058static int kvm_irq_init (struct arch_timer_kvm_info * info )
9871059{
1060+ struct irq_domain * domain = NULL ;
1061+
9881062 if (info -> virtual_irq <= 0 ) {
9891063 kvm_err ("kvm_arch_timer: invalid virtual timer IRQ: %d\n" ,
9901064 info -> virtual_irq );
@@ -994,9 +1068,36 @@ static int kvm_irq_init(struct arch_timer_kvm_info *info)
9941068 host_vtimer_irq = info -> virtual_irq ;
9951069 kvm_irq_fixup_flags (host_vtimer_irq , & host_vtimer_irq_flags );
9961070
1071+ if (kvm_vgic_global_state .no_hw_deactivation ) {
1072+ struct fwnode_handle * fwnode ;
1073+ struct irq_data * data ;
1074+
1075+ fwnode = irq_domain_alloc_named_fwnode ("kvm-timer" );
1076+ if (!fwnode )
1077+ return - ENOMEM ;
1078+
1079+ /* Assume both vtimer and ptimer in the same parent */
1080+ data = irq_get_irq_data (host_vtimer_irq );
1081+ domain = irq_domain_create_hierarchy (data -> domain , 0 ,
1082+ NR_KVM_TIMERS , fwnode ,
1083+ & timer_domain_ops , NULL );
1084+ if (!domain ) {
1085+ irq_domain_free_fwnode (fwnode );
1086+ return - ENOMEM ;
1087+ }
1088+
1089+ arch_timer_irq_ops .flags |= VGIC_IRQ_SW_RESAMPLE ;
1090+ WARN_ON (irq_domain_push_irq (domain , host_vtimer_irq ,
1091+ (void * )TIMER_VTIMER ));
1092+ }
1093+
9971094 if (info -> physical_irq > 0 ) {
9981095 host_ptimer_irq = info -> physical_irq ;
9991096 kvm_irq_fixup_flags (host_ptimer_irq , & host_ptimer_irq_flags );
1097+
1098+ if (domain )
1099+ WARN_ON (irq_domain_push_irq (domain , host_ptimer_irq ,
1100+ (void * )TIMER_PTIMER ));
10001101 }
10011102
10021103 return 0 ;
@@ -1125,10 +1226,6 @@ bool kvm_arch_timer_get_input_level(int vintid)
11251226 return kvm_timer_should_fire (timer );
11261227}
11271228
1128- static struct irq_ops arch_timer_irq_ops = {
1129- .get_input_level = kvm_arch_timer_get_input_level ,
1130- };
1131-
11321229int kvm_timer_enable (struct kvm_vcpu * vcpu )
11331230{
11341231 struct arch_timer_cpu * timer = vcpu_timer (vcpu );
0 commit comments