A problem when enabling xapic and x2apic

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
michael
Posts: 12
Joined: Fri Nov 12, 2021 1:09 am

A problem when enabling xapic and x2apic

Post by michael »

When I use these codes to enable xapic and x2apic:

Code: Select all

__asm__ __volatile__(
		"movq $0x1b,%%rcx	\n\t"
		"rdmsr				\n\t"
		"or $0xc00,%%rax	\n\t"
		"wrmsr			\n\t"
		//"wrmsr	\n\t"
		"movq $0x1b,%%rcx	\n\t"
		"rdmsr				\n\t"
		:"=a"(x),"=d"(y)
		:
		:"memory");
everything goes well at first. But after I remove the annotation mark before the second "wrmsr", it turns me a general protection fault with error code 0xe0.
I'm sure my simulator(Bochs x86 Emulator 2.6) support apic, xapic, and x2apic, and I have no idea why it happens.
Octocontrabass
Member
Member
Posts: 5563
Joined: Mon Mar 25, 2013 7:01 pm

Re: A problem when enabling xapic and x2apic

Post by Octocontrabass »

Your inline assembly clobbers RCX without telling the compiler.

But why are you doing all of that in inline assembly? Do you really write a bunch of inline assembly every time you need to read or write a MSR? You could be doing something like this instead:

Code: Select all

inline uint64_t rdmsr( uint32_t msr )
{
    uint32_t low;
    uint32_t high;
    asm volatile ( "rdmsr" : "=a"(low), "=d"(high) : "c"(msr) : "memory" );
    return ((uint64_t)high << 32) | low;
}

inline void wrmsr( uint32_t msr, uint64_t val )
{
    asm volatile ( "wrmsr" :: "a"((uint32_t)val), "d"((uint32_t)(val >> 32)), "c"(msr) : "memory" );
}

uint64_t enable_x2apic( void )
{
    wrmsr( 0x1b, rdmsr( 0x1b ) | 0xc00 );
    return rdmsr( 0x1b );
}
kzinti
Member
Member
Posts: 898
Joined: Mon Feb 02, 2015 7:11 pm

Re: A problem when enabling xapic and x2apic

Post by kzinti »

Octocontrabass wrote:

Code: Select all

inline uint64_t rdmsr( uint32_t msr )
{
    uint32_t low;
    uint32_t high;
    asm volatile ( "rdmsr" : "=a"(low), "=d"(high) : "c"(msr) : "memory" );
    return ((uint64_t)high << 32) | low;
}
I don't think you need the "memory" clobber on this one... Or are there cases where reading a MSR will change memory?
Octocontrabass
Member
Member
Posts: 5563
Joined: Mon Mar 25, 2013 7:01 pm

Re: A problem when enabling xapic and x2apic

Post by Octocontrabass »

I don't know of any cases where reading a MSR could change memory, but I can think of cases where you might want a compiler memory barrier.

If you're sure you don't need the memory clobber, you can remove it.
kzinti
Member
Member
Posts: 898
Joined: Mon Feb 02, 2015 7:11 pm

Re: A problem when enabling xapic and x2apic

Post by kzinti »

Octocontrabass wrote:but I can think of cases where you might want a compiler memory barrier.
Do you have any examples?
Octocontrabass
Member
Member
Posts: 5563
Joined: Mon Mar 25, 2013 7:01 pm

Re: A problem when enabling xapic and x2apic

Post by Octocontrabass »

Reading counters using RDMSR. I don't know why you would want to do that instead of RDTSC/RDPMC, but it's an option.
kzinti
Member
Member
Posts: 898
Joined: Mon Feb 02, 2015 7:11 pm

Re: A problem when enabling xapic and x2apic

Post by kzinti »

So then it sounds like there is no need for the memory barriers either.
Post Reply