This is a sample in C++ which reproduce the problem randomly (1 ~ 2
seconds).
On the same host / guest / cpu that my previous mail.

2016-05-12 12:20 GMT+02:00 quentin buathier <qbuath...@tetrane.com>:

> Hi Michal,
>
> I can't now give a way to reproduce the bug but I'll send an executable if
> I manage to reproduce the problem on something minimalist.
>
> But I can give you the context of the problem:
>  Host OS: Debian jessie 64-bits
>  Guest OS: Debian jessie 32-bits
>  Processor: i7-2600 (and all i7 tested)
>
> PS: Sorry for the previous mail that was accidently sent
>
> Regards,
>
> 2016-05-12 12:18 GMT+02:00 quentin buathier <qbuath...@tetrane.com>:
>
>> Hi Michal,
>>
>> I can't now give a way to reproduce the bug. I'll send an executable if I
>> manage to reproduce the problem on something minimalist.
>>
>> But I can give you the context of the problem:
>>  Host OS: Debian jessie 64-bits
>>
>>
>> 2016-05-12 11:52 GMT+02:00 Michal Necasek <michal.neca...@oracle.com>:
>>
>>>
>>>    Hi Quentin,
>>>
>>>  Thank you for the patch!
>>>
>>>  Unfortunately (?) I can't reproduce the problem that was originally
>>> fixed. Could you please provide a bit more information? What's the host OS,
>>> guest OS, host CPU type? How to reproduce the problem?
>>>
>>>     Regards,
>>>       Michal
>>>
>>>
>>> On 5/12/2016 11:26 AM, quentin buathier wrote:
>>>
>>>> Hi,
>>>>
>>>> As I understand it, there used to be a problem with restoring the FPU
>>>> segments in case of a 64-bit hosts with a 32-bit guest. This issue has
>>>> been fixed by using the macros "SAVE_32_OR_64_FPU" and
>>>> "RESTORE_32_OR_64_FPU" in "src/VBox/VMM/VMMR0/CPUMR0A.asm" (when
>>>> Virtualbox was using fxsave and fxrstor to save and restore the FPU
>>>> context).
>>>>
>>>> But along with the recent support of xsave / xrstor, the bug was
>>>> reintroduced: if the CPU supports xsave/xrstor, Virtualbox uses these
>>>> instructions and the guest's FPU segments are not restored properly.
>>>>
>>>> Please find attached a possible patch to fix this issue (MIT licence).
>>>>
>>>> Regards,
>>>>
>>>>
>>>> _______________________________________________
>>>> vbox-dev mailing list
>>>> vbox-dev@virtualbox.org
>>>> https://www.virtualbox.org/mailman/listinfo/vbox-dev
>>>>
>>>>
>>> _______________________________________________
>>> vbox-dev mailing list
>>> vbox-dev@virtualbox.org
>>> https://www.virtualbox.org/mailman/listinfo/vbox-dev
>>>
>>
>>
>
#include <cstdint>
#include <iostream>
#include <exception>
#include <signal.h>

struct fpu_state
{
	std::uint16_t cw;
	std::uint16_t rsv_cw;

	std::uint16_t sw;
	std::uint16_t rsv_sw;

	std::uint16_t tw;
	std::uint16_t rsv_tw;

	std::uint32_t cp;

	std::uint16_t cs;
	std::uint16_t opcode;

	std::uint32_t dp;

	std::uint16_t ds;
	std::uint16_t ds_rsv;

} __attribute__((aligned(16))) ;

void print_fpu_state(const fpu_state& state)
{
	std::cout
		<< std::hex

		<< "0x" << state.rsv_cw << "\t" << "0x" << state.cw << "\t(rsv - cw)" <<  std::endl
		<< "0x" << state.rsv_sw << "\t" << "0x" << state.sw << "\t(rsv - sw)" << std::endl
		<< "0x" << state.rsv_tw << "\t" << "0x" << state.tw << "\t(rsv - tw)" << std::endl

		<< "-\t0x" << state.cp << "\t(instruction pointer)" << std::endl

		<< "0x" << state.opcode << "\t" << "0x" << state.cs << "\t(opcode - cs)" << std::endl

		<< "-\t0x" << state.dp << "\t(operand pointer)" << std::endl

		<< "0x" << state.ds_rsv << "\t" << "0x" << state.ds << "\t(rsv - ds)" << std::endl
		<< "end"
		<< std::dec
		<< std::endl;
}

bool is_any_seg_zero()
{
	static fpu_state state;
	__asm__ volatile ("fnstenv %0" : "=m"(state));

	print_fpu_state(state);
	return not state.cs or not state.ds;
}

void sigint3(int)
{
	std::cout << "int 3" << std::endl;
}

int main(int argc, char* argv[])
{
	double zero = 0.0;
	__asm__ volatile ("fninit");
	
	signal(SIGTRAP, &sigint3);

	unsigned c = 0;
	while(1)
	{
		// Just do some fpu operations and interrupt
		__asm__ volatile ("fldpi");
		__asm__ volatile ("fadd %0" :: "m"(zero));
		__asm__ volatile ("int3");

		c++;
		
		// Randomly this test will success (maybe task switching?)
		if (is_any_seg_zero()) {
			std::cout << "segs unset " << c << std::endl;
			return 1;
		}
	}

	std::cout << "segs set" << std::endl;

	return 0;
}
_______________________________________________
vbox-dev mailing list
vbox-dev@virtualbox.org
https://www.virtualbox.org/mailman/listinfo/vbox-dev

Reply via email to