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,36 +974,154 @@ static int kvm_timer_dying_cpu(unsigned int cpu)
973974 return 0 ;
974975}
975976
976- int kvm_timer_hyp_init ( bool has_gic )
977+ static int timer_irq_set_vcpu_affinity ( struct irq_data * d , void * vcpu )
977978{
978- struct arch_timer_kvm_info * info ;
979- int err ;
979+ if (vcpu )
980+ irqd_set_forwarded_to_vcpu (d );
981+ else
982+ irqd_clr_forwarded_to_vcpu (d );
980983
981- info = arch_timer_get_kvm_info () ;
982- timecounter = & info -> timecounter ;
984+ return 0 ;
985+ }
983986
984- if (!timecounter -> cc ) {
985- kvm_err ("kvm_arch_timer: uninitialized timecounter\n" );
986- return - ENODEV ;
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+
1048+ static void kvm_irq_fixup_flags (unsigned int virq , u32 * flags )
1049+ {
1050+ * flags = irq_get_trigger_type (virq );
1051+ if (* flags != IRQF_TRIGGER_HIGH && * flags != IRQF_TRIGGER_LOW ) {
1052+ kvm_err ("Invalid trigger for timer IRQ%d, assuming level low\n" ,
1053+ virq );
1054+ * flags = IRQF_TRIGGER_LOW ;
9871055 }
1056+ }
9881057
989- /* First, do the virtual EL1 timer irq */
1058+ static int kvm_irq_init (struct arch_timer_kvm_info * info )
1059+ {
1060+ struct irq_domain * domain = NULL ;
9901061
9911062 if (info -> virtual_irq <= 0 ) {
9921063 kvm_err ("kvm_arch_timer: invalid virtual timer IRQ: %d\n" ,
9931064 info -> virtual_irq );
9941065 return - ENODEV ;
9951066 }
1067+
9961068 host_vtimer_irq = info -> virtual_irq ;
1069+ kvm_irq_fixup_flags (host_vtimer_irq , & host_vtimer_irq_flags );
1070+
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+ }
9971093
998- host_vtimer_irq_flags = irq_get_trigger_type (host_vtimer_irq );
999- if (host_vtimer_irq_flags != IRQF_TRIGGER_HIGH &&
1000- host_vtimer_irq_flags != IRQF_TRIGGER_LOW ) {
1001- kvm_err ("Invalid trigger for vtimer IRQ%d, assuming level low\n" ,
1002- host_vtimer_irq );
1003- host_vtimer_irq_flags = IRQF_TRIGGER_LOW ;
1094+ if (info -> physical_irq > 0 ) {
1095+ host_ptimer_irq = info -> physical_irq ;
1096+ 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 ));
10041101 }
10051102
1103+ return 0 ;
1104+ }
1105+
1106+ int kvm_timer_hyp_init (bool has_gic )
1107+ {
1108+ struct arch_timer_kvm_info * info ;
1109+ int err ;
1110+
1111+ info = arch_timer_get_kvm_info ();
1112+ timecounter = & info -> timecounter ;
1113+
1114+ if (!timecounter -> cc ) {
1115+ kvm_err ("kvm_arch_timer: uninitialized timecounter\n" );
1116+ return - ENODEV ;
1117+ }
1118+
1119+ err = kvm_irq_init (info );
1120+ if (err )
1121+ return err ;
1122+
1123+ /* First, do the virtual EL1 timer irq */
1124+
10061125 err = request_percpu_irq (host_vtimer_irq , kvm_arch_timer_handler ,
10071126 "kvm guest vtimer" , kvm_get_running_vcpus ());
10081127 if (err ) {
@@ -1027,15 +1146,6 @@ int kvm_timer_hyp_init(bool has_gic)
10271146 /* Now let's do the physical EL1 timer irq */
10281147
10291148 if (info -> physical_irq > 0 ) {
1030- host_ptimer_irq = info -> physical_irq ;
1031- host_ptimer_irq_flags = irq_get_trigger_type (host_ptimer_irq );
1032- if (host_ptimer_irq_flags != IRQF_TRIGGER_HIGH &&
1033- host_ptimer_irq_flags != IRQF_TRIGGER_LOW ) {
1034- kvm_err ("Invalid trigger for ptimer IRQ%d, assuming level low\n" ,
1035- host_ptimer_irq );
1036- host_ptimer_irq_flags = IRQF_TRIGGER_LOW ;
1037- }
1038-
10391149 err = request_percpu_irq (host_ptimer_irq , kvm_arch_timer_handler ,
10401150 "kvm guest ptimer" , kvm_get_running_vcpus ());
10411151 if (err ) {
@@ -1143,15 +1253,15 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu)
11431253 ret = kvm_vgic_map_phys_irq (vcpu ,
11441254 map .direct_vtimer -> host_timer_irq ,
11451255 map .direct_vtimer -> irq .irq ,
1146- kvm_arch_timer_get_input_level );
1256+ & arch_timer_irq_ops );
11471257 if (ret )
11481258 return ret ;
11491259
11501260 if (map .direct_ptimer ) {
11511261 ret = kvm_vgic_map_phys_irq (vcpu ,
11521262 map .direct_ptimer -> host_timer_irq ,
11531263 map .direct_ptimer -> irq .irq ,
1154- kvm_arch_timer_get_input_level );
1264+ & arch_timer_irq_ops );
11551265 }
11561266
11571267 if (ret )
0 commit comments