As far as I know, x86_cpu_to_apicid
is not a table but a per_cpu
variable, meaning that it gets replicated for each CPU but it isn't strictly aggregated into a table.
Of course, you can consider each replicated section of per-cpu data as an "entry" in a table but that's a bit of a stretch.
x86_cpu_to_apicid
is a kernel variable and you cannot access it from user space. It would be pretty trivial to make an LKM that return the APIC ID for the current processor:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/uaccess.h>
#include <linux/version.h>
#include <linux/smp.h>
#define APICID_PROC_NAME "apicid"
static ssize_t acpicid_proc_read(struct file *file_pointer, char __user *buffer, size_t buffer_length, loff_t *offset);
static struct proc_dir_entry* acpicid_proc_entry;
static const struct proc_ops acpicid_proc_fops = {
.proc_read = acpicid_proc_read,
};
ssize_t acpicid_proc_read(struct file *file_pointer, char __user *buffer, size_t buffer_length, loff_t *offset)
{
u16 this_cpu_apic_id = this_cpu_read(x86_cpu_to_apicid);
if (*offset > 0 || buffer_length != 2 || copy_to_user(buffer, &this_cpu_apic_id, 2))
return 0;
*offset += 2;
return 2;
}
static int __init acpiid_proc_init(void)
{
acpicid_proc_entry = proc_create(APICID_PROC_NAME, 0444, NULL, &acpicid_proc_fops);
if (NULL == acpicid_proc_entry) {
proc_remove(acpicid_proc_entry);
return -ENOMEM;
}
return 0;
}
static void __exit acpiid_proc_exit(void)
{
proc_remove(acpicid_proc_entry);
}
module_init(acpiid_proc_init);
module_exit(acpiid_proc_exit);
MODULE_LICENSE("GPL");
Then you could read the APIC ID of the current processor from /proc/apicid
, e.g. with parallel -v taskset -c {} dd status=none if=/proc/apicid bs=2 count=1 '|' xxd -p ::: {1..4}
(for the first four CPUs).
However, for Intel's CPU the APIC ID is also available through the cpuid
instruction. Initially at leaf 0x1, then 0xb and finally at leaf 0x1f (if supported and the value returned is not zero).
For example the output of the command cpuid -l 0xb
gives me the same APIC IDs retrieved through the LKM above.
Note that the Intel's LAPIC can be in APIC, xAPIC and x2APIC mode and that the APIC ID in the xAPIC and APIC mode can be modified in some processor. The value returned by cpuid
is the initial value.
Modern OSes uses APIC in x2APIC mode and don't/cannot modify the APIC ID AFAIK, so cpuid
is a valid way to get the APIC IDs from userspace.
For completeness, there was once a /proc
tree that exposed the APIC ID of each CPU but it's now gone.
I don't know if it's still possible find the APIC ID somewhere under /sys
or /proc
.