intel / intel/pcm

IOConnectCallStructMethod calling failed

Open
#839 10 comments 0 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
3.3k
Forks
528
Avg merge
1h 40m
Merged PRs (30d)
2

Description

Below is the output of `pcm`.
```
Intel(r) Performance Counter Monitor ($Format:%ci ID=%h$)

===== Processor information =====
Hybrid processor : no
IBRS and IBPB supported : yes
STIBP supported : yes
Spec arch caps supported : yes
Max CPUID level : 22
CPU family : 6
CPU model number : 166
IOServiceOpen returned 0xe00002c7
Unable to build CPU topology
WARNING: Core 0 IA32_PERFEVTSEL0_ADDR is not zeroed 18446744073709551615
Access to Intel(r) Performance Counter Monitor has denied (Performance Monitoring Unit is occupied by other application). Try to stop the application that uses PMU.
Alternatively you can try running PCM with option -r to reset PMU.
Cleaning up
Zeroed PMU registers
Zeroed uncore PMU registers
```

I tried to debug the code, below is the call stack.
```
libPcmMsr.dylib!MSRAccessor::read(unsigned int, unsigned long long, unsigned long long*) (/Users/bixian/pcm/src/MacMSRDriver/MSRAccessor.cpp:37)
pcm!pcm::MsrHandle::read(unsigned long long, unsigned long long*) (/Users/bixian/pcm/src/msr.cpp:140)
pcm!pcm::SafeMsrHandle::read(unsigned long long, unsigned long long*) (/Users/bixian/pcm/src/msr.h:76)
pcm!pcm::PCM::PMUinUse() (/Users/bixian/pcm/src/cpucounters.cpp:4720)
pcm!pcm::PCM::program(pcm::PCM::ProgramMode, void const*, bool, int) (/Users/bixian/pcm/src/cpucounters.cpp:3467)
pcm!mainThrows(int, char**) (/Users/bixian/pcm/src/pcm.cpp:1557)
pcm!main (/Users/bixian/pcm/src/pcm.cpp:1343)
libdyld.dylib!start (Unknown Source:0)
libdyld.dylib!start (Unknown Source:0)
```

And when the debugger step over `kern_return_t ret = IOConnectCallStructMethod(connect, kReadMSR, &idatas, struct_size, &odatas, &struct_size);`, the returned value is 268435459 rather than 0.
Below is the code snippet and corresponding arguments passed into `IOConnectCallStructMethod`
```cpp
int32_t MSRAccessor::read(uint32_t core_num, uint64_t msr_num, uint64_t * value)
{
pcm_msr_data_t idatas, odatas;

size_t struct_size = sizeof(pcm_msr_data_t);
idatas.msr_num = (uint32_t)msr_num;
idatas.cpu_num = core_num;

kern_return_t ret = IOConnectCallStructMethod(connect, kReadMSR,
&idatas, struct_size,
&odatas, &struct_size);

if(ret == KERN_SUCCESS)
{
*value = odatas.value;
return sizeof(uint64_t);
} else {
return -1;
}
}
```
```
idatas={
value=0;
cpu_num=0;
mar_num=914;
}
struct_size=16
connect=0
kReadMSR=2
```

I did some research about `IOConnectCallStructMethod`. It seems `IOConnectCallStructMethod` is trying to send a struct to a kext and get the output struct, correct? And I double checked that SIP is disabled and `com.intel.driver.PcmMsr` is loaded.

I cannot diagnose anymore.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.