Dirty Stack?

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
DevNoteHQ
Member
Member
Posts: 50
Joined: Mon May 15, 2017 11:04 am

Dirty Stack?

Post by DevNoteHQ »

Hi guys! It's me again :mrgreen:

I discovered a weired issue in my VMM-Mapping-Methods.
The following code works:

Code: Select all

void KernelTable::Map2M(void *VirtAddress, const void *PhysAddress, uint64_t Bitmap)
{
	uint16_t PML4I = (((uint64_t)VirtAddress) >> 39) & 0x1FF;
	uint16_t PDPTI = (((uint64_t)VirtAddress) >> 30) & 0x1FF;
	uint16_t PDI = (((uint64_t)VirtAddress) >> 21) & 0x1FF;

	uint64_t *PML4E = GetAddress(511, 511, 511, PML4I);
	Check(PML4E, Bitmap);

	uint64_t *PDPTE = GetAddress(511, 511, PML4I, PDPTI);
	Check(PDPTE, Bitmap);

	uint64_t *PDE = GetAddress(511, PML4I, PDPTI, PDI);
	CheckPage(PDE, PhysAddress, (Bitmap | PG_BIG));
}
But without the "const" it doesn't. I've debugged it and it seems like after the first function call (GetAddress), the second parameter gets overwritten and is 0x0 instead of 0x200000 what it should have been. Bitmap seems to stay the same. Could that mean a dirty stack? Or is it maybe something C++-Related?

Thanks for your help!



EDIT: Well i've somehow fixed it... I changed my Check-Methode and now it works without the const in the parameter list... The question is why?
This is the original Check-Methode:

Code: Select all

void KernelTable::Check(uint64_t *Entry, uint64_t Bitmap)
{
	if ((*Entry == 0) || (((*Entry) & 0x1) == 0))
	{
		*Entry = (uint64_t)PMM::Alloc4K.Alloc() | Bitmap;
	}
}
And this is the edited Check-Methode:

Code: Select all

void KernelTable::Check(uint64_t *Entry, uint64_t Bitmap)
{
	if ((*Entry == 0) || (((*Entry) & 0x1) == 0))
	{
		*Entry = (uint64_t)PMM::Alloc4K.Alloc() | Bitmap;
		void *NextEntry = (uint64_t)Entry << 9;
		memset(NextEntry, 0, 4096);
	}
}
Which is obviously more bug-proof :mrgreen:
nullplan
Member
Member
Posts: 1801
Joined: Wed Aug 30, 2017 8:24 am

Re: Dirty Stack?

Post by nullplan »

Are you manipulating the currently used page table there? In that case, zero out a new page table before adding it. As soon as the write has commenced, the processor might update its TLB with whatever garbage still was in the newly added page.

Also, if the entire entry is zero then so is its least significant bit.

As for your original problem, I'm sure that was just coincidence. Maybe the missing const lead to a slightly different codegen, making the code win/loose a data race or something. Why are you treating physical addresses as pointers? They aren't: You can never dereference them.
Carpe diem!
DevNoteHQ
Member
Member
Posts: 50
Joined: Mon May 15, 2017 11:04 am

Re: Dirty Stack?

Post by DevNoteHQ »

Yes i am. I just didn't find an easy way to zero it out first. Then i realised i have Recrusive-Mapping :mrgreen:

Well i sure hope so :mrgreen:
Physical addresses are addresses so in my mind i had to represent them with pointers :mrgreen: But changing that would probably simplify things...
Post Reply