-
Notifications
You must be signed in to change notification settings - Fork 4
/
linux-apic-for-4.14.113.patch
5353 lines (5055 loc) · 207 KB
/
linux-apic-for-4.14.113.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
From ba9e296b4c1ff56edae6766ef25ffd60d2bc5757 Mon Sep 17 00:00:00 2001
From: Dongli Zhang <[email protected]>
Date: Fri, 18 Feb 2022 00:06:07 -0800
Subject: [PATCH 1/1] linux-apic-for-4.14.113
Signed-off-by: Dongli Zhang <[email protected]>
---
arch/x86/include/asm/apic.h | 6 +
arch/x86/include/asm/hw_irq.h | 10 +
arch/x86/include/asm/i8259.h | 31 ++
arch/x86/include/asm/io_apic.h | 10 +
arch/x86/include/asm/irq_vectors.h | 7 +
arch/x86/kernel/apic/apic.c | 41 ++
arch/x86/kernel/apic/apic_flat_64.c | 8 +
arch/x86/kernel/apic/apic_noop.c | 6 +
arch/x86/kernel/apic/apic_numachip.c | 8 +
arch/x86/kernel/apic/bigsmp_32.c | 6 +
arch/x86/kernel/apic/htirq.c | 33 ++
arch/x86/kernel/apic/io_apic.c | 498 ++++++++++++++++++++++++
arch/x86/kernel/apic/msi.c | 198 ++++++++++
arch/x86/kernel/apic/probe_32.c | 6 +
arch/x86/kernel/apic/probe_64.c | 26 ++
arch/x86/kernel/apic/vector.c | 541 ++++++++++++++++++++++++++
arch/x86/kernel/apic/x2apic_cluster.c | 82 ++++
arch/x86/kernel/apic/x2apic_phys.c | 6 +
arch/x86/kernel/apic/x2apic_uv_x.c | 6 +
arch/x86/kernel/dumpstack.c | 6 +
arch/x86/kernel/hpet.c | 9 +
arch/x86/kernel/i8259.c | 221 +++++++++++
arch/x86/kernel/irq.c | 91 +++++
arch/x86/kernel/irqinit.c | 27 ++
arch/x86/kernel/smpboot.c | 5 +
arch/x86/kernel/time.c | 28 ++
arch/x86/kernel/traps.c | 13 +
arch/x86/kernel/x86_init.c | 15 +
drivers/clocksource/i8253.c | 4 +
drivers/nvme/host/pci.c | 37 ++
drivers/pci/msi.c | 142 +++++++
include/linux/device.h | 18 +
include/linux/irq.h | 59 +++
include/linux/irqdesc.h | 3 +
include/linux/irqdomain.h | 40 ++
include/linux/msi.h | 14 +
include/linux/pci.h | 6 +
kernel/cpu.c | 32 ++
kernel/irq/autoprobe.c | 69 ++++
kernel/irq/chip.c | 46 +++
kernel/irq/cpuhotplug.c | 31 ++
kernel/irq/handle.c | 24 ++
kernel/irq/irqdesc.c | 30 ++
kernel/irq/irqdomain.c | 201 ++++++++++
kernel/irq/manage.c | 16 +
kernel/irq/msi.c | 109 ++++++
kernel/irq/proc.c | 24 ++
kernel/irq_work.c | 6 +
kernel/kexec_core.c | 21 +
kernel/panic.c | 7 +
kernel/smpboot.c | 1 +
kernel/stop_machine.c | 7 +
kernel/time/tick-common.c | 5 +
kernel/time/tick-oneshot.c | 9 +
54 files changed, 2905 insertions(+)
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
index a1ed92aa..19be1b8f 100644
--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -243,6 +243,12 @@ static inline int x2apic_enabled(void)
return boot_cpu_has(X86_FEATURE_X2APIC) && apic_is_x2apic_enabled();
}
+/*
+ * called by:
+ * - arch/x86/kernel/apic/apic.c|1740| <<enable_IR_x2apic>> if (ir_stat < 0 && !x2apic_supported())
+ * - drivers/iommu/intel_irq_remapping.c|675| <<intel_cleanup_irq_remapping>> if (x2apic_supported())
+ * - drivers/iommu/intel_irq_remapping.c|712| <<intel_prepare_irq_remapping>> if (x2apic_supported()) {
+ */
#define x2apic_supported() (boot_cpu_has(X86_FEATURE_X2APIC))
#else /* !CONFIG_X86_X2APIC */
static inline void check_x2apic(void) { }
diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h
index bf253ad9..e83ebdbf 100644
--- a/arch/x86/include/asm/hw_irq.h
+++ b/arch/x86/include/asm/hw_irq.h
@@ -123,6 +123,10 @@ struct irq_alloc_info {
};
struct irq_cfg {
+ /*
+ * 在这里修改dest_apicid:
+ * - arch/x86/kernel/apic/vector.c|542| <<__assign_irq_vector>> &d->cfg.dest_apicid));
+ */
unsigned int dest_apicid;
u8 vector;
u8 old_vector;
@@ -159,6 +163,12 @@ extern char irq_entries_start[];
#endif
#define VECTOR_UNUSED NULL
+/*
+ * 使用VECTOR_RETRIGGERED:
+ * - arch/x86/kernel/irq.c|258| <<do_IRQ>> if (desc != VECTOR_RETRIGGERED) {
+ * - arch/x86/kernel/irq.c|530| <<fixup_irqs>> __this_cpu_write(vector_irq[vector], VECTOR_RETRIGGERED);
+ * - arch/x86/kernel/irq.c|534| <<fixup_irqs>> if (__this_cpu_read(vector_irq[vector]) != VECTOR_RETRIGGERED)
+ */
#define VECTOR_RETRIGGERED ((void *)~0UL)
typedef struct irq_desc* vector_irq_t[NR_VECTORS];
diff --git a/arch/x86/include/asm/i8259.h b/arch/x86/include/asm/i8259.h
index 89789e8c..909be799 100644
--- a/arch/x86/include/asm/i8259.h
+++ b/arch/x86/include/asm/i8259.h
@@ -8,7 +8,23 @@
extern unsigned int cached_irq_mask;
#define __byte(x, y) (((unsigned char *)&(y))[x])
+/*
+ * 只使用, 不修改:
+ * - arch/x86/kernel/i8259.c|113| <<mask_8259A_irq>> outb(cached_master_mask, PIC_MASTER_IMR);
+ * - arch/x86/kernel/i8259.c|147| <<unmask_8259A_irq>> outb(cached_master_mask, PIC_MASTER_IMR);
+ * - arch/x86/kernel/i8259.c|288| <<mask_and_ack_8259A>> outb(cached_master_mask, PIC_MASTER_IMR);
+ * - arch/x86/kernel/i8259.c|413| <<unmask_8259A>> outb(cached_master_mask, PIC_MASTER_IMR);
+ * - arch/x86/kernel/i8259.c|528| <<init_8259A>> outb(cached_master_mask, PIC_MASTER_IMR);
+ */
#define cached_master_mask (__byte(0, cached_irq_mask))
+/*
+ * 只使用, 不修改:
+ * - arch/x86/kernel/i8259.c|111| <<mask_8259A_irq>> outb(cached_slave_mask, PIC_SLAVE_IMR);
+ * - arch/x86/kernel/i8259.c|145| <<unmask_8259A_irq>> outb(cached_slave_mask, PIC_SLAVE_IMR);
+ * - arch/x86/kernel/i8259.c|281| <<mask_and_ack_8259A>> outb(cached_slave_mask, PIC_SLAVE_IMR);
+ * - arch/x86/kernel/i8259.c|414| <<unmask_8259A>> outb(cached_slave_mask, PIC_SLAVE_IMR);
+ * - arch/x86/kernel/i8259.c|529| <<init_8259A>> outb(cached_slave_mask, PIC_SLAVE_IMR);
+ */
#define cached_slave_mask (__byte(1, cached_irq_mask))
/* i8259A PIC registers */
@@ -61,9 +77,20 @@ struct legacy_pic {
void (*unmask)(unsigned int irq);
void (*mask_all)(void);
void (*restore_mask)(void);
+ /*
+ * called by:
+ * - arch/x86/kernel/apic/io_apic.c|2166| <<check_timer>> legacy_pic->init(1);
+ * - arch/x86/kernel/apic/io_apic.c|2315| <<check_timer>> legacy_pic->init(0);
+ * - arch/x86/kernel/irqinit.c|68| <<init_ISA_irqs>> legacy_pic->init(0);
+ */
void (*init)(int auto_eoi);
int (*probe)(void);
int (*irq_pending)(unsigned int irq);
+ /*
+ * calld by:
+ * - arch/x86/kernel/apic/io_apic.c|1977| <<init_IO_APIC_traps>> legacy_pic->make_irq(irq);
+ * - arch/x86/kernel/apic/io_apic.c|2316| <<check_timer>> legacy_pic->make_irq(0);
+ */
void (*make_irq)(unsigned int irq);
};
@@ -75,6 +102,10 @@ static inline bool has_legacy_pic(void)
return legacy_pic != &null_legacy_pic;
}
+/*
+ * 在default_legacy_pic返回NR_IRQS_LEGACY(16)
+ * 在null_legacy_pic返回0
+ */
static inline int nr_legacy_irqs(void)
{
return legacy_pic->nr_legacy_irqs;
diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index 5c27e146..ad0a20d5 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -150,6 +150,16 @@ extern unsigned long io_apic_irqs;
* If we use the IO-APIC for IRQ routing, disable automatic
* assignment of PCI IRQ's.
*/
+/*
+ * used by:
+ * - arch/x86/pci/irq.c|898| <<pcibios_lookup_irq>> if (io_apic_assign_pci_irqs)
+ * - arch/x86/pci/irq.c|1051| <<pcibios_fixup_irqs>> if (io_apic_assign_pci_irqs)
+ * - arch/x86/pci/irq.c|1147| <<pcibios_irq_init>> if (io_apic_assign_pci_irqs)
+ * - arch/x86/pci/irq.c|1153| <<pcibios_irq_init>> if (io_apic_assign_pci_irqs && pci_routeirq) {
+ * - arch/x86/pci/irq.c|1198| <<pirq_enable_irq>> if (!io_apic_assign_pci_irqs && dev->irq)
+ * - arch/x86/pci/irq.c|1201| <<pirq_enable_irq>> if (io_apic_assign_pci_irqs) {
+ * - arch/x86/pci/irq.c|1275| <<pirq_disable_irq>> if (io_apic_assign_pci_irqs && !mp_should_keep_irq(&dev->dev) &&
+ */
#define io_apic_assign_pci_irqs \
(mp_irq_entries && !skip_ioapic_setup && io_apic_irqs)
diff --git a/arch/x86/include/asm/irq_vectors.h b/arch/x86/include/asm/irq_vectors.h
index c20ffca8..df116f47 100644
--- a/arch/x86/include/asm/irq_vectors.h
+++ b/arch/x86/include/asm/irq_vectors.h
@@ -53,6 +53,13 @@
* Vectors 0x30-0x3f are used for ISA interrupts.
* round up to the next 16-vector boundary
*/
+/*
+ * FIRST_EXTERNAL_VECTOR = 0x20
+ * FIRST_EXTERNAL_VECTOR + 16 = 0x30 = 110000
+ * ~15 = ~1111 = 11110000
+ * ((FIRST_EXTERNAL_VECTOR + 16) & ~15) = 110000 & 11110000 = 110000 = 0x30
+ * 于是这里是输入一个irq, 返回0x30+irq, 也就是48+irq
+ */
#define ISA_IRQ_VECTOR(irq) (((FIRST_EXTERNAL_VECTOR + 16) & ~15) + irq)
/*
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 2e64178f..47294ead 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -59,6 +59,26 @@
#include <asm/intel-family.h>
#include <asm/irq_regs.h>
+/*
+ * 主要的数据结构:
+ *
+ * 533 static struct clock_event_device lapic_clockevent = {
+ * 534 .name = "lapic",
+ * 535 .features = CLOCK_EVT_FEAT_PERIODIC |
+ * 536 CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_C3STOP
+ * 537 | CLOCK_EVT_FEAT_DUMMY,
+ * 538 .shift = 32,
+ * 539 .set_state_shutdown = lapic_timer_shutdown,
+ * 540 .set_state_periodic = lapic_timer_set_periodic,
+ * 541 .set_state_oneshot = lapic_timer_set_oneshot,
+ * 542 .set_state_oneshot_stopped = lapic_timer_shutdown,
+ * 543 .set_next_event = lapic_next_event,
+ * 544 .broadcast = lapic_timer_broadcast,
+ * 545 .rating = 100,
+ * 546 .irq = -1,
+ * 547 };
+ */
+
unsigned int num_processors;
unsigned disabled_cpus;
@@ -1542,6 +1562,13 @@ void apic_ap_setup(void)
}
#ifdef CONFIG_X86_X2APIC
+/*
+ * 在以下修改:
+ * - arch/x86/kernel/apic/apic.c|1616| <<setup_nox2apic>> x2apic_mode = 0;
+ * - arch/x86/kernel/apic/apic.c|1639| <<x2apic_disable>> x2apic_mode = 0;
+ * - arch/x86/kernel/apic/apic.c|1658| <<x2apic_enable>> x2apic_mode = 1;
+ * - arch/x86/kernel/apic/apic.c|1692| <<check_x2apic>> x2apic_mode = 1;
+ */
int x2apic_mode;
enum {
@@ -1630,6 +1657,10 @@ static __init void x2apic_disable(void)
register_lapic_address(mp_lapic_addr);
}
+/*
+ * called by:
+ * - arch/x86/kernel/apic/apic.c|1685| <<try_to_enable_x2apic>> x2apic_enable();
+ */
static __init void x2apic_enable(void)
{
if (x2apic_state != X2APIC_OFF)
@@ -1640,6 +1671,10 @@ static __init void x2apic_enable(void)
__x2apic_enable();
}
+/*
+ * called by:
+ * - arch/x86/kernel/apic/apic.c|1753| <<enable_IR_x2apic>> try_to_enable_x2apic(ir_stat);
+ */
static __init void try_to_enable_x2apic(int remap_mode)
{
if (x2apic_state == X2APIC_DISABLED)
@@ -2287,6 +2322,12 @@ int default_cpu_mask_to_apicid(const struct cpumask *mask,
return 0;
}
+/*
+ * struct apic apic_flat.cpu_mask_to_apicid = flat_cpu_mask_to_apicid()
+ * struct apic apic_noop.cpu_mask_to_apicid = flat_cpu_mask_to_apicid()
+ * struct apic apic_default.cpu_mask_to_apicid = flat_cpu_mask_to_apicid()
+ * struct apic xen_pv_apic.cpu_mask_to_apicid = flat_cpu_mask_to_apicid()
+ */
int flat_cpu_mask_to_apicid(const struct cpumask *mask,
struct irq_data *irqdata,
unsigned int *apicid)
diff --git a/arch/x86/kernel/apic/apic_flat_64.c b/arch/x86/kernel/apic/apic_flat_64.c
index dedd5a41..6469a1f1 100644
--- a/arch/x86/kernel/apic/apic_flat_64.c
+++ b/arch/x86/kernel/apic/apic_flat_64.c
@@ -22,6 +22,14 @@
#include <linux/acpi.h>
+/*
+ * 主要的数据结构:
+ *
+ * struct apic apic_physflat
+ *
+ * struct apic apic_flat
+ */
+
static struct apic apic_physflat;
static struct apic apic_flat;
diff --git a/arch/x86/kernel/apic/apic_noop.c b/arch/x86/kernel/apic/apic_noop.c
index c8d21127..1fbf1028 100644
--- a/arch/x86/kernel/apic/apic_noop.c
+++ b/arch/x86/kernel/apic/apic_noop.c
@@ -29,6 +29,12 @@
#include <asm/acpi.h>
#include <asm/e820/api.h>
+/*
+ * 主要的数据结构:
+ *
+ * struct apic apic_noop
+ */
+
static void noop_init_apic_ldr(void) { }
static void noop_send_IPI(int cpu, int vector) { }
static void noop_send_IPI_mask(const struct cpumask *cpumask, int vector) { }
diff --git a/arch/x86/kernel/apic/apic_numachip.c b/arch/x86/kernel/apic/apic_numachip.c
index 2fda9122..74bbb2fb 100644
--- a/arch/x86/kernel/apic/apic_numachip.c
+++ b/arch/x86/kernel/apic/apic_numachip.c
@@ -20,6 +20,14 @@
#include <asm/pgtable.h>
#include <asm/pci_x86.h>
+/*
+ * 主要的数据结构:
+ *
+ * struct apic apic_numachip1;
+ *
+ * struct apic apic_numachip2;
+ */
+
u8 numachip_system __read_mostly;
static const struct apic apic_numachip1;
static const struct apic apic_numachip2;
diff --git a/arch/x86/kernel/apic/bigsmp_32.c b/arch/x86/kernel/apic/bigsmp_32.c
index e12fbcfc..4a3e4319 100644
--- a/arch/x86/kernel/apic/bigsmp_32.c
+++ b/arch/x86/kernel/apic/bigsmp_32.c
@@ -17,6 +17,12 @@
#include <asm/apic.h>
#include <asm/ipi.h>
+/*
+ * 主要数据结构:
+ *
+ * struct apic apic_bigsmp
+ */
+
static unsigned bigsmp_get_apic_id(unsigned long x)
{
return (x >> 24) & 0xFF;
diff --git a/arch/x86/kernel/apic/htirq.c b/arch/x86/kernel/apic/htirq.c
index 741de281..a3c35812 100644
--- a/arch/x86/kernel/apic/htirq.c
+++ b/arch/x86/kernel/apic/htirq.c
@@ -23,6 +23,27 @@
#include <asm/apic.h>
#include <asm/hypertransport.h>
+/*
+ * 主要的数据结构:
+ *
+ * 156 static const struct irq_domain_ops htirq_domain_ops = {
+ * 157 .alloc = htirq_domain_alloc,
+ * 158 .free = htirq_domain_free,
+ * 159 .activate = htirq_domain_activate,
+ * 160 .deactivate = htirq_domain_deactivate,
+ * 161 };
+ *
+ * 72 static struct irq_chip ht_irq_chip = {
+ * 73 .name = "PCI-HT",
+ * 74 .irq_mask = mask_ht_irq,
+ * 75 .irq_unmask = unmask_ht_irq,
+ * 76 .irq_ack = irq_chip_ack_parent,
+ * 77 .irq_set_affinity = ht_set_affinity,
+ * 78 .irq_retrigger = irq_chip_retrigger_hierarchy,
+ * 79 .flags = IRQCHIP_SKIP_SET_WAKE,
+ * 80 };
+ */
+
static struct irq_domain *htirq_domain;
/*
@@ -52,6 +73,10 @@ ht_set_affinity(struct irq_data *data, const struct cpumask *mask, bool force)
return ret;
}
+/*
+ * used by:
+ * - arch/x86/kernel/apic/htirq.c|101| <<htirq_domain_alloc>> irq_domain_set_info(domain, virq, hwirq, &ht_irq_chip, ht_cfg,
+ */
static struct irq_chip ht_irq_chip = {
.name = "PCI-HT",
.irq_mask = mask_ht_irq,
@@ -145,6 +170,10 @@ static void htirq_domain_deactivate(struct irq_domain *domain,
write_ht_irq_msg(irq_data->irq, &msg);
}
+/*
+ * used by:
+ * - arch/x86/kernel/apic/htirq.c|166| <<arch_init_htirq_domain>> htirq_domain = irq_domain_create_tree(fn, &htirq_domain_ops, NULL);
+ */
static const struct irq_domain_ops htirq_domain_ops = {
.alloc = htirq_domain_alloc,
.free = htirq_domain_free,
@@ -152,6 +181,10 @@ static const struct irq_domain_ops htirq_domain_ops = {
.deactivate = htirq_domain_deactivate,
};
+/*
+ * called by only:
+ * - arch/x86/kernel/apic/vector.c|673| <<arch_early_irq_init>> arch_init_htirq_domain(x86_vector_domain);
+ */
void __init arch_init_htirq_domain(struct irq_domain *parent)
{
struct fwnode_handle *fn;
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 96a8a68f..77a24e52 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -65,6 +65,49 @@
#include <asm/apic.h>
+/*
+ * 主要数据结构:
+ *
+ * 2025 static struct irq_chip ioapic_chip __read_mostly = {
+ * 2026 .name = "IO-APIC",
+ * 2027 .irq_startup = startup_ioapic_irq,
+ * 2028 .irq_mask = mask_ioapic_irq,
+ * 2029 .irq_unmask = unmask_ioapic_irq,
+ * 2030 .irq_ack = irq_chip_ack_parent,
+ * 2031 .irq_eoi = ioapic_ack_level,
+ * 2032 .irq_set_affinity = ioapic_set_affinity,
+ * 2033 .irq_retrigger = irq_chip_retrigger_hierarchy,
+ * 2034 .flags = IRQCHIP_SKIP_SET_WAKE,
+ * 2035 };
+ *
+ * 2058 static struct irq_chip ioapic_ir_chip __read_mostly = {
+ * 2059 .name = "IR-IO-APIC",
+ * 2060 .irq_startup = startup_ioapic_irq,
+ * 2061 .irq_mask = mask_ioapic_irq,
+ * 2062 .irq_unmask = unmask_ioapic_irq,
+ * 2063 .irq_ack = irq_chip_ack_parent,
+ * 2064 .irq_eoi = ioapic_ir_ack_level,
+ * 2065 .irq_set_affinity = ioapic_set_affinity,
+ * 2066 .irq_retrigger = irq_chip_retrigger_hierarchy,
+ * 2067 .flags = IRQCHIP_SKIP_SET_WAKE,
+ * 2068 };
+ *
+ * 2142 static struct irq_chip lapic_chip __read_mostly = {
+ * 2143 .name = "local-APIC",
+ * 2144 .irq_mask = mask_lapic_irq,
+ * 2145 .irq_unmask = unmask_lapic_irq,
+ * 2146 .irq_ack = ack_lapic_irq,
+ * 2147 };
+ *
+ *
+ * 3484 const struct irq_domain_ops mp_ioapic_irqdomain_ops = {
+ * 3485 .alloc = mp_irqdomain_alloc,
+ * 3486 .free = mp_irqdomain_free,
+ * 3487 .activate = mp_irqdomain_activate,
+ * 3488 .deactivate = mp_irqdomain_deactivate,
+ * 3489 };
+ */
+
#define for_each_ioapic(idx) \
for ((idx) = 0; (idx) < nr_ioapics; (idx)++)
#define for_each_ioapic_reverse(idx) \
@@ -79,6 +122,11 @@
static DEFINE_RAW_SPINLOCK(ioapic_lock);
static DEFINE_MUTEX(ioapic_mutex);
+/*
+ * used by:
+ * - arch/x86/kernel/apic/io_apic.c|2554| <<mp_irqdomain_create>> ioapic_dynirq_base = max(ioapic_dynirq_base,
+ * - arch/x86/kernel/apic/io_apic.c|2659| <<arch_dynirq_lower_bound>> return ioapic_initialized ? ioapic_dynirq_base : gsi_top;
+ */
static unsigned int ioapic_dynirq_base;
static int ioapic_initialized;
@@ -88,6 +136,22 @@ struct irq_pin_list {
};
struct mp_chip_data {
+ /*
+ * 使用的地方:
+ * - arch/x86/kernel/apic/io_apic.c|414| <<__add_pin_to_irq_node>> for_each_irq_pin(entry, data->irq_2_pin)
+ * - arch/x86/kernel/apic/io_apic.c|426| <<__add_pin_to_irq_node>> list_add_tail(&entry->list, &data->irq_2_pin);
+ * - arch/x86/kernel/apic/io_apic.c|435| <<__remove_pin_from_irq>> list_for_each_entry_safe(entry, tmp, &data->irq_2_pin, list)
+ * - arch/x86/kernel/apic/io_apic.c|463| <<replace_pin_at_irq_node>> for_each_irq_pin(entry, data->irq_2_pin) {
+ * - arch/x86/kernel/apic/io_apic.c|488| <<io_apic_modify_irq>> for_each_irq_pin(entry, data->irq_2_pin) {
+ * - arch/x86/kernel/apic/io_apic.c|578| <<eoi_ioapic_pin>> for_each_irq_pin(entry, data->irq_2_pin)
+ * - arch/x86/kernel/apic/io_apic.c|1410| <<print_IO_APICs>> if (list_empty(&data->irq_2_pin))
+ * - arch/x86/kernel/apic/io_apic.c|1414| <<print_IO_APICs>> for_each_irq_pin(entry, data->irq_2_pin)
+ * - arch/x86/kernel/apic/io_apic.c|1763| <<io_apic_level_ack_pending>> for_each_irq_pin(entry, data->irq_2_pin) {
+ * - arch/x86/kernel/apic/io_apic.c|1930| <<ioapic_set_affinity>> for_each_irq_pin(entry, data->irq_2_pin)
+ * - arch/x86/kernel/apic/io_apic.c|3113| <<mp_irqdomain_alloc>> INIT_LIST_HEAD(&data->irq_2_pin);
+ * - arch/x86/kernel/apic/io_apic.c|3151| <<mp_irqdomain_free>> WARN_ON(!list_empty(&data->irq_2_pin));
+ * - arch/x86/kernel/apic/io_apic.c|3165| <<mp_irqdomain_activate>> for_each_irq_pin(entry, data->irq_2_pin)
+ */
struct list_head irq_2_pin;
struct IO_APIC_route_entry entry;
int trigger;
@@ -105,6 +169,15 @@ static struct ioapic {
/*
* # of IRQ routing registers
*/
+ /*
+ * used by:
+ * - arch/x86/kernel/apic/io_apic.c|73| <<for_each_pin>> for ((pin) = 0; (pin) < ioapics[(idx)].nr_registers; (pin)++)
+ * - arch/x86/kernel/apic/io_apic.c|240| <<alloc_ioapic_saved_registers>> size = sizeof(struct IO_APIC_route_entry) * ioapics[idx].nr_registers;
+ * - arch/x86/kernel/apic/io_apic.c|1324| <<print_IO_APICs>> ioapics[ioapic_idx].nr_registers);
+ * - arch/x86/kernel/apic/io_apic.c|2752| <<find_free_ioapic_entry>> if (ioapics[idx].nr_registers == 0)
+ * - arch/x86/kernel/apic/io_apic.c|2849| <<mp_register_ioapic>> ioapics[idx].nr_registers = entries;
+ * - arch/x86/kernel/apic/io_apic.c|2890| <<mp_unregister_ioapic>> ioapics[ioapic].nr_registers = 0;
+ */
int nr_registers;
/*
* Saved state during suspend/resume, or while enabling intr-remap.
@@ -176,6 +249,24 @@ int nr_ioapics;
/* The one past the highest gsi number used */
u32 gsi_top;
+/*
+ * 在以下被使用:
+ * - mp_config_acpi_legacy_irqs()
+ * - mp_save_irq()
+ * - find_irq_entry()
+ * - find_isa_irq_pin()
+ * - find_isa_irq_apic()
+ * - default_EISA_trigger()
+ * - irq_polarity()
+ * - irq_trigger()
+ * - mp_map_pin_to_irq()
+ * - pin_2_irq()
+ * - IO_APIC_get_PCI_irq_vector()
+ * - setup_ioapic_ids_from_mpc_nocheck()
+ * - get_MP_intsrc_index()
+ * - check_irq_src()
+ * - replace_intsrc_all()
+ */
/* MP IRQ source entries */
struct mpc_intsrc mp_irqs[MAX_IRQ_SOURCES];
@@ -303,10 +394,18 @@ union entry_union {
struct IO_APIC_route_entry entry;
};
+/*
+ * called by:
+ * - arch/x86/kernel/apic/io_apic.c|322| <<ioapic_read_entry>> eu.entry = __ioapic_read_entry(apic, pin);
+ * - arch/x86/kernel/apic/io_apic.c|516| <<__eoi_ioapic_pin>> entry = entry1 = __ioapic_read_entry(apic, pin);
+ */
static struct IO_APIC_route_entry __ioapic_read_entry(int apic, int pin)
{
union entry_union eu;
+ /*
+ * 乘以2是因为一个entry是64 bits
+ */
eu.w1 = io_apic_read(apic, 0x10 + 2 * pin);
eu.w2 = io_apic_read(apic, 0x11 + 2 * pin);
@@ -415,12 +514,32 @@ static void add_pin_to_irq_node(struct mp_chip_data *data,
/*
* Reroute an IRQ to a different pin.
*/
+/*
+ * called by only:
+ * - arch/x86/kernel/apic/io_apic.c|2226| <<check_timer>> replace_pin_at_irq_node(data, node, apic1, pin1, apic2, pin2);
+ */
static void __init replace_pin_at_irq_node(struct mp_chip_data *data, int node,
int oldapic, int oldpin,
int newapic, int newpin)
{
struct irq_pin_list *entry;
+ /*
+ * 使用的地方:
+ * - arch/x86/kernel/apic/io_apic.c|414| <<__add_pin_to_irq_node>> for_each_irq_pin(entry, data->irq_2_pin)
+ * - arch/x86/kernel/apic/io_apic.c|426| <<__add_pin_to_irq_node>> list_add_tail(&entry->list, &data->irq_2_pin);
+ * - arch/x86/kernel/apic/io_apic.c|435| <<__remove_pin_from_irq>> list_for_each_entry_safe(entry, tmp, &data->irq_2_pin, list)
+ * - arch/x86/kernel/apic/io_apic.c|463| <<replace_pin_at_irq_node>> for_each_irq_pin(entry, data->irq_2_pin) {
+ * - arch/x86/kernel/apic/io_apic.c|488| <<io_apic_modify_irq>> for_each_irq_pin(entry, data->irq_2_pin) {
+ * - arch/x86/kernel/apic/io_apic.c|578| <<eoi_ioapic_pin>> for_each_irq_pin(entry, data->irq_2_pin)
+ * - arch/x86/kernel/apic/io_apic.c|1410| <<print_IO_APICs>> if (list_empty(&data->irq_2_pin))
+ * - arch/x86/kernel/apic/io_apic.c|1414| <<print_IO_APICs>> for_each_irq_pin(entry, data->irq_2_pin)
+ * - arch/x86/kernel/apic/io_apic.c|1763| <<io_apic_level_ack_pending>> for_each_irq_pin(entry, data->irq_2_pin) {
+ * - arch/x86/kernel/apic/io_apic.c|1930| <<ioapic_set_affinity>> for_each_irq_pin(entry, data->irq_2_pin)
+ * - arch/x86/kernel/apic/io_apic.c|3113| <<mp_irqdomain_alloc>> INIT_LIST_HEAD(&data->irq_2_pin);
+ * - arch/x86/kernel/apic/io_apic.c|3151| <<mp_irqdomain_free>> WARN_ON(!list_empty(&data->irq_2_pin));
+ * - arch/x86/kernel/apic/io_apic.c|3165| <<mp_irqdomain_activate>> for_each_irq_pin(entry, data->irq_2_pin)
+ */
for_each_irq_pin(entry, data->irq_2_pin) {
if (entry->apic == oldapic && entry->pin == oldpin) {
entry->apic = newapic;
@@ -465,6 +584,10 @@ static void io_apic_sync(struct irq_pin_list *entry)
readl(&io_apic->data);
}
+/*
+ * struct irq_chip ioapic_chip.irq_mask = mask_ioapic_irq()
+ * struct irq_chip ioapic_ir_chip.irq_mask = mask_ioapic_irq()
+ */
static void mask_ioapic_irq(struct irq_data *irq_data)
{
struct mp_chip_data *data = irq_data->chip_data;
@@ -480,6 +603,10 @@ static void __unmask_ioapic(struct mp_chip_data *data)
io_apic_modify_irq(data, ~IO_APIC_REDIR_MASKED, 0, NULL);
}
+/*
+ * struct irq_chip ioapic_chip.irq_unmask = unmask_ioapic_irq()
+ * struct irq_chip ioapic_ir_chip.irq_unmask = unmask_ioapic_irq()
+ */
static void unmask_ioapic_irq(struct irq_data *irq_data)
{
struct mp_chip_data *data = irq_data->chip_data;
@@ -541,6 +668,15 @@ static void eoi_ioapic_pin(int vector, struct mp_chip_data *data)
raw_spin_unlock_irqrestore(&ioapic_lock, flags);
}
+/*
+ * called by:
+ * - arch/x86/kernel/apic/io_apic.c|636| <<clear_IO_APIC>> clear_IO_APIC_pin(apic, pin);
+ * - arch/x86/kernel/apic/io_apic.c|2033| <<unlock_ExtINT_logic>> clear_IO_APIC_pin(apic, pin);
+ * - arch/x86/kernel/apic/io_apic.c|2062| <<unlock_ExtINT_logic>> clear_IO_APIC_pin(apic, pin);
+ * - arch/x86/kernel/apic/io_apic.c|2209| <<check_timer>> clear_IO_APIC_pin(0, pin1);
+ * - arch/x86/kernel/apic/io_apic.c|2214| <<check_timer>> clear_IO_APIC_pin(apic1, pin1);
+ * - arch/x86/kernel/apic/io_apic.c|2239| <<check_timer>> clear_IO_APIC_pin(apic2, pin2);
+ */
static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin)
{
struct IO_APIC_route_entry entry;
@@ -588,6 +724,11 @@ static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin)
mpc_ioapic_id(apic), pin);
}
+/*
+ * called by:
+ * - arch/x86/kernel/apic/io_apic.c|1410| <<enable_IO_APIC>> clear_IO_APIC();
+ * - arch/x86/kernel/apic/io_apic.c|1449| <<disable_IO_APIC>> clear_IO_APIC();
+ */
static void clear_IO_APIC (void)
{
int apic, pin;
@@ -717,6 +858,9 @@ static int find_irq_entry(int ioapic_idx, int pin, int type)
/*
* Find the pin to which IRQ[irq] (ISA) is connected
*/
+/*
+ * 通过mptable读取
+ */
static int __init find_isa_irq_pin(int irq, int type)
{
int i;
@@ -733,6 +877,9 @@ static int __init find_isa_irq_pin(int irq, int type)
return -1;
}
+/*
+ * 通过mptable读取
+ */
static int __init find_isa_irq_apic(int irq, int type)
{
int i;
@@ -1226,6 +1373,10 @@ void ioapic_zap_locks(void)
raw_spin_lock_init(&ioapic_lock);
}
+/*
+ * called by only:
+ * - arch/x86/kernel/apic/io_apic.c|1408| <<print_IO_APIC>> io_apic_print_entries(ioapic_idx, reg_01.bits.entries);
+ */
static void io_apic_print_entries(unsigned int apic, unsigned int nr_entries)
{
int i;
@@ -1312,6 +1463,10 @@ static void __init print_IO_APIC(int ioapic_idx)
io_apic_print_entries(ioapic_idx, reg_01.bits.entries);
}
+/*
+ * called by only:
+ * - arch/x86/kernel/apic/vector.c|993| <<print_ICs>> print_IO_APICs();
+ */
void __init print_IO_APICs(void)
{
int ioapic_idx;
@@ -1356,9 +1511,28 @@ void __init print_IO_APICs(void)
printk(KERN_INFO ".................................... done.\n");
}
+/*
+ * used by:
+ * - arch/x86/kernel/apic/io_apic.c|1381| <<enable_IO_APIC>> ioapic_i8259.apic = apic;
+ * - arch/x86/kernel/apic/io_apic.c|1382| <<enable_IO_APIC>> ioapic_i8259.pin = pin;
+ * - arch/x86/kernel/apic/io_apic.c|1395| <<enable_IO_APIC>> if ((ioapic_i8259.pin == -1) && (i8259_pin >= 0)) {
+ * - arch/x86/kernel/apic/io_apic.c|1397| <<enable_IO_APIC>> ioapic_i8259.pin = i8259_pin;
+ * - arch/x86/kernel/apic/io_apic.c|1398| <<enable_IO_APIC>> ioapic_i8259.apic = i8259_apic;
+ * - arch/x86/kernel/apic/io_apic.c|1401| <<enable_IO_APIC>> if (((ioapic_i8259.apic != i8259_apic) || (ioapic_i8259.pin != i8259_pin)) &&
+ * - arch/x86/kernel/apic/io_apic.c|1402| <<enable_IO_APIC>> (i8259_pin >= 0) && (ioapic_i8259.pin >= 0))
+ * - arch/x86/kernel/apic/io_apic.c|1420| <<native_disable_io_apic>> if (ioapic_i8259.pin != -1) {
+ * - arch/x86/kernel/apic/io_apic.c|1434| <<native_disable_io_apic>> ioapic_write_entry(ioapic_i8259.apic, ioapic_i8259.pin, entry);
+ * - arch/x86/kernel/apic/io_apic.c|1438| <<native_disable_io_apic>> disconnect_bsp_APIC(ioapic_i8259.pin != -1);
+ * - arch/x86/kernel/apic/io_apic.c|2079| <<check_timer>> pin2 = ioapic_i8259.pin;
+ * - arch/x86/kernel/apic/io_apic.c|2080| <<check_timer>> apic2 = ioapic_i8259.apic;
+ */
/* Where if anywhere is the i8259 connect in external int mode */
static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
+/*
+ * called by only:
+ * - arch/x86/kernel/apic/apic.c|2361| <<apic_bsp_setup>> enable_IO_APIC();
+ */
void __init enable_IO_APIC(void)
{
int i8259_apic, i8259_pin;
@@ -1578,6 +1752,15 @@ void __init setup_ioapic_ids_from_mpc(void)
}
#endif
+/*
+ * 在以下设置:
+ * - arch/x86/kernel/apic/io_apic.c|1699| <<notimercheck>> no_timer_check = 1; ---> "no_timer_check"参数!
+ * - arch/x86/kernel/cpu/mshyperv.c|231| <<ms_hyperv_init_platform>> no_timer_check = 1;
+ * - arch/x86/kernel/cpu/vmware.c|171| <<vmware_platform_setup>> no_timer_check = 1;
+ * - arch/x86/kernel/kvm.c|298| <<paravirt_ops_setup>> no_timer_check = 1;
+ * 只在timer_irq_works()使用:
+ * - arch/x86/kernel/apic/io_apic.c|1724| <<timer_irq_works>> if (no_timer_check)
+ */
int no_timer_check __initdata;
static int __init notimercheck(char *s)
@@ -1595,11 +1778,27 @@ __setup("no_timer_check", notimercheck);
* - if this function detects that timer IRQs are defunct, then we fall
* back to ISA timer IRQs
*/
+/*
+ * 在timer_irq_works()中测试的时候会激活中断
+ */
static int __init timer_irq_works(void)
{
+ /*
+ * jiffies和jiffies_64是一样的, 定义在
+ * arch/x86/kernel/vmlinux.lds.S
+ */
unsigned long t1 = jiffies;
unsigned long flags;
+ /*
+ * 在以下设置:
+ * - arch/x86/kernel/apic/io_apic.c|1699| <<notimercheck>> no_timer_check = 1; ---> "no_timer_check"参数!
+ * - arch/x86/kernel/cpu/mshyperv.c|231| <<ms_hyperv_init_platform>> no_timer_check = 1;
+ * - arch/x86/kernel/cpu/vmware.c|171| <<vmware_platform_setup>> no_timer_check = 1;
+ * - arch/x86/kernel/kvm.c|298| <<paravirt_ops_setup>> no_timer_check = 1;
+ * 只在timer_irq_works()使用:
+ * - arch/x86/kernel/apic/io_apic.c|1724| <<timer_irq_works>> if (no_timer_check)
+ */
if (no_timer_check)
return 1;
@@ -1645,6 +1844,10 @@ static int __init timer_irq_works(void)
* This is not complete - we should be able to fake
* an edge even if it isn't on the 8259A...
*/
+/*
+ * struct irq_chip ioapic_chip.irq_startup = startup_ioapic_irq()
+ * struct irq_chip ioapic_ir_chip.irq_startup = startup_ioapic_irq()
+ */
static unsigned int startup_ioapic_irq(struct irq_data *data)
{
int was_pending = 0, irq = data->irq;
@@ -1742,6 +1945,9 @@ static inline void ioapic_irqd_unmask(struct irq_data *data, bool masked)
}
#endif
+/*
+ * struct irq_chip ioapic_chip.irq_eoi = ioapic_ack_level()
+ */
static void ioapic_ack_level(struct irq_data *irq_data)
{
struct irq_cfg *cfg = irqd_cfg(irq_data);
@@ -1808,6 +2014,9 @@ static void ioapic_ack_level(struct irq_data *irq_data)
ioapic_irqd_unmask(irq_data, masked);
}
+/*
+ * struct irq_chip ioapic_ir_chip.irq_eoi = ioapic_ir_ack_level()
+ */
static void ioapic_ir_ack_level(struct irq_data *irq_data)
{
struct mp_chip_data *data = irq_data->chip_data;
@@ -1822,6 +2031,10 @@ static void ioapic_ir_ack_level(struct irq_data *irq_data)
eoi_ioapic_pin(data->entry.vector, data);
}
+/*
+ * struct irq_chip ioapic_chip.irq_set_affinity = ioapic_set_affinity()
+ * struct irq_chip ioapic_ir_chip.irq_set_affinity = ioapic_set_affinity()
+ */
static int ioapic_set_affinity(struct irq_data *irq_data,
const struct cpumask *mask, bool force)
{
@@ -1847,6 +2060,11 @@ static int ioapic_set_affinity(struct irq_data *irq_data,
return ret;
}
+/*
+ * used by:
+ * - arch/x86/kernel/apic/io_apic.c|1446| <<print_IO_APICs>> if (chip != &ioapic_chip && chip != &ioapic_ir_chip)
+ * - arch/x86/kernel/apic/io_apic.c|3296| <<mp_irqdomain_alloc>> &ioapic_chip : &ioapic_ir_chip;
+ */
static struct irq_chip ioapic_chip __read_mostly = {
.name = "IO-APIC",
.irq_startup = startup_ioapic_irq,
@@ -1859,6 +2077,11 @@ static struct irq_chip ioapic_chip __read_mostly = {
.flags = IRQCHIP_SKIP_SET_WAKE,
};
+/*
+ * used by:
+ * - arch/x86/kernel/apic/io_apic.c|1446| <<print_IO_APICs>> if (chip != &ioapic_chip && chip != &ioapic_ir_chip)
+ * - arch/x86/kernel/apic/io_apic.c|3296| <<mp_irqdomain_alloc>> &ioapic_chip : &ioapic_ir_chip;
+ */
static struct irq_chip ioapic_ir_chip __read_mostly = {
.name = "IR-IO-APIC",
.irq_startup = startup_ioapic_irq,
@@ -1897,6 +2120,9 @@ static inline void init_IO_APIC_traps(void)
* The local APIC irq-chip implementation:
*/
+/*
+ * struct irq_chip lapic_chip.irq_mask = mask_lapic_irq()
+ */
static void mask_lapic_irq(struct irq_data *data)
{
unsigned long v;
@@ -1905,6 +2131,9 @@ static void mask_lapic_irq(struct irq_data *data)
apic_write(APIC_LVT0, v | APIC_LVT_MASKED);
}
+/*
+ * struct irq_chip lapic_chip.irq_unmask = unmask_lapic_irq()
+ */
static void unmask_lapic_irq(struct irq_data *data)
{
unsigned long v;
@@ -1913,11 +2142,18 @@ static void unmask_lapic_irq(struct irq_data *data)
apic_write(APIC_LVT0, v & ~APIC_LVT_MASKED);
}
+/*
+ * struct irq_chip lapic_chip.irq_ack = ack_lapic_irq()
+ */
static void ack_lapic_irq(struct irq_data *data)
{
ack_APIC_irq();
}
+/*
+ * used by:
+ * - arch/x86/kernel/apic/io_apic.c|2121| <<lapic_register_intr>> irq_set_chip_and_handler_name(irq, &lapic_chip, handle_edge_irq,
+ */
static struct irq_chip lapic_chip __read_mostly = {
.name = "local-APIC",
.irq_mask = mask_lapic_irq,
@@ -1925,9 +2161,26 @@ static struct irq_chip lapic_chip __read_mostly = {
.irq_ack = ack_lapic_irq,
};
+/*
+ * called by:
+ * - arch/x86/kernel/apic/io_apic.c|2278| <<check_timer>> lapic_register_intr(0);
+ */
static void lapic_register_intr(int irq)
{
irq_clear_status_flags(irq, IRQ_LEVEL);
+ /*
+ * 在部分以下调用:
+ * - arch/x86/kernel/apic/io_apic.c|2056| <<lapic_register_intr>> irq_set_chip_and_handler_name(irq, &lapic_chip, handle_edge_irq,
+ * - kernel/irq/irqdomain.c|1797| <<irq_domain_set_info>> irq_set_chip_and_handler_name(virq, chip, handler, handler_name);
+ * - include/linux/irq.h|620| <<irq_set_chip_and_handler>> irq_set_chip_and_handler_name(irq, chip, handle, NULL);
+ * - drivers/xen/events/events_base.c|702| <<xen_bind_pirq_gsi_to_irq>> irq_set_chip_and_handler_name(irq, &xen_pirq_chip,
+ * - drivers/xen/events/events_base.c|705| <<xen_bind_pirq_gsi_to_irq>> irq_set_chip_and_handler_name(irq, &xen_pirq_chip,
+ * - drivers/xen/events/events_base.c|741| <<xen_bind_pirq_msi_to_irq>> irq_set_chip_and_handler_name(irq + i, &xen_pirq_chip, handle_edge_irq, name);
+ * - drivers/xen/events/events_base.c|846| <<bind_evtchn_to_irq>> irq_set_chip_and_handler_name(irq, &xen_dynamic_chip,
+ * - drivers/xen/events/events_base.c|884| <<bind_ipi_to_irq>> irq_set_chip_and_handler_name(irq, &xen_percpu_chip,
+ * - drivers/xen/events/events_base.c|976| <<bind_virq_to_irq>> irq_set_chip_and_handler_name(irq, &xen_percpu_chip,
+ * - drivers/xen/events/events_base.c|979| <<bind_virq_to_irq>> irq_set_chip_and_handler_name(irq, &xen_dynamic_chip,
+ */
irq_set_chip_and_handler_name(irq, &lapic_chip, handle_edge_irq,
"edge");
}
@@ -1945,11 +2198,13 @@ static inline void __init unlock_ExtINT_logic(void)
struct IO_APIC_route_entry entry0, entry1;
unsigned char save_control, save_freq_select;
+ /* 通过mptable读取 */
pin = find_isa_irq_pin(8, mp_INT);
if (pin == -1) {
WARN_ON_ONCE(1);
return;
}
+ /* 通过mptable读取 */
apic = find_isa_irq_apic(8, mp_INT);
if (apic == -1) {
WARN_ON_ONCE(1);
@@ -2027,10 +2282,47 @@ static int mp_alloc_timer_irq(int ioapic, int pin)
*
* FIXME: really need to revamp this for all platforms.
*/
+/*
+ * called by only:
+ * - arch/x86/kernel/apic/io_apic.c|2312| <<setup_IO_APIC>> check_timer();
+ *
+ * 在之前给KVM的commit的中禁用了
+ * commit a90ede7b17d122acd58e6e1ff911be9dcf5263cc
+ * Author: Marcelo Tosatti <[email protected]>
+ * Date: Wed Feb 11 22:45:42 2009 -0200
+ *
+ * KVM: x86: paravirt skip pit-through-ioapic boot check
+ *
+ * Skip the test which checks if the PIT is properly routed when
+ * using the IOAPIC, aimed at buggy hardware.
+ *
+ * Signed-off-by: Marcelo Tosatti <[email protected]>
+ * Signed-off-by: Avi Kivity <[email protected]>
+ */
static inline void __init check_timer(void)
{
+ /*
+ * 获得irq 0的struct irq_desc *desc, 返回desc->irq_data
+ *
+ * irq_data是: struct irq_data irq_data
+ */
struct irq_data *irq_data = irq_get_irq_data(0);
+ /*
+ * chip_data是: void *chip_data
+ *
+ * chip_data在以下设置:
+ * - arch/x86/kernel/apic/io_apic.c|3385| <<mp_irqdomain_alloc>> irq_data->chip_data = data;
+ * - arch/x86/kernel/apic/vector.c|563| <<x86_vector_alloc_irqs>> irq_data->chip_data = data;
+ * - drivers/iommu/amd_iommu.c|4161| <<irq_remapping_alloc>> irq_data->chip_data = data;
+ * - drivers/iommu/intel_irq_remapping.c|1372| <<intel_irq_remapping_alloc>> irq_data->chip_data = ird;
+ * - drivers/pci/host/pci-hyperv.c|1224| <<hv_compose_msi_msg>> data->chip_data = int_desc;
+ * - kernel/irq/chip.c|167| <<irq_set_chip_data>> desc->irq_data.chip_data = data;
+ * - kernel/irq/irqdomain.c|1403| <<irq_domain_set_hwirq_and_chip>> irq_data->chip_data = chip_data;
+ */
struct mp_chip_data *data = irq_data->chip_data;
+ /*
+ * irq_data是struct irq_desc的struct irq_data irq_data
+ */
struct irq_cfg *cfg = irqd_cfg(irq_data);
int node = cpu_to_node(0);
int apic1, pin1, apic2, pin2;
@@ -2042,6 +2334,18 @@ static inline void __init check_timer(void)
/*
* get/set the timer IRQ vector:
*/
+ /*
+ * legacy_pic可以是:
+ * - default_legacy_pic
+ * - null_legacy_pic
+ *
+ * 这里的参数0是irq
+ *
+ * 对于mask_8259A_irq(): 通过IMR寄存器在8259禁用某个irq line
+ *
+ * 对于8259, 由于从片串接到主片的IRQ2 pin上,
+ * 从片的IRQ1 pin同时接到IRQ2和IRQ9 line
+ */
legacy_pic->mask(0);
/*
@@ -2054,13 +2358,31 @@ static inline void __init check_timer(void)
* automatically.
*/
apic_write(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT);
+ /*
+ * init_8259A(): 1说明支持AEOI
+ * 按照ICW要求的顺序初始化8259
+ * vector 0x30对应irq line 0
+ * vector 0x38对应irq line 8
+ * 最后会根据cached_irq_mask屏蔽中断
+ */
legacy_pic->init(1);
+ /* 通过mptable读取 */
pin1 = find_isa_irq_pin(0, mp_INT);
+ /* 通过mptable读取 */