Page 2 of 2
Re: problem changing page table in bochs
Posted: Thu Jun 07, 2012 9:25 am
by iansjack
Well, at least he'd see what address was being passed to the invlpg command. If the penny didn't drop then, then there's no hope.
Re: problem changing page table in bochs
Posted: Thu Jun 07, 2012 4:19 pm
by vjain20
Ok so may be I am dumb but I still don't see it.
I looked at the disassembly and the stack after passing the address - 0xC0000000 to the function
Code: Select all
void vmmgr_flush_tlb_entry(void* addr)
{
asm volatile("cli");
asm volatile("invlpg %0":: "m"(*((uint32*)addr)): "memory");
asm volatile("sti");
}
Here is the disassembly
0) [0x000000000010390c] 0008:c000390c (vmmgr_flush_tlb_entry+0): cli
<bochs:3> s
Next at t=157661647
(0) [0x000000000010390d] 0008:c000390d (vmmgr_flush_tlb_entry+1): mov eax, dword ptr ss:[esp+4]
<bochs:4> print-stack
Stack address size 4
| STACK 0xc000af4c [0xc0003ce2]
| STACK 0xc000af50 [0xc0000000] <<<<<<<<<<<<<<<<<<<<<<<<
| STACK 0xc000af54 [0x00008000]
(0) [0x0000000000103911] 0008:c0003911 (vmmgr_flush_tlb_entry+5): invlpg ds:[eax]
<bochs:6> info cpu
eax: 0xc0000000 -1073741824 <<<<<<<<<<<<<<<<<<<<
ecx: 0x00000004 4
To me this appears that invlpg takes the value at the address which needs to invalidated.
When I change the function back to -
Code: Select all
void vmmgr_flush_tlb_entry(void* addr)
{
asm volatile("cli");
asm volatile("invlpg %0":: "m"((uint32)addr): "memory"); // No de-referencing
asm volatile("sti");
}
the disassembly is -
(0) [0x000000000010390c] 0008:c000390c (vmmgr_flush_tlb_entry+0): cli
<bochs:4> s
Next at t=154722081
(0) [0x000000000010390d] 0008:c000390d (vmmgr_flush_tlb_entry+1): invlpg ss:[esp+4]
<bochs:6> print-stack
Stack address size 4
| STACK 0xc000af4c [0xc0003ce0]
| STACK 0xc000af50 [0xc0000000]
from which it seems that invlpg is given the address that is to be invalidated and this is not working.
I hope I am not wrong at least in interpreting the disassembly.
-Thanks
Vaibhav Jain
Re: problem changing page table in bochs
Posted: Thu Jun 07, 2012 4:46 pm
by Combuster
briefly looking at the docs, it looks like it should be currently invalidating the page at 0xc000a000.
Re: problem changing page table in bochs
Posted: Fri Jun 08, 2012 2:45 am
by iansjack
I think perhaps the OP is misunderstanding the documentation of INVLPG in the Intel manual:
"INVLPG m
Invalidate TLB Entry for page that contains m."
It doesn't say "Invalidate TLB Entry for page that contains the value in m".
This is as opposed to, for example, the NEG instruction for which the AMD manual says
"Performs the two’s complement negation of the value in the specified ... memory location".
(I think the AMD documentation makes this clearer than the Intel documents.)
Note the difference between "m" and "the value in m". It's a question of what "m" is.
Re: problem changing page table in bochs
Posted: Fri Jun 08, 2012 5:46 pm
by vjain20
Note the difference between "m" and "the value in m". It's a question of what "m" is.
This is what I am wondering about. What is m ?
From the disassembly I understand that
invlpg *(0xC0000000) is working (invalidating the entry for 0xC0000000)
while
invlpg 0xC0000000 is Not which is counter-intuitive to me.
I feel embarrassed to be not able to understand this after so much discussion
Thanks
Vaibhav Jain
Re: problem changing page table in bochs
Posted: Sat Jun 09, 2012 12:29 am
by iansjack
m in this case is the value of the stack pointer (0xc000a000) which is the address of the parameter you passed to the function (which points to 0xc0000000, the value you passed in that parameter). So you are invalidating the page containing 0xc000a000. When you dereference the pointer you invalidate the page containing 0xc0000000, which is what you want to do.
Re: problem changing page table in bochs
Posted: Sat Jun 09, 2012 2:20 am
by vjain20
m in this case is the value of the stack pointer (0xc000a000) which is the address of the parameter you passed to the function (which points to 0xc0000000, the value you passed in that parameter). So you are invalidating the page containing 0xc000a000. When you dereference the pointer you invalidate the page containing 0xc0000000, which is what you want to do.
Thanks for the explanation @iansjack. I think i failed to make myself clear but I don't want to take any more of your time.
So I am stating for the last time what I actually found to be working and what I didn't -
WORKING - :
mov eax, dword ptr ss:[esp+4]
<bochs:4> print-stack
Stack address size 4
| STACK 0xc000af4c [0xc0003ce2]
| STACK 0xc000af50 [0xc0000000] <<<<<<<<<<<<<<<<<<<<<<<<
//eax should now have the value 0xC0000000- the address to be invalidated
invlpg ds:[eax]
//As far as I understand ds:[eax] is equal to value pointed to by 0xC000000 and not equal to 0xC0000000
NOT WORKING :-
invlpg ss:[esp+4]
<bochs:6> print-stack
Stack address size 4
| STACK 0xc000af4c [0xc0003ce0]
| STACK 0xc000af50 [0xc0000000]
//Here ss:[esp+4] should be equal to 0xC0000000 - the address to be invalidated - but this is NOT working.
If I understood your comments correctly this is not how it should be i.e. the first one should fail and the second one should work. If I misunderstood
then I should keep quiet about this. Anyways I have the code working.
-Thanks
Re: problem changing page table in bochs
Posted: Sat Jun 09, 2012 3:24 am
by Combuster
vjain20 wrote:invlpg 0xC0000000 is Not which is counter-intuitive to me.
It actually doesn't even assemble because invlpg demands a memory operand, not an immediate or register value.
INVLPG falls in the same class as the LEA instruction. They both take a memory operand, but do not actually use the
data stored at that location. INVLPG says that any TLB entries that would otherwise be used for the access should be deleted. The more common LEA opcode differs from MOV by telling us to return the address that would be used instead of the actual data.
Re: problem changing page table in bochs
Posted: Sat Jun 09, 2012 4:18 am
by iansjack
"As far as I understand ds:[eax] is equal to value pointed to by 0xC000000 and not equal to 0xC0000000"
Unfortunately you understand incorrectly. There's little more I can add, other than suggest that you study both Intel and AMD manuals carefully. Or else, just accept that that is the way is (and, as Combuster says, be careful if you ever use the LEA instruction).
Re: problem changing page table in bochs
Posted: Sat Jun 09, 2012 10:34 pm
by jbemmel
It's a matter of syntax and context. "ds:[eax]" CAN mean "the value stored at the address contained in EAX", for example in the context of a MOV instruction (which is more common, so this explains why you think of it in this way).
However, in the context of INVLPG, INVLPG ds:[eax] means "invalidate the TLB entry for the page that contains the address stored in EAX"
The error comes from looking only at "ds:[eax]" - you need to know the associated instruction to interpret what it means.
Of course, Intel could have designed the opcode to take a register operand as input - but they didn't