problem changing page table in bochs
Re: problem changing page table in bochs
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
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
Here is the disassembly
When I change the function back to -
the disassembly is -
I hope I am not wrong at least in interpreting the disassembly.
-Thanks
Vaibhav Jain
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");
}
To me this appears that invlpg takes the value at the address which needs to invalidated.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
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");
}
from which it seems that invlpg is given the address that is to be invalidated and this is not working.(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]
I hope I am not wrong at least in interpreting the disassembly.
-Thanks
Vaibhav Jain
- Thanks
Vaibhav jain
Vaibhav jain
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
Re: problem changing page table in bochs
briefly looking at the docs, it looks like it should be currently invalidating the page at 0xc000a000.
Re: problem changing page table in bochs
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.
"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
This is what I am wondering about. What is m ?Note the difference between "m" and "the value in m". It's a question of what "m" is.
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
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
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.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.
So I am stating for the last time what I actually found to be working and what I didn't -
WORKING - :
NOT 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
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 misunderstoodinvlpg 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.
then I should keep quiet about this. Anyways I have the code working.
-Thanks
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
Re: problem changing page table in bochs
It actually doesn't even assemble because invlpg demands a memory operand, not an immediate or register value.vjain20 wrote:invlpg 0xC0000000 is Not which is counter-intuitive to me.
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
"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).
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
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
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