Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

some code wrong with cr3 filter or i have not understand cr3 filter mechanism #20

Open
crackzhazha opened this issue Jun 25, 2018 · 5 comments

Comments

@crackzhazha
Copy link

Accroding to the Intel® 64 and IA-32 Architectures Software Developer’s Manual.pdf section 35.2.7.6 IA32_RTIT_CR3_MATCH MSR Intel says Bits 63:5 hold the CR3 address value to match, bits 4:0 are reserved to 0.
image
But in your code at simple-pt.c line 774 function set_cr3_filter

static void set_cr3_filter(void *arg)
{
	u64 val;

	if (pt_rdmsrl_safe(MSR_IA32_RTIT_CTL, &val) < 0)
		return;
	if ((val & TRACE_EN) && pt_wrmsrl_safe(MSR_IA32_RTIT_CTL, val & ~TRACE_EN) < 0)
		return;
	if (pt_wrmsrl_safe(MSR_IA32_CR3_MATCH, *(u64 *)arg) < 0)
		pr_err("cpu %d, cannot set cr3 filter\n", smp_processor_id());
	if ((val & TRACE_EN) && pt_wrmsrl_safe(MSR_IA32_RTIT_CTL, val) < 0)
		return;
}

You haven't set the low 5bit of arg(the value of cr3) to 0, this may cause general-protection fault (#GP)
We know when low 5 bit is 0 ,the mask is 0xffffffffffffffe0
hex(0b1111111111111111111111111111111111111111111111111111111111100000)=0xffffffffffffffe0L
so this is my code for set_cr3_filter,you can ignore the code for logging.

static void set_cr3_filter_fix(void *arg)
{
        u64 val;

        if (pt_rdmsrl_safe(MSR_IA32_RTIT_CTL, &val) < 0)
                return;
        if ((val & TRACE_EN) && pt_wrmsrl_safe(MSR_IA32_RTIT_CTL, val & ~TRACE_EN) < 0)
                return;
        pr_err("now arg: %p,before set_cr3_filter",*(u64 *)arg);
        pr_err("simple-pt:Cpu %d Ready to set_cr3_filter: cr3:%p",smp_processor_id(),(*(u64 *)arg )&0xffffffffffffffe0 ) ;
        if (pt_wrmsrl_safe(MSR_IA32_CR3_MATCH, (*(u64 *)arg )&0xffffffffffffffe0 ) < 0)
                pr_err("cpu %d, cannot set cr3 filter\n", smp_processor_id());
        if ((val & TRACE_EN) && pt_wrmsrl_safe(MSR_IA32_RTIT_CTL, val) < 0)
                return;
}

And i have another question, after I perform this patch. I can only get trace log for my specific process in ring0 code,but can not get any log for my specific process in ring3 code. I wonder know it's my code error or i have not understand the mechanism of cr3 filter? Could you help figure out this question?
I want to use cr3 filter to trace an specific process both ring0 and cr3 code. thanks all.

@andikleen
Copy link
Owner

bit 5 should never be set because the page table is 4K page aligned.

Likely you need to boot with "nopti" on newer kernels, CR3 filter is incompatible with page table separation

@crackzhazha
Copy link
Author

crackzhazha commented Jun 26, 2018 via email

@crackzhazha
Copy link
Author

crackzhazha commented Jun 26, 2018 via email

@andikleen
Copy link
Owner

The lower 5 bits are the PCID, which is used in PTI kernels.

simple-pt should probably check and warn about it, although right now it will just be checked by the WRMSR. Could also be masked out, but usually the filtering is not very useful with PTI anyways because you will only see kernel code.

@andikleen andikleen reopened this Jun 26, 2018
@andikleen
Copy link
Owner

Should mask out the PCID in CR3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants