273
273
#define SKX_CPUNODEID 0xc0
274
274
#define SKX_GIDNIDMAP 0xd4
275
275
276
+ /*
277
+ * The CPU_BUS_NUMBER MSR returns the values of the respective CPUBUSNO CSR
278
+ * that BIOS programmed. MSR has package scope.
279
+ * | Bit | Default | Description
280
+ * | [63] | 00h | VALID - When set, indicates the CPU bus
281
+ * numbers have been initialized. (RO)
282
+ * |[62:48]| --- | Reserved
283
+ * |[47:40]| 00h | BUS_NUM_5 — Return the bus number BIOS assigned
284
+ * CPUBUSNO(5). (RO)
285
+ * |[39:32]| 00h | BUS_NUM_4 — Return the bus number BIOS assigned
286
+ * CPUBUSNO(4). (RO)
287
+ * |[31:24]| 00h | BUS_NUM_3 — Return the bus number BIOS assigned
288
+ * CPUBUSNO(3). (RO)
289
+ * |[23:16]| 00h | BUS_NUM_2 — Return the bus number BIOS assigned
290
+ * CPUBUSNO(2). (RO)
291
+ * |[15:8] | 00h | BUS_NUM_1 — Return the bus number BIOS assigned
292
+ * CPUBUSNO(1). (RO)
293
+ * | [7:0] | 00h | BUS_NUM_0 — Return the bus number BIOS assigned
294
+ * CPUBUSNO(0). (RO)
295
+ */
296
+ #define SKX_MSR_CPU_BUS_NUMBER 0x300
297
+ #define SKX_MSR_CPU_BUS_VALID_BIT (1ULL << 63)
298
+ #define BUS_NUM_STRIDE 8
299
+
276
300
/* SKX CHA */
277
301
#define SKX_CHA_MSR_PMON_BOX_FILTER_TID (0x1ffULL << 0)
278
302
#define SKX_CHA_MSR_PMON_BOX_FILTER_LINK (0xfULL << 9)
@@ -3612,6 +3636,170 @@ static struct intel_uncore_ops skx_uncore_iio_ops = {
3612
3636
.read_counter = uncore_msr_read_counter ,
3613
3637
};
3614
3638
3639
+ static inline u8 skx_iio_stack (struct intel_uncore_pmu * pmu , int die )
3640
+ {
3641
+ return pmu -> type -> topology [die ] >> (pmu -> pmu_idx * BUS_NUM_STRIDE );
3642
+ }
3643
+
3644
+ static umode_t
3645
+ skx_iio_mapping_visible (struct kobject * kobj , struct attribute * attr , int die )
3646
+ {
3647
+ struct intel_uncore_pmu * pmu = dev_to_uncore_pmu (kobj_to_dev (kobj ));
3648
+
3649
+ /* Root bus 0x00 is valid only for die 0 AND pmu_idx = 0. */
3650
+ return (!skx_iio_stack (pmu , die ) && pmu -> pmu_idx ) ? 0 : attr -> mode ;
3651
+ }
3652
+
3653
+ static ssize_t skx_iio_mapping_show (struct device * dev ,
3654
+ struct device_attribute * attr , char * buf )
3655
+ {
3656
+ struct pci_bus * bus = pci_find_next_bus (NULL );
3657
+ struct intel_uncore_pmu * uncore_pmu = dev_to_uncore_pmu (dev );
3658
+ struct dev_ext_attribute * ea = to_dev_ext_attribute (attr );
3659
+ long die = (long )ea -> var ;
3660
+
3661
+ /*
3662
+ * Current implementation is for single segment configuration hence it's
3663
+ * safe to take the segment value from the first available root bus.
3664
+ */
3665
+ return sprintf (buf , "%04x:%02x\n" , pci_domain_nr (bus ),
3666
+ skx_iio_stack (uncore_pmu , die ));
3667
+ }
3668
+
3669
+ static int skx_msr_cpu_bus_read (int cpu , u64 * topology )
3670
+ {
3671
+ u64 msr_value ;
3672
+
3673
+ if (rdmsrl_on_cpu (cpu , SKX_MSR_CPU_BUS_NUMBER , & msr_value ) ||
3674
+ !(msr_value & SKX_MSR_CPU_BUS_VALID_BIT ))
3675
+ return - ENXIO ;
3676
+
3677
+ * topology = msr_value ;
3678
+
3679
+ return 0 ;
3680
+ }
3681
+
3682
+ static int die_to_cpu (int die )
3683
+ {
3684
+ int res = 0 , cpu , current_die ;
3685
+ /*
3686
+ * Using cpus_read_lock() to ensure cpu is not going down between
3687
+ * looking at cpu_online_mask.
3688
+ */
3689
+ cpus_read_lock ();
3690
+ for_each_online_cpu (cpu ) {
3691
+ current_die = topology_logical_die_id (cpu );
3692
+ if (current_die == die ) {
3693
+ res = cpu ;
3694
+ break ;
3695
+ }
3696
+ }
3697
+ cpus_read_unlock ();
3698
+ return res ;
3699
+ }
3700
+
3701
+ static int skx_iio_get_topology (struct intel_uncore_type * type )
3702
+ {
3703
+ int i , ret ;
3704
+ struct pci_bus * bus = NULL ;
3705
+
3706
+ /*
3707
+ * Verified single-segment environments only; disabled for multiple
3708
+ * segment topologies for now except VMD domains.
3709
+ * VMD domains start at 0x10000 to not clash with ACPI _SEG domains.
3710
+ */
3711
+ while ((bus = pci_find_next_bus (bus ))
3712
+ && (!pci_domain_nr (bus ) || pci_domain_nr (bus ) > 0xffff ))
3713
+ ;
3714
+ if (bus )
3715
+ return - EPERM ;
3716
+
3717
+ type -> topology = kcalloc (uncore_max_dies (), sizeof (u64 ), GFP_KERNEL );
3718
+ if (!type -> topology )
3719
+ return - ENOMEM ;
3720
+
3721
+ for (i = 0 ; i < uncore_max_dies (); i ++ ) {
3722
+ ret = skx_msr_cpu_bus_read (die_to_cpu (i ), & type -> topology [i ]);
3723
+ if (ret ) {
3724
+ kfree (type -> topology );
3725
+ type -> topology = NULL ;
3726
+ return ret ;
3727
+ }
3728
+ }
3729
+
3730
+ return 0 ;
3731
+ }
3732
+
3733
+ static struct attribute_group skx_iio_mapping_group = {
3734
+ .is_visible = skx_iio_mapping_visible ,
3735
+ };
3736
+
3737
+ static const struct attribute_group * skx_iio_attr_update [] = {
3738
+ & skx_iio_mapping_group ,
3739
+ NULL ,
3740
+ };
3741
+
3742
+ static int skx_iio_set_mapping (struct intel_uncore_type * type )
3743
+ {
3744
+ char buf [64 ];
3745
+ int ret ;
3746
+ long die = -1 ;
3747
+ struct attribute * * attrs = NULL ;
3748
+ struct dev_ext_attribute * eas = NULL ;
3749
+
3750
+ ret = skx_iio_get_topology (type );
3751
+ if (ret )
3752
+ return ret ;
3753
+
3754
+ /* One more for NULL. */
3755
+ attrs = kcalloc ((uncore_max_dies () + 1 ), sizeof (* attrs ), GFP_KERNEL );
3756
+ if (!attrs )
3757
+ goto err ;
3758
+
3759
+ eas = kcalloc (uncore_max_dies (), sizeof (* eas ), GFP_KERNEL );
3760
+ if (!eas )
3761
+ goto err ;
3762
+
3763
+ for (die = 0 ; die < uncore_max_dies (); die ++ ) {
3764
+ sprintf (buf , "die%ld" , die );
3765
+ sysfs_attr_init (& eas [die ].attr .attr );
3766
+ eas [die ].attr .attr .name = kstrdup (buf , GFP_KERNEL );
3767
+ if (!eas [die ].attr .attr .name )
3768
+ goto err ;
3769
+ eas [die ].attr .attr .mode = 0444 ;
3770
+ eas [die ].attr .show = skx_iio_mapping_show ;
3771
+ eas [die ].attr .store = NULL ;
3772
+ eas [die ].var = (void * )die ;
3773
+ attrs [die ] = & eas [die ].attr .attr ;
3774
+ }
3775
+ skx_iio_mapping_group .attrs = attrs ;
3776
+
3777
+ return 0 ;
3778
+ err :
3779
+ for (; die >= 0 ; die -- )
3780
+ kfree (eas [die ].attr .attr .name );
3781
+ kfree (eas );
3782
+ kfree (attrs );
3783
+ kfree (type -> topology );
3784
+ type -> attr_update = NULL ;
3785
+ return - ENOMEM ;
3786
+ }
3787
+
3788
+ static void skx_iio_cleanup_mapping (struct intel_uncore_type * type )
3789
+ {
3790
+ struct attribute * * attr = skx_iio_mapping_group .attrs ;
3791
+
3792
+ if (!attr )
3793
+ return ;
3794
+
3795
+ for (; * attr ; attr ++ )
3796
+ kfree ((* attr )-> name );
3797
+ kfree (attr_to_ext_attr (* skx_iio_mapping_group .attrs ));
3798
+ kfree (skx_iio_mapping_group .attrs );
3799
+ skx_iio_mapping_group .attrs = NULL ;
3800
+ kfree (type -> topology );
3801
+ }
3802
+
3615
3803
static struct intel_uncore_type skx_uncore_iio = {
3616
3804
.name = "iio" ,
3617
3805
.num_counters = 4 ,
@@ -3626,6 +3814,9 @@ static struct intel_uncore_type skx_uncore_iio = {
3626
3814
.constraints = skx_uncore_iio_constraints ,
3627
3815
.ops = & skx_uncore_iio_ops ,
3628
3816
.format_group = & skx_uncore_iio_format_group ,
3817
+ .attr_update = skx_iio_attr_update ,
3818
+ .set_mapping = skx_iio_set_mapping ,
3819
+ .cleanup_mapping = skx_iio_cleanup_mapping ,
3629
3820
};
3630
3821
3631
3822
enum perf_uncore_iio_freerunning_type_id {
0 commit comments