[PATCH] target/i386: Change CR4 before CR0 in SVM

2023-01-27 Thread Bernhard Kauer
Resend as attachment as the previous version gots corrupted.From abea41b457aff4c04c3aa397b88847b66aaff1ad Mon Sep 17 00:00:00 2001
From: Bernhard Kauer 
Date: Fri, 20 Jan 2023 21:33:04 +
Subject: [PATCH 2/2] target/i386: Change CR4 before CR0 in SVM

There is a dependency in cpu_x86_update_cr0() to the current value of CR4
to enable or disable long-mode.  This value is outdated when switching into
or out of SVM. This leads to invalid CPU state when returning from an unpaged
VM when EFER.LME is set.

Signed-off-by: Bernhard Kauer 
---
 target/i386/tcg/sysemu/svm_helper.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/target/i386/tcg/sysemu/svm_helper.c b/target/i386/tcg/sysemu/svm_helper.c
index 2d27731b60..229a22816e 100644
--- a/target/i386/tcg/sysemu/svm_helper.c
+++ b/target/i386/tcg/sysemu/svm_helper.c
@@ -312,8 +312,8 @@ void helper_vmrun(CPUX86State *env, int aflag, int next_eip_addend)
 x86_stq_phys(cs,
  env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2), 0);
 
-cpu_x86_update_cr0(env, new_cr0);
 cpu_x86_update_cr4(env, new_cr4);
+cpu_x86_update_cr0(env, new_cr0);
 cpu_x86_update_cr3(env, new_cr3);
 env->cr[2] = x86_ldq_phys(cs,
   env->vm_vmcb + offsetof(struct vmcb, save.cr2));
@@ -812,13 +812,13 @@ void do_vmexit(CPUX86State *env)
 env->idt.limit = x86_ldl_phys(cs, env->vm_hsave + offsetof(struct vmcb,
save.idtr.limit));
 
+cpu_x86_update_cr4(env, x86_ldq_phys(cs,
+ env->vm_hsave + offsetof(struct vmcb,
+  save.cr4)));
 cpu_x86_update_cr0(env, x86_ldq_phys(cs,
  env->vm_hsave + offsetof(struct vmcb,
   save.cr0)) |
CR0_PE_MASK);
-cpu_x86_update_cr4(env, x86_ldq_phys(cs,
- env->vm_hsave + offsetof(struct vmcb,
-  save.cr4)));
 cpu_x86_update_cr3(env, x86_ldq_phys(cs,
  env->vm_hsave + offsetof(struct vmcb,
   save.cr3)));
-- 
2.39.0



[PATCH] target/i386: translate GPA to HPA even in unpaged mode

2023-01-20 Thread Bernhard Kauer
Guest to host page translation is missing if the guest runs in unpaged mode.
See last sentence in AMD SDM rev 3.40 section 15.25.5.

Signed-off-by: Bernhard Kauer 
---
 target/i386/tcg/sysemu/excp_helper.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/target/i386/tcg/sysemu/excp_helper.c 
b/target/i386/tcg/sysemu/excp_helper.c
index 55bd1194d3..8d9152245b 100644
--- a/target/i386/tcg/sysemu/excp_helper.c
+++ b/target/i386/tcg/sysemu/excp_helper.c
@@ -576,6 +576,9 @@ static bool get_physical_address(CPUX86State *env, vaddr 
addr,
 }
 return mmu_translate(env, , out, err);
 }
+if (use_stage2) {
+return get_physical_address(env, addr, access_type, 
MMU_NESTED_IDX, out, err);
+}
 break;
 }




[PATCH] target/i386: translate GPA to HPA even in unpaged mode

2023-01-20 Thread Bernhard Kauer
Guest to host page translation should be done even if the guest runs in unpaged 
mode.
See last sentence in AMD SDM rev 3.40 section 15.25.5.

Signed-off-by: Bernhard Kauer 
---
 target/i386/tcg/sysemu/excp_helper.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/target/i386/tcg/sysemu/excp_helper.c 
b/target/i386/tcg/sysemu/excp_helper.c
index 55bd1194d3..8d9152245b 100644
--- a/target/i386/tcg/sysemu/excp_helper.c
+++ b/target/i386/tcg/sysemu/excp_helper.c
@@ -576,6 +576,9 @@ static bool get_physical_address(CPUX86State *env, vaddr 
addr,
             }
             return mmu_translate(env, , out, err);
         }
+        if (use_stage2) {
+            return get_physical_address(env, addr, access_type, 
MMU_NESTED_IDX, out, err);
+        }
         break;
     }
 



Patch: target/i386: Change CR4 before CR0 in SVM

2023-01-20 Thread Bernhard Kauer
 There is a dependency in cpu_x86_update_cr0() to the current value of CR4
 to enable or disable long-mode.  This value is outdated when switching into
 or out of SVM. This leads to invalid CPU state when returning from an unpaged
 VM when EFER.LME is set.
    
Signed-off-by: Bernhard Kauer 

diff --git a/target/i386/tcg/sysemu/svm_helper.c 
b/target/i386/tcg/sysemu/svm_helper.c
index 2d27731b60..229a22816e 100644
--- a/target/i386/tcg/sysemu/svm_helper.c
+++ b/target/i386/tcg/sysemu/svm_helper.c
@@ -312,8 +312,8 @@ void helper_vmrun(CPUX86State *env, int aflag, int 
next_eip_addend)
     x86_stq_phys(cs,
              env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2), 0);
 
-    cpu_x86_update_cr0(env, new_cr0);
     cpu_x86_update_cr4(env, new_cr4);
+    cpu_x86_update_cr0(env, new_cr0);
     cpu_x86_update_cr3(env, new_cr3);
     env->cr[2] = x86_ldq_phys(cs,
                           env->vm_vmcb + offsetof(struct vmcb, save.cr2));
@@ -812,13 +812,13 @@ void do_vmexit(CPUX86State *env)
     env->idt.limit = x86_ldl_phys(cs, env->vm_hsave + offsetof(struct vmcb,
                                                        save.idtr.limit));
 
+    cpu_x86_update_cr4(env, x86_ldq_phys(cs,
+                                     env->vm_hsave + offsetof(struct vmcb,
+                                                              save.cr4)));
     cpu_x86_update_cr0(env, x86_ldq_phys(cs,
                                      env->vm_hsave + offsetof(struct vmcb,
                                                               save.cr0)) |
                        CR0_PE_MASK);
-    cpu_x86_update_cr4(env, x86_ldq_phys(cs,
-                                     env->vm_hsave + offsetof(struct vmcb,
-                                                              save.cr4)));
     cpu_x86_update_cr3(env, x86_ldq_phys(cs,
                                      env->vm_hsave + offsetof(struct vmcb,
                                                               save.cr3)));



Re: [Qemu-devel] [PATCH] fix curses update - v2

2010-05-21 Thread Bernhard Kauer
On Fri, May 21, 2010 at 02:02:43PM +0200, andrzej zaborowski wrote:
 I pushed a modified patch to preserve attributes such as background
 colour.

Good idea.

  Please check if this works for you.

Yes, this works.


Thanks,

Bernhard Kauer



[Qemu-devel] [PATCH] fix curses update - v2

2010-05-20 Thread Bernhard Kauer
On Mon, May 03, 2010 at 01:06:46PM -0500, Anthony Liguori wrote:
 On 04/22/2010 09:08 AM, Bernhard Kauer wrote:
 Hi,
 
 I believe this issue has come up before with a similar patch but
 well i've submitted such a patch more than two years ago.  Unfortunatelly
 it got never applied, so that I have to patch my Qemu on every update...
 
 
 someone checked their ncurses and they didn't see the same issue.
 I just checked and here mvwaddchnstr() does not expect a null-terminated
 string either, but it skips the \0 characters.
 This is not conforming to the Single UNIX Specification, which states
 that the string is shown until a null chtype is encountered. See for
 example:
http://www.opengroup.org/onlinepubs/007908775/xcurses/addchstr.html
 
 
   So probably we should
 replace them with spaces or something else,  I wouldn't like to
 replace a single library call with 80 calls, it's better to go through
 the string and replace them, maybe in console_write_ch or somewhere
 else.
 That would be a one-liner.  Should I send such a patch?
 
 Yes.

Replace the \0 character with a space to allow to use mvwaddchnstr for
full-screen updates in curses mode.


Signed-off-by: Bernhard Kauer ka...@tudos.org

diff --git a/console.h b/console.h
index 6def115..42ff822 100644
--- a/console.h
+++ b/console.h
@@ -306,6 +306,7 @@ static inline int ds_get_bytes_per_pixel(DisplayState *ds)
 typedef unsigned long console_ch_t;
 static inline void console_write_ch(console_ch_t *dest, uint32_t ch)
 {
+if (!(ch  0xff))  ch = 0x20;
 cpu_to_le32wu((uint32_t *) dest, ch);
 }





Re: [Qemu-devel] [PATCH] fix curses update

2010-04-22 Thread Bernhard Kauer
Hi,

 I believe this issue has come up before with a similar patch but

well i've submitted such a patch more than two years ago.  Unfortunatelly
it got never applied, so that I have to patch my Qemu on every update...


 someone checked their ncurses and they didn't see the same issue. 
 I just checked and here mvwaddchnstr() does not expect a null-terminated
 string either, but it skips the \0 characters.

This is not conforming to the Single UNIX Specification, which states
that the string is shown until a null chtype is encountered. See for
example:
  http://www.opengroup.org/onlinepubs/007908775/xcurses/addchstr.html 


  So probably we should
 replace them with spaces or something else,  I wouldn't like to
 replace a single library call with 80 calls, it's better to go through
 the string and replace them, maybe in console_write_ch or somewhere
 else.

That would be a one-liner.  Should I send such a patch?


Thanks,

Bernhard




[Qemu-devel] [PATCH] fix curses update

2010-04-20 Thread Bernhard Kauer
If a terminal is resized or the VGA model issues a full refresh, curses_update()
is called, which uses mvwaddchnstr() to draw a full line of characters.  
Unfortunatelly
this routine expects a null-terminated string and early aborts if a null is 
present
in the line. 

When booting an OS that zeros the VGA text buffer and later pokes single 
characters,
the console output can become unreadable.  The attached patch corrects this bug.


Bernhard Kauer



Signed-off-by: Bernhard Kauer ka...@tudos.org

diff --git a/curses.c b/curses.c
index ed3165e..9bf9265 100644
--- a/curses.c
+++ b/curses.c
@@ -48,10 +48,12 @@ static int px, py, sminx, sminy, smaxx, smaxy;
 static void curses_update(DisplayState *ds, int x, int y, int w, int h)
 {
 chtype *line;
+int i;
 
 line = ((chtype *) screen) + y * width;
 for (h += y; y  h; y ++, line += width)
-mvwaddchnstr(screenpad, y, 0, line, width);
+  for (i = 0; i  width; i++)
+   mvwaddch(screenpad, y, i, (line[i]  0xff) ? line[i] : ' ');
 
 pnoutrefresh(screenpad, py, px, sminy, sminx, smaxy - 1, smaxx - 1);
 refresh();




Re: [Qemu-devel] [PATCH] allow update of MSR_EFER_SVM

2008-02-29 Thread Bernhard Kauer
On Wed, Feb 27, 2008 at 06:03:49PM +0100, Alexander Graf wrote:
 MSR_EFER_SVM is not defined in my qemu version. What does the bit change 
 if set?

The AMD vol2 reads like this:

Secure Virtual Machine Enable (SVME) Bit. Bit 12. Enables the SVM 
extensions.
When this bit is zero, the SVM instructions cause #UD exceptions.

The bit was called MSR_EFER_SVME_MASK in svm.h before, I renamed it in the
attached patch to MSR_EFER_SVME to match the style of the other definitions
in cpu.h.

BTW, triggering the above mentioned #UD is missing in the code...


Bernhard Kauer
Index: target-i386/helper.c
===
RCS file: /sources/qemu/qemu/target-i386/helper.c,v
retrieving revision 1.101
diff -u -r1.101 helper.c
--- target-i386/helper.c	3 Feb 2008 03:26:30 -	1.101
+++ target-i386/helper.c	29 Feb 2008 09:33:41 -
@@ -2802,6 +2802,8 @@
 update_mask |= MSR_EFER_FFXSR;
 if (env-cpuid_ext2_features  CPUID_EXT2_NX)
 update_mask |= MSR_EFER_NXE;
+	if (env-cpuid_ext3_features  CPUID_EXT3_SVM)
+	update_mask |= MSR_EFER_SVME;
 env-efer = (env-efer  ~update_mask) |
 (val  update_mask);
 }
Index: target-i386/svm.h
===
RCS file: /sources/qemu/qemu/target-i386/svm.h,v
retrieving revision 1.1
diff -u -r1.1 svm.h
--- target-i386/svm.h	23 Sep 2007 15:30:28 -	1.1
+++ target-i386/svm.h	29 Feb 2008 09:33:41 -
@@ -179,7 +179,7 @@
 #define SVM_CPUID_FEATURE_SHIFT 2
 #define SVM_CPUID_FUNC 0x800a
 
-#define MSR_EFER_SVME_MASK (1ULL  12)
+#define MSR_EFER_SVME  (1ULL  12)
 
 #define SVM_SELECTOR_S_SHIFT 4
 #define SVM_SELECTOR_DPL_SHIFT 5


Re: [Qemu-devel] [PATCH] allow update of MSR_EFER_SVM

2008-02-29 Thread Bernhard Kauer
On Fri, Feb 29, 2008 at 11:20:24AM +0100, Alexander Graf wrote:
 Keep in mind that updating the bit should fail within a virtual machine.

I found the following sentence in the manual:

The effect of turning off EFER.SVME while a guest is running is 
undefined;
therefore, the VMM should always prevent guests from writing EFER.

Therefore i think the wrmsr-code is just fine, as it is in my patch.


Bernhard Kauer




[Qemu-devel] [PATCH] allow update of MSR_EFER_SVM

2008-02-27 Thread Bernhard Kauer
The wrmsr_helper should allow to set the SVM flag in EFER.


Bernhard Kauer
Index: target-i386/helper.c
===
RCS file: /sources/qemu/qemu/target-i386/helper.c,v
retrieving revision 1.101
diff -u -r1.101 helper.c
--- target-i386/helper.c	3 Feb 2008 03:26:30 -	1.101
+++ target-i386/helper.c	27 Feb 2008 16:05:33 -
@@ -2802,6 +2802,8 @@
 update_mask |= MSR_EFER_FFXSR;
 if (env-cpuid_ext2_features  CPUID_EXT2_NX)
 update_mask |= MSR_EFER_NXE;
+	if (env-cpuid_ext3_features  CPUID_EXT3_SVM)
+	update_mask |= MSR_EFER_SVM;
 env-efer = (env-efer  ~update_mask) |
 (val  update_mask);
 }


[Qemu-devel] [PATCH] fix ncurses output

2008-02-25 Thread Bernhard Kauer
The ncurses console uses mvwaddchnstr() to print a line of output
to a ncurses pad. Unfortunately this routine stops to print further
chars if a zero-char is seen in the line. This has the effect that
parts of a line are never redraw.

The following patch puts spaces instead of the zeros into the line-buffer.
Please note that this change affects other consoles as well and is
perhaps undesirable. Comments?


Bernhard Kauer
Index: console.h
--- console.h	10 Feb 2008 16:33:13 -	1.2
+++ console.h	25 Feb 2008 17:25:53 -
@@ -104,7 +104,8 @@
 typedef unsigned long console_ch_t;
 static inline void console_write_ch(console_ch_t *dest, uint32_t ch)
 {
-cpu_to_le32wu((uint32_t *) dest, ch);
+  if (!(ch  0xff))  ch = 0x20;
+  cpu_to_le32wu((uint32_t *) dest, ch);
 }
 
 typedef void (*vga_hw_update_ptr)(void *);


[Qemu-devel] [PATCH] fix SVM event injection

2008-01-23 Thread Bernhard Kauer
The SVM event injection mechanism for NMI and INTRs should not
be handled as software interrupts.


Bernhard Kauer
Index: target-i386/helper.c
--- target-i386/helper.c	24 Dec 2007 13:36:00 -	1.98
+++ target-i386/helper.c	23 Jan 2008 22:37:49 -
@@ -4124,7 +4193,7 @@
 case SVM_EVTINJ_TYPE_INTR:
 env-exception_index = vector;
 env-error_code = event_inj_err;
-env-exception_is_int = 1;
+env-exception_is_int = 0;
 env-exception_next_eip = -1;
 if (loglevel  CPU_LOG_TB_IN_ASM)
 fprintf(logfile, INTR);
@@ -4132,7 +4201,7 @@
 case SVM_EVTINJ_TYPE_NMI:
 env-exception_index = vector;
 env-error_code = event_inj_err;
-env-exception_is_int = 1;
+env-exception_is_int = 0;
 env-exception_next_eip = EIP;
 if (loglevel  CPU_LOG_TB_IN_ASM)
 fprintf(logfile, NMI);


Re: [Qemu-devel] [PATCH]SVM CR8 undefined bug fix

2008-01-17 Thread Bernhard Kauer
On Thu, Jan 17, 2008 at 05:13:31PM +0100, Alexander Graf wrote:
 Their only difference is, that the TPR is implemented as an MSR, whereas 
 the CR8 is a CPU register.

The TPR is currently a memory mapped local Apic register. The
default address is 0xfee00080, according to Intel vol3a chapter 8...


Bernhard Kauer





[Qemu-devel] [PATCH] fix cmpxchg8b translation

2007-12-18 Thread Bernhard Kauer
The cmpxchg8b opcode is only valid if the nnn bits
in the mod/rm byte are 001, otherwise an #UD should
be generated. The attached patch fixes this.


Bernhard Kauer
Index: target-i386/translate.c
--- target-i386/translate.c	8 Nov 2007 14:25:03 -	1.74
+++ target-i386/translate.c	18 Dec 2007 12:14:08 -
@@ -3887,7 +3887,7 @@
 case 0x1c7: /* cmpxchg8b */
 modrm = ldub_code(s-pc++);
 mod = (modrm  6)  3;
-if (mod == 3)
+if ((mod == 3) || ((modrm  0x38) != 0x8))
 goto illegal_op;
 gen_jmp_im(pc_start - s-cs_base);
 if (s-cc_op != CC_OP_DYNAMIC)


[Qemu-devel] [PATCH] SVM enabled processor should provide cpuid Fn8000_000A

2007-12-18 Thread Bernhard Kauer
An SVM enabled processor should provide the CPUID extended leaf Fn8000_000A
(see AMD documentation #25481). The attached patch add this feature.


Bernhard Kauer
Index: target-i386/helper.c
===
RCS file: /sources/qemu/qemu/target-i386/helper.c,v
retrieving revision 1.97
diff -u -r1.97 helper.c
--- target-i386/helper.c	9 Dec 2007 23:39:22 -	1.97
+++ target-i386/helper.c	18 Dec 2007 12:40:06 -
@@ -1751,6 +1819,12 @@
 ECX = 0;
 EDX = 0;
 break;
+case 0x800A:
+EAX = 0x0001;
+EBX = 0;
+ECX = 0;
+EDX = 0;
+	break;
 default:
 /* reserved values: zero */
 EAX = 0;
Index: target-i386/helper2.c
===
RCS file: /sources/qemu/qemu/target-i386/helper2.c,v
retrieving revision 1.60
diff -u -r1.60 helper2.c
--- target-i386/helper2.c	9 Dec 2007 02:43:19 -	1.60
+++ target-i386/helper2.c	18 Dec 2007 12:40:06 -
@@ -150,7 +150,7 @@
 .ext2_features = (PPRO_FEATURES  0x0183F3FF) | 
 CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
 .ext3_features = CPUID_EXT3_SVM,
-.xlevel = 0x8008,
+.xlevel = 0x800A,
 },
 #endif
 {



Re: [Qemu-devel] [PATCH] SVM IOIO intercept does not check all bits

2007-12-08 Thread Bernhard Kauer
On Fri, Dec 07, 2007 at 04:16:00PM +0100, Alexander Graf wrote:
 For IN/OUT instructions that access more than a single byte, the
 permission bits for all bytes are checked; if any bit is set to 1,
 the I/O operation is intercepted.


 That was the one. Thank you.


Unfortunately there is another bug in this line. As there
is only a single byte read from the permission bitmap, an
unaligned 4-byte access to port 0x7 would be possible even
when the access to port 0x8-0xa is not allowed. The updated
patch fixes also this case.


Bernhard Kauer
Index: target-i386/helper.c
===
RCS file: /sources/qemu/qemu/target-i386/helper.c,v
retrieving revision 1.95
diff -u -r1.95 helper.c
--- target-i386/helper.c	18 Nov 2007 01:44:38 -	1.95
+++ target-i386/helper.c	8 Dec 2007 20:44:28 -
@@ -4250,7 +4332,8 @@
 uint64_t addr = ldq_phys(env-vm_vmcb + offsetof(struct vmcb, control.iopm_base_pa));
 uint16_t port = (uint16_t) (param  16);
 
-if(ldub_phys(addr + port / 8)  (1  (port % 8)))
+uint16_t mask = (1  ((param  4)  7)) - 1;
+if(lduw_phys(addr + port / 8)  (mask  (port  7)))
 vmexit(type, param);
 }
 break;


Re: [Qemu-devel] [PATCH] SVM IOIO intercept does not check all bits

2007-12-07 Thread Bernhard Kauer
On Fri, Dec 07, 2007 at 02:10:35PM +0100, Alexander Graf wrote:
 Could you please make this more readable?

Not easy by a one liner. I splitted the mask calculation in a separate line.
Is it better now?

 Apart from that the patch is fine if the highest bit in the IOIO vector is
 to be set. I could not find that in the documentation.


I did not understand your comment. Perhaps you mean the following
sentence from the AMD vol. 2:

 For IN/OUT instructions that access more than a single byte, the
 permission bits for all bytes are checked; if any bit is set to 1,
 the I/O operation is intercepted.


Greetings,

Bernhard
Index: target-i386/helper.c
===
RCS file: /sources/qemu/qemu/target-i386/helper.c,v
retrieving revision 1.95
diff -u -r1.95 helper.c
--- target-i386/helper.c	18 Nov 2007 01:44:38 -	1.95
+++ target-i386/helper.c	7 Dec 2007 14:10:57 -
@@ -4250,7 +4331,8 @@
 uint64_t addr = ldq_phys(env-vm_vmcb + offsetof(struct vmcb, control.iopm_base_pa));
 uint16_t port = (uint16_t) (param  16);
 
-if(ldub_phys(addr + port / 8)  (1  (port % 8)))
+	uint8_t mask = (1  ((param  4)  0x7)) - 1;
+	if(ldub_phys(addr + port / 8)  (mask  (port % 8)))
 vmexit(type, param);
 }
 break;


[Qemu-devel] [PATCH] SVM IOIO intercept does not check all bits

2007-12-06 Thread Bernhard Kauer
The SVM IOIO intercept does not check all bits in the IO permission map
for in/outs with word or long operand size. The attached patch fix this.


Bernhard Kauer
Index: target-i386/helper.c
--- target-i386/helper.c	18 Nov 2007 01:44:38 -	1.95
+++ target-i386/helper.c	6 Dec 2007 19:22:55 -
@@ -4250,8 +4331,8 @@
 uint64_t addr = ldq_phys(env-vm_vmcb + offsetof(struct vmcb, control.iopm_base_pa));
 uint16_t port = (uint16_t) (param  16);
 
-if(ldub_phys(addr + port / 8)  (1  (port % 8)))
-vmexit(type, param);
+	if(ldub_phys(addr + port / 8)  (((1  ((param  4)  0x7)) - 1)  (port % 8)))
+	  vmexit(type, param);
 }
 break;
 


[Qemu-devel] [PATCH] add rdpmc intercept for SVM

2007-12-05 Thread Bernhard Kauer
The attached patch adds an SVM intercept for rdpmc to qemu,
thus allowing a VMM to virtualize them. Please note that 
performance counters are currently unimplemented in qemu.


Bernhard Kauer
Index: target-i386/helper.c
--- target-i386/helper.c	18 Nov 2007 01:44:38 -	1.95
+++ target-i386/helper.c	5 Dec 2007 19:31:31 -
@@ -2743,6 +2816,19 @@
 EDX = (uint32_t)(val  32);
 }
 
+void helper_rdpmc()
+{
+  if ((env-cr[4]  CR4_PCE_MASK)  ((env-hflags  HF_CPL_MASK) != 0)) {
+raise_exception(EXCP0D_GPF);
+  }
+  
+  if (!svm_check_intercept_param(SVM_EXIT_RDPMC, 0))
+{
+  // currently unimplemented
+  raise_exception_err(EXCP06_ILLOP, 0);
+}
+}
+
 #if defined(CONFIG_USER_ONLY)
 void helper_wrmsr(void)
 {
Index: target-i386/op.c
--- target-i386/op.c	23 Sep 2007 15:28:04 -	1.51
+++ target-i386/op.c	5 Dec 2007 19:31:32 -
@@ -953,6 +953,11 @@
 helper_rdtsc();
 }
 
+void OPPROTO op_rdpmc(void)
+{
+helper_rdpmc();
+}
+
 void OPPROTO op_cpuid(void)
 {
 helper_cpuid();
Index: target-i386/translate.c
--- target-i386/translate.c	8 Nov 2007 14:25:03 -	1.74
+++ target-i386/translate.c	5 Dec 2007 19:31:38 -
@@ -5653,5 +5653,9 @@
 gen_op_rdtsc();
 break;
+case 0x133: /* rdpmc */
+gen_jmp_im(pc_start - s-cs_base);
+gen_op_rdpmc();
+break;
 case 0x134: /* sysenter */
 if (CODE64(s))
 goto illegal_op;


Re: [Qemu-devel] [Patch] set boot sequence from command line

2007-10-25 Thread Bernhard Kauer
It is perhaps not the best idea to read behind the
end of the boot_device string. It would be safer to
declare boot_device as 'static char boot_device[4]'
and use a strncpy.


Bernhard


 diff --git a/hw/pc.c b/hw/pc.c
 index a0c824f..3c552ff 100644
 --- a/hw/pc.c
 +++ b/hw/pc.c
 +/* set boot devices, and disable floppy signature check if requested */
 +rtc_set_memory(s, 0x3d,
 +boot_device2nible(boot_device[1])  4 |
 +boot_device2nible(boot_device[0]) );
 +rtc_set_memory(s, 0x38,
 +boot_device2nible(boot_device[2])  4 | (fd_bootchk ? 0x0 : 
 0x1));
  
  /* floppy type */
 diff --git a/vl.c b/vl.c
 index 6d8fe35..be0e06a 100644
 --- a/vl.c
 +++ b/vl.c
 +if (strlen(optarg)  3) {
 +fprintf(stderr, qemu: too many boot devices\n);
 +exit(1);
 +}
 +boot_device = strdup(optarg);
 +if (!strchr(boot_device, 'a') 




Re: [Qemu-devel] BIOS: ACPI Tables: wrong memory pointer

2007-09-14 Thread Bernhard Kauer
On Fri, Sep 14, 2007 at 02:55:22PM +0200, Chris wrote:
 There is an error in the bios code (I haven´t found it) with the address 
 which gets insert into the acpi tables (rsdt address) and the address which 
 is inserted into the smap tables when the memory of the emulated machine is 
 under 19MiB RAM!

 From 19MiB RAM on the address in the smap tables and the address of the 
 rsdt in the acpi tables is correct. Maybe someone with more experience with 
 the bios code can look on this?

It's a Bochs Bios bug. See my mail [EMAIL PROTECTED]
from Sep 10 on the Bochs developer mailinglist for a patch.


Bernhard Kauer




Re: [Qemu-devel] [PATCH] SVM support

2007-08-30 Thread Bernhard Kauer
On Thu, Aug 30, 2007 at 04:54:15PM +0200, Alexander Graf wrote:
 Hi,
 
 after a lot of struggling I finally got everything working smoothly
 (special thanks to Fabrice and Avi), so I believe this patch is ready to
 be taken upstream.
 CC_DST was never a problem, as everything I did in the eflags area
 already worked. I managed to clobber the segment attributes though, so
 that was the real problem here.
 Nevertheless there is still a lot of functionality missing, whereas none
 of that is used in kvm by now, so that works already.
 
 So there are still missing parts that I will list here:
 
 - NPT support
 - Everything related to device virtualisation
 - The Secure part of the extension (would need TPM emulation for that)

I backported Xen's TPM emulation to Qemu for exactly that purpose.
I also started to implement skinit, but did not had the time to
finish that work, yet. Please note that this patch requires
a two line patch to the tpm-emulator to understand the localities.


Bernhard Kauer
Index: Makefile.target
===
RCS file: /sources/qemu/qemu/Makefile.target,v
retrieving revision 1.191
diff -u -r1.191 Makefile.target
--- Makefile.target	31 Jul 2007 23:44:21 -	1.191
+++ Makefile.target	7 Aug 2007 03:43:28 -
@@ -429,6 +429,7 @@
 VL_OBJS+= fdc.o mc146818rtc.o serial.o i8259.o i8254.o pcspk.o pc.o
 VL_OBJS+= cirrus_vga.o apic.o parallel.o acpi.o piix_pci.o
 VL_OBJS+= usb-uhci.o smbus_eeprom.o vmmouse.o vmware_vga.o
+VL_OBJS+= tpm_tis.o
 CPPFLAGS += -DHAS_AUDIO -DHAS_AUDIO_CHOICE
 endif
 ifeq ($(TARGET_BASE_ARCH), ppc)
Index: hw/pc.c
===
RCS file: /sources/qemu/qemu/hw/pc.c,v
retrieving revision 1.81
diff -u -r1.81 pc.c
--- hw/pc.c	6 Jun 2007 16:26:13 -	1.81
+++ hw/pc.c	7 Aug 2007 03:43:37 -
@@ -914,6 +917,9 @@
 if (i440fx_state) {
 i440fx_init_memory_mappings(i440fx_state);
 }
+
+tpm_tis_init();
+
 #if 0
 /* ??? Need to figure out some way for the user to
specify SCSI devices.  */
--- /dev/null	2007-08-06 15:49:45.580307540 +0200
+++ hw/tpm_tis.c	2007-08-07 05:39:41.0 +0200
@@ -0,0 +1,890 @@
+/*
+ * tpm_tis.c - QEMU emulator for a 1.2 TPM with TIS interface
+ *
+ * Copyright (C) 2006 IBM Corporation
+ *
+ * Author: Stefan Berger [EMAIL PROTECTED]
+ * David Safford [EMAIL PROTECTED]
+ * Bernhard Kauer [EMAIL PROTECTED]
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ *
+ * Implementation of the TIS interface according to specs at
+ * https://www.trustedcomputinggroup.org/groups/pc_client/TCG_PCClientTPMSpecification_1-20_1-00_FINAL.pdf
+ *
+ */
+
+#include sys/types.h
+#include sys/stat.h
+#include sys/socket.h
+#include sys/un.h
+#include fcntl.h
+#include errno.h
+#include assert.h
+#include vl.h
+
+
+#define DEBUG_TPM
+#define logfile stderr
+#define LOCAL_SOCKET_PATH  tpmd
+/* if the connection to the vTPM should be closed after a successfully
+   received response; set to '0' to allow keeping the connection */
+#define FORCE_CLOSE  0
+
+
+
+#define TPM_MAX_PKT	  4096
+#define TIS_ADDR_BASE 0xFED4
+
+/* tis registers */
+#define TPM_REG_ACCESS0x00
+#define TPM_REG_INT_ENABLE0x08
+#define TPM_REG_INT_VECTOR0x0c
+#define TPM_REG_INT_STATUS0x10
+#define TPM_REG_INTF_CAPABILITY   0x14
+#define TPM_REG_STS   0x18
+#define TPM_REG_HASH_END  0x20
+#define TPM_REG_DATA_FIFO 0x24
+#define TPM_REG_HASH_START0x28
+#define TPM_REG_DID_VID   0xf00
+#define TPM_REG_RID   0xf04
+
+#define STS_VALID(1  7)
+#define STS_COMMAND_READY(1  6)
+#define STS_TPM_GO   (1  5)
+#define STS_DATA_AVAILABLE   (1  4)
+#define STS_EXPECT   (1  3)
+#define STS_RESPONSE_RETRY   (1  1)
+
+#define ACCESS_TPM_REG_VALID_STS (1  7)
+#define ACCESS_ACTIVE_LOCALITY   (1  5)
+#define ACCESS_BEEN_SEIZED   (1  4)
+#define ACCESS_SEIZE (1  3)
+#define ACCESS_PENDING_REQUEST   (1  2)
+#define ACCESS_REQUEST_USE   (1  1)
+#define ACCESS_TPM_ESTABLISHMENT (1  0)
+
+#define INT_ENABLED  (1  31)
+#define INT_DATA_AVAILABLE   (1  0)
+#define INT_LOCALITY_CHANGED (1  2)
+#define INT_COMMAND_READY(1  7)
+
+#define INTERRUPTS_SUPPORTED (INT_LOCALITY_CHANGED | \
+  INT_DATA_AVAILABLE   | \
+  INT_COMMAND_READY)
+#define CAPABILITIES_SUPPORTED   ((1  4) |\
+  INTERRUPTS_SUPPORTED)
+
+enum {
+  STATE_IDLE

Re: [Qemu-devel] Patch: let qemu work with latest bochsbios

2007-08-17 Thread Bernhard Kauer
Has somebody besides me tested the patch?


Bernhard Kauer


On Wed, Aug 01, 2007 at 05:42:17PM +0200, Bernhard Kauer wrote:
 The boot_device is not communicated to the bochsbios
 through the CMOS. The following patch allows to boot 
 via network on the newest bochsbios.




Re: [Qemu-devel] Why not use exit() instead of abort()?

2007-08-17 Thread Bernhard Kauer
On Mon, Aug 06, 2007 at 07:21:21AM +0930, Dan Shearer wrote:
 On Sun, Aug 05, 2007 at 11:13:55PM +0200, Bernhard Kauer wrote:
  There are a couple of places in qemu, where abort() is called.
  The most commonly used one is perhaps cpu_abort() which is called
  e.g. when a triple fault occures.
  
  As abort() does not call any atexit() function, cleanup is not
  performed. 
 
 Tiny correction: abort() and _exit don't call atexit(), however
 unix-like OSs still cleanup memory and file descriptors and other
 transient resources  anyway no matter how the program ended. So lack of
 cleanup isn't quite as big an issue as it might seem.
 
  This leaves for example the terminal in a state where
  the cursor is invisible.
 
 Non-transient resources such as DSOs and domain sockets are not cleaned
 up by the OS, which accounts for the terminal problem you noticed.

Well, the problem is here that the function term_exit() is never
called, which would restore the terminal state to the old version
via a tcsetattr().


  Are there any reasons not to use exit(1) in cpu_abort()?
 
 Speed. I used to use abort() or _exit() for speed, ie they didn't hang
 around while atexit() waited politely for timeouts. I thought if I told
 the program to stop it should stop immediately :-)

I would use a 'kill -TERM' for that.


Bernhard




[Qemu-devel] Why not use exit() instead of abort()?

2007-08-05 Thread Bernhard Kauer
There are a couple of places in qemu, where abort() is called.
The most commonly used one is perhaps cpu_abort() which is called
e.g. when a triple fault occures.

As abort() does not call any atexit() function, cleanup is not
performed. This leaves for example the terminal in a state where
the cursor is invisible.

Are there any reasons not to use exit(1) in cpu_abort()?


Bernhard Kauer
Index: exec.c
===
RCS file: /sources/qemu/qemu/exec.c,v
retrieving revision 1.103
diff -u -r1.103 exec.c
--- exec.c	1 Jul 2007 18:21:11 -	1.103
+++ exec.c	4 Aug 2007 13:07:52 -
@@ -1301,7 +1301,7 @@
 fflush(logfile);
 fclose(logfile);
 }
-abort();
+exit(1);
 }
 
 CPUState *cpu_copy(CPUState *env)


[Qemu-devel] Patch: let qemu work with latest bochsbios

2007-08-01 Thread Bernhard Kauer
The boot_device is not communicated to the bochsbios
through the CMOS. The following patch allows to boot 
via network on the newest bochsbios.


Bernhard Kauer




[Qemu-devel] Patch: let qemu work with latest bochsbios

2007-08-01 Thread Bernhard Kauer
The boot_device is not communicated to the bochsbios
through the CMOS. The following patch allows to boot 
via network on the newest bochsbios.


Bernhard Kauer
Index: vl.c
===
RCS file: /sources/qemu/qemu/vl.c,v
retrieving revision 1.323
diff -u -r1.323 vl.c
--- vl.c	29 Jul 2007 17:57:25 -	1.323
+++ vl.c	1 Aug 2007 15:36:31 -
@@ -7828,7 +7828,7 @@
 	fprintf(stderr, No valid PXE rom found for network device\n);
 	exit(1);
 	}
-	boot_device = 'c'; /* to prevent confusion by the BIOS */
+	//boot_device = 'c'; /* to prevent confusion by the BIOS */
 }
 #endif
 
Index: hw/pc.c
===
RCS file: /sources/qemu/qemu/hw/pc.c,v
retrieving revision 1.81
diff -u -r1.81 pc.c
--- hw/pc.c	6 Jun 2007 16:26:13 -	1.81
+++ hw/pc.c	1 Aug 2007 15:36:31 -
@@ -197,6 +197,9 @@
 case 'd':
 rtc_set_memory(s, 0x3d, 0x03); /* CD-ROM boot */
 break;
+case 'n':
+rtc_set_memory(s, 0x3d, 0x04); /* Network boot */
+break;	
 }
 
 /* floppy type */


[Qemu-devel] Patch: fix init of old_exception

2007-07-31 Thread Bernhard Kauer
The old_exception field is initialized on startup with 0.
Therefore the very first fault (e.g. #GP) could be converted
to a double fault on an application processor. The attached
patch initialize old_exception on every CPU reset with -1.


Bernhard Kauer
Index: target-i386/helper2.c
===
RCS file: /sources/qemu/qemu/target-i386/helper2.c,v
retrieving revision 1.47
diff -u -r1.47 helper2.c
--- target-i386/helper2.c	17 Apr 2007 23:08:56 -	1.47
+++ target-i386/helper2.c	31 Jul 2007 14:30:55 -
@@ -155,6 +155,8 @@
 
 tlb_flush(env, 1);
 
+env-old_exception = -1;
+
 /* init to reset state */
 
 #ifdef CONFIG_SOFTMMU


[Qemu-devel] Patch: PIC-i8259 mode transition wrong

2007-07-31 Thread Bernhard Kauer
The PIC initilization should respect the fourth byte init
bit in single mode.


Bernhard Kauer
Index: hw/i8259.c
===
RCS file: /sources/qemu/qemu/hw/i8259.c,v
retrieving revision 1.22
diff -u -r1.22 i8259.c
--- hw/i8259.c	7 Apr 2007 18:14:41 -	1.22
+++ hw/i8259.c	31 Jul 2007 14:31:14 -
@@ -351,7 +351,7 @@
 break;
 case 1:
 s-irq_base = val  0xf8;
-s-init_state = s-single_mode  s-init4 ? 3 : 2;
+s-init_state = s-single_mode ? (s-init4 ? 3 : 0) : 2;
 break;
 case 2:
 if (s-init4) {


Re: [Qemu-devel] Qemu / KQemu on 64-bit (x86_64) host systems

2007-04-17 Thread Bernhard Kauer
On Mon, Apr 16, 2007 at 08:47:07AM +0200, Werner Dittmann wrote:
 My general thought about the problem: running 32bit code
 on a 64bit host with similar architecture as this is the case
 of x86 / x86_64 could easily result in problems with signedness,
 sign bit extension, different pointer/word/interger sizes...


qemu-system-x86_64 has indeed some signedness problem. I posted a
patch [EMAIL PROTECTED] a couple of
days ago for the problem that the pagefault address gets incorrectly
sign extended when running 32-bit code. Nevertheless its just a
workaround, the place where this wrong sign extension happend needs
still to be found.


Bernhard Kauer




[Qemu-devel] Patch: ptable calculation broken for 32bit code under x86_64

2007-04-10 Thread Bernhard Kauer
The calculation of pdpe and pde addresses is broken, when running 32bit
code under x86_64-qemu. The code assumes that the addr parameter is 32bit
wide. This assumption does not hold for x86_64 as target.

Bernhard Kauer

Index: target-i386/helper2.c
===
RCS file: /sources/qemu/qemu/target-i386/helper2.c,v
retrieving revision 1.46
diff -u -r1.46 helper2.c
--- target-i386/helper2.c	7 Apr 2007 11:21:28 -	1.46
+++ target-i386/helper2.c	10 Apr 2007 13:28:02 -
@@ -670,7 +670,7 @@
 #endif
 {
 /* XXX: load them when cr3 is loaded ? */
-pdpe_addr = ((env-cr[3]  ~0x1f) + ((addr  30)  3))  
+pdpe_addr = ((env-cr[3]  ~0x1f) + ((addr  27)  0x18))  
 env-a20_mask;
 pdpe = ldq_phys(pdpe_addr);
 if (!(pdpe  PG_PRESENT_MASK)) {
@@ -765,7 +765,7 @@
 uint32_t pde;
 
 /* page directory entry */
-pde_addr = ((env-cr[3]  ~0xfff) + ((addr  20)  ~3))  
+pde_addr = ((env-cr[3]  ~0xfff) + ((addr  20)  0xffc))  
 env-a20_mask;
 pde = ldl_phys(pde_addr);
 if (!(pde  PG_PRESENT_MASK)) {
@@ -910,7 +910,7 @@
 } else 
 #endif
 {
-pdpe_addr = ((env-cr[3]  ~0x1f) + ((addr  30)  3))  
+pdpe_addr = ((env-cr[3]  ~0x1f) + ((addr  27)  0x18))  
 env-a20_mask;
 pdpe = ldl_phys(pdpe_addr);
 if (!(pdpe  PG_PRESENT_MASK))
@@ -940,7 +940,7 @@
 page_size = 4096;
 } else {
 /* page directory entry */
-pde_addr = ((env-cr[3]  ~0xfff) + ((addr  20)  ~3))  env-a20_mask;
+pde_addr = ((env-cr[3]  ~0xfff) + ((addr  20)  0xffc))  env-a20_mask;
 pde = ldl_phys(pde_addr);
 if (!(pde  PG_PRESENT_MASK)) 
 return -1;


[Qemu-devel] Patch: generate double and triple faults

2007-03-31 Thread Bernhard Kauer
On Wed, Mar 28, 2007 at 02:39:31PM +0200, Bernhard Kauer wrote:
 On Wed, Mar 28, 2007 at 10:13:49AM +0200, Sebastian Kaliszewski wrote:
  Bernhard Kauer wrote:
  Qemu does not generate a double fault (DBF) on x86, if a general protection
  fault could not be delivered. Instead it hangs in a loop.
  
  The patch fix this bug by checking whether we are already in a GPF 
  exception.
  
  If you're at it, maybe add triple fault handling (ie exception if DBF 
  handler) -- it should reset CPU.
 
 There are many things missing in the x86 exception handling. For example
 the case PF - PF is also not handled.

The attached patch implements double andd triple fault handling and makes
the last patch obsolete. It does not generate a reset on triple fault, but
it aborts qemu. The same happen currently if the TSS is bogous.


Greetings,

Bernhard Kauer
Index: cpu-exec.c
===
RCS file: /sources/qemu/qemu/cpu-exec.c,v
retrieving revision 1.97
diff -u -r1.97 cpu-exec.c
--- cpu-exec.c  30 Mar 2007 16:44:53 -  1.97
+++ cpu-exec.c  31 Mar 2007 11:59:52 -
@@ -360,6 +360,7 @@
  env-exception_is_int, 
  env-error_code, 
  env-exception_next_eip, 0);
+   env-old_exception = -1;  // successful delivered
 #elif defined(TARGET_PPC)
 do_interrupt(env);
 #elif defined(TARGET_MIPS)
Index: target-i386/helper.c
===
RCS file: /sources/qemu/qemu/target-i386/helper.c,v
retrieving revision 1.74
diff -u -r1.74 helper.c
--- target-i386/helper.c1 Feb 2007 22:12:19 -   1.74
+++ target-i386/helper.c31 Mar 2007 11:59:58 -
@@ -1192,6 +1193,37 @@
 }
 }
 
+
+/**
+ * Check nested exceptions and change to double or triple fault if
+ * needed. It should only be called, if this is not an
+ * interrrupt. Returns the new exception number.
+ */
+int check_exception(int intno, int *error_code)
+{
+  if (loglevel  CPU_LOG_INT)
+fprintf(logfile, %s()  old: %x new %x\n,__func__,  env-old_exception, 
intno);
+
+
+ if (env-old_exception == EXCP08_DBLE)
+   cpu_abort(env, triple fault);
+
+ char  first_contributory  = env-old_exception == 0 || (env-old_exception = 
10  env-old_exception = 13);
+ char second_contributory  = intno == 0 || (intno = 10  intno = 13);
+
+ if ((first_contributory  second_contributory) 
+ || (env-old_exception == EXCP0E_PAGE  (second_contributory || (intno 
== EXCP0E_PAGE
+   {
+ intno = EXCP08_DBLE;
+ *error_code = 0;
+   }
+
+ if (second_contributory || (intno == EXCP0E_PAGE) || (intno == EXCP08_DBLE))
+   env-old_exception = intno;
+ return intno;
+}
+
+
 /*
  * Signal an interruption. It is executed in the main CPU loop.
  * is_int is TRUE if coming from the int instruction. next_eip is the
@@ -1201,6 +1233,9 @@
 void raise_interrupt(int intno, int is_int, int error_code, 
  int next_eip_addend)
 {
+if (!is_int)
+intno = check_exception(intno, error_code);
+
 env-exception_index = intno;
 env-error_code = error_code;
 env-exception_is_int = is_int;
@@ -1211,6 +1246,8 @@
 /* same as raise_exception_err, but do not restore global registers */
 static void raise_exception_err_norestore(int exception_index, int error_code)
 {
+exception_index = check_exception(exception_index, error_code);
+
 env-exception_index = exception_index;
 env-error_code = error_code;
 env-exception_is_int = 0;
Index: target-i386/cpu.h
===
RCS file: /sources/qemu/qemu/target-i386/cpu.h,v
retrieving revision 1.41
diff -u -r1.41 cpu.h
--- target-i386/cpu.h   5 Feb 2007 22:06:27 -   1.41
+++ target-i386/cpu.h   31 Mar 2007 11:59:56 -
@@ -515,6 +515,7 @@
 uint32_t smbase;
 int interrupt_request; 
 int user_mode_only; /* user mode only simulation */
+int old_exception;  /* exception in flight */
 
 CPU_COMMON
 


[Qemu-devel] Patch: PIC-i8259 does not work in single mode

2007-03-29 Thread Bernhard Kauer
The PIC-i8259 does not work in single mode, where only the master PIC is used.
The attached patch fixes the initialization part for single mode.

Bernhard Kauer
Index: i8259.c
===
RCS file: /sources/qemu/qemu/hw/i8259.c,v
retrieving revision 1.20
diff -u -r1.20 i8259.c
--- i8259.c 24 Jan 2007 01:47:51 -  1.20
+++ i8259.c 26 Mar 2007 17:01:18 -
@@ -44,6 +44,7 @@
 uint8_t rotate_on_auto_eoi;
 uint8_t special_fully_nested_mode;
 uint8_t init4; /* true if 4 byte init */
+uint8_t single_mode; /* true if slave pic is not initialized */
 uint8_t elcr; /* PIIX edge/trigger selection*/
 uint8_t elcr_mask;
 PicState2 *pics_state;
@@ -278,6 +279,7 @@
 s-rotate_on_auto_eoi = 0;
 s-special_fully_nested_mode = 0;
 s-init4 = 0;
+s-single_mode = 0;
 /* Note: ELCR is not reset */
 }
 
@@ -298,8 +300,7 @@
 s-pics_state-irq_request(s-pics_state-irq_request_opaque, 0);
 s-init_state = 1;
 s-init4 = val  1;
-if (val  0x02)
-hw_error(single mode not supported);
+s-single_mode = val  2;
 if (val  0x08)
 hw_error(level sensitive irq not supported);
 } else if (val  0x08) {
@@ -356,7 +357,7 @@
 break;
 case 1:
 s-irq_base = val  0xf8;
-s-init_state = 2;
+s-init_state = s-single_mode  s-init4 ? 3 : 2;
 break;
 case 2:
 if (s-init4) {
@@ -468,6 +469,7 @@
 qemu_put_8s(f, s-rotate_on_auto_eoi);
 qemu_put_8s(f, s-special_fully_nested_mode);
 qemu_put_8s(f, s-init4);
+qemu_put_8s(f, s-single_mode);
 qemu_put_8s(f, s-elcr);
 }
 
@@ -492,6 +494,7 @@
 qemu_get_8s(f, s-rotate_on_auto_eoi);
 qemu_get_8s(f, s-special_fully_nested_mode);
 qemu_get_8s(f, s-init4);
+qemu_get_8s(f, s-single_mode);
 qemu_get_8s(f, s-elcr);
 return 0;
 }


Re: [Qemu-devel] Patch: generate a DBF when a GPF could not be delivered on x86

2007-03-28 Thread Bernhard Kauer
On Wed, Mar 28, 2007 at 10:13:49AM +0200, Sebastian Kaliszewski wrote:
 Bernhard Kauer wrote:
 Qemu does not generate a double fault (DBF) on x86, if a general protection
 fault could not be delivered. Instead it hangs in a loop.
 
 The patch fix this bug by checking whether we are already in a GPF 
 exception.
 
 If you're at it, maybe add triple fault handling (ie exception if DBF 
 handler) -- it should reset CPU.

There are many things missing in the x86 exception handling. For example
the case PF - PF is also not handled.


Bernhard Kauer




[Qemu-devel] Patch: generate a DBF when a GPF could not be delivered on x86

2007-03-27 Thread Bernhard Kauer
Qemu does not generate a double fault (DBF) on x86, if a general protection
fault could not be delivered. Instead it hangs in a loop.

The patch fix this bug by checking whether we are already in a GPF exception.


Bernhard Kauer
 
Index: helper.c
===
RCS file: /sources/qemu/qemu/target-i386/helper.c,v
retrieving revision 1.74
diff -u -r1.74 helper.c
--- helper.c1 Feb 2007 22:12:19 -   1.74
+++ helper.c27 Mar 2007 11:33:34 -
@@ -592,6 +592,16 @@
 sp += 4;\
 }
 
+void
+raise_gpf(int intno, int is_int, int is_hw, int error)
+{
+  if (!is_int  !is_hw  intno == EXCP0D_GPF)
+raise_exception_err(EXCP08_DBLE, 0);
+  else
+raise_exception_err(EXCP0D_GPF, error = 0 ? error : intno * 
TARGET_LONG_SIZE + 2);
+}
+
+
 /* protected mode interrupt */
 static void do_interrupt_protected(int intno, int is_int, int error_code,
unsigned int next_eip, int is_hw)
@@ -624,7 +634,7 @@
 
 dt = env-idt;
 if (intno * 8 + 7  dt-limit)
-raise_exception_err(EXCP0D_GPF, intno * 8 + 2);
+raise_gpf(intno, is_int, is_hw, -1);
 ptr = dt-base + intno * 8;
 e1 = ldl_kernel(ptr);
 e2 = ldl_kernel(ptr + 4);
@@ -661,29 +671,30 @@
 case 15: /* 386 trap gate */
 break;
 default:
-raise_exception_err(EXCP0D_GPF, intno * 8 + 2);
+raise_gpf(intno, is_int, is_hw, -1);
 break;
 }
 dpl = (e2  DESC_DPL_SHIFT)  3;
 cpl = env-hflags  HF_CPL_MASK;
 /* check privledge if software int */
 if (is_int  dpl  cpl)
-raise_exception_err(EXCP0D_GPF, intno * 8 + 2);
+raise_gpf(intno, is_int, is_hw, -1);
+
 /* check valid bit */
 if (!(e2  DESC_P_MASK))
 raise_exception_err(EXCP0B_NOSEG, intno * 8 + 2);
 selector = e1  16;
 offset = (e2  0x) | (e1  0x);
 if ((selector  0xfffc) == 0)
-raise_exception_err(EXCP0D_GPF, 0);
+raise_gpf(intno, is_int, is_hw, 0);
 
 if (load_segment(e1, e2, selector) != 0)
-raise_exception_err(EXCP0D_GPF, selector  0xfffc);
+raise_gpf(intno, is_int, is_hw, selector  0xfffc);
 if (!(e2  DESC_S_MASK) || !(e2  (DESC_CS_MASK)))
-raise_exception_err(EXCP0D_GPF, selector  0xfffc);
+raise_gpf(intno, is_int, is_hw, selector  0xfffc);
 dpl = (e2  DESC_DPL_SHIFT)  3;
 if (dpl  cpl)
-raise_exception_err(EXCP0D_GPF, selector  0xfffc);
+raise_gpf(intno, is_int, is_hw, selector  0xfffc);
 if (!(e2  DESC_P_MASK))
 raise_exception_err(EXCP0B_NOSEG, selector  0xfffc);
 if (!(e2  DESC_C_MASK)  dpl  cpl) {
@@ -710,14 +721,14 @@
 } else if ((e2  DESC_C_MASK) || dpl == cpl) {
 /* to same priviledge */
 if (env-eflags  VM_MASK)
-raise_exception_err(EXCP0D_GPF, selector  0xfffc);
+   raise_gpf(intno, is_int, is_hw, selector  0xfffc);
 new_stack = 0;
 sp_mask = get_sp_mask(env-segs[R_SS].flags);
 ssp = env-segs[R_SS].base;
 esp = ESP;
 dpl = cpl;
 } else {
-raise_exception_err(EXCP0D_GPF, selector  0xfffc);
+raise_gpf(intno, is_int, is_hw, selector  0xfffc);
 new_stack = 0; /* avoid warning */
 sp_mask = 0; /* avoid warning */
 ssp = 0; /* avoid warning */
@@ -860,7 +871,7 @@
 
 dt = env-idt;
 if (intno * 16 + 15  dt-limit)
-raise_exception_err(EXCP0D_GPF, intno * 16 + 2);
+raise_gpf(intno, is_int, is_hw, -1);
 ptr = dt-base + intno * 16;
 e1 = ldl_kernel(ptr);
 e2 = ldl_kernel(ptr + 4);
@@ -872,14 +883,13 @@
 case 15: /* 386 trap gate */
 break;
 default:
-raise_exception_err(EXCP0D_GPF, intno * 16 + 2);
-break;
+raise_gpf(intno, is_int, is_hw, -1);
 }
 dpl = (e2  DESC_DPL_SHIFT)  3;
 cpl = env-hflags  HF_CPL_MASK;
 /* check privledge if software int */
 if (is_int  dpl  cpl)
-raise_exception_err(EXCP0D_GPF, intno * 16 + 2);
+raise_gpf(intno, is_int, is_hw, -1);
 /* check valid bit */
 if (!(e2  DESC_P_MASK))
 raise_exception_err(EXCP0B_NOSEG, intno * 16 + 2);
@@ -887,19 +897,19 @@
 offset = ((target_ulong)e3  32) | (e2  0x) | (e1  0x);
 ist = e2  7;
 if ((selector  0xfffc) == 0)
-raise_exception_err(EXCP0D_GPF, 0);
+raise_gpf(intno, is_int, is_hw, 0);
 
 if (load_segment(e1, e2, selector) != 0)
-raise_exception_err(EXCP0D_GPF, selector  0xfffc);
+raise_gpf(intno, is_int, is_hw, selector  0xfffc);
 if (!(e2  DESC_S_MASK) || !(e2  (DESC_CS_MASK)))
-raise_exception_err(EXCP0D_GPF, selector  0xfffc);
+raise_gpf(intno, is_int, is_hw, selector  0xfffc);
 dpl = (e2  DESC_DPL_SHIFT)  3;
 if (dpl  cpl)
-raise_exception_err(EXCP0D_GPF, selector  0xfffc);
+raise_gpf(intno, is_int, is_hw, selector  0xfffc);
 if (!(e2  DESC_P_MASK

[Qemu-devel] Patch: ltr for x86_64 should check the upper descriptor type

2007-03-26 Thread Bernhard Kauer
The Intel manual states for LTR and 64-Bit Exceptions:

#GP(selector)
   If the descriptor type of the upper 8-byte of the 16-byte descriptor
   is non-zero.

Qemu currently does not check this. The attached patch fixes the bug.


Bernhard Kauer
--- helper.c.orig   2007-03-26 15:39:11.0 +0200
+++ helper.c2007-03-26 15:40:27.0 +0200
@@ -1825,8 +1825,11 @@
 raise_exception_err(EXCP0B_NOSEG, selector  0xfffc);
 #ifdef TARGET_X86_64
 if (env-hflags  HF_LMA_MASK) {
-uint32_t e3;
+uint32_t e3, e4;
 e3 = ldl_kernel(ptr + 8);
+   e4 = ldl_kernel(ptr + 12);
+   if ((e4  DESC_TYPE_SHIFT)  0xf)
+   raise_exception_err(EXCP0D_GPF, selector  0xfffc);
 load_seg_cache_raw_dt(env-tr, e1, e2);
 env-tr.base |= (target_ulong)e3  32;
 } else 


Re: [Qemu-devel] Patch: ltr for x86_64 should check the upper descriptor type

2007-03-26 Thread Bernhard Kauer
On Mon, Mar 26, 2007 at 01:54:43PM +, Julian Seward wrote:
 
 Does this fix some specific bug you encountered?

I have some code here that runs on Qemu but not on real hardware
due to this missing check.


Bernhard


 On Monday 26 March 2007 14:53, Bernhard Kauer wrote:
  The Intel manual states for LTR and 64-Bit Exceptions:
 
  #GP(selector)
 If the descriptor type of the upper 8-byte of the 16-byte descriptor
 is non-zero.
 
  Qemu currently does not check this. The attached patch fixes the bug.




[Qemu-devel] [PATCH] TPM TIS device model

2007-03-25 Thread Bernhard Kauer
This patch adds a TIS device model for a v1.2 TPM to qemu.
It is based on the Xen patch from IBM and adopted by removing
the Xen-specific stuff. It works with the tpmd daemon of the
tpm-emulator package.

The following things are still missing:

* locality support
* cmdline option for the socket name


Greetings,

Bernhard Kauer
diff -N -r -u qemu.old/Makefile.target qemu/Makefile.target
--- qemu.old/Makefile.target2007-03-09 02:46:14.024009410 +0100
+++ qemu/Makefile.target2007-03-09 01:03:53.0 +0100
@@ -372,6 +372,7 @@
 VL_OBJS+= fdc.o mc146818rtc.o serial.o i8259.o i8254.o pcspk.o pc.o
 VL_OBJS+= cirrus_vga.o mixeng.o apic.o parallel.o acpi.o piix_pci.o
 VL_OBJS+= usb-uhci.o smbus_eeprom.o
+VL_OBJS+= tpm_tis.o
 CPPFLAGS += -DHAS_AUDIO
 endif
 ifeq ($(TARGET_BASE_ARCH), ppc)
diff -N -r -u qemu.old/hw/pc.c qemu/hw/pc.c
--- qemu.old/hw/pc.c2007-03-09 02:46:14.424026396 +0100
+++ qemu/hw/pc.c2007-03-09 01:14:26.507262699 +0100
@@ -734,6 +734,9 @@
 if (i440fx_state) {
 i440fx_init_memory_mappings(i440fx_state);
 }
+
+tpm_tis_init();
+
 #if 0
 /* ??? Need to figure out some way for the user to
specify SCSI devices.  */
diff -N -r -u qemu.old/hw/tpm_tis.c qemu/hw/tpm_tis.c
--- qemu.old/hw/tpm_tis.c   1970-01-01 01:00:00.0 +0100
+++ qemu/hw/tpm_tis.c   2007-03-09 02:59:13.801196995 +0100
@@ -0,0 +1,992 @@
+/*
+ * tpm_tis.c - QEMU emulator for a 1.2 TPM with TIS interface
+ *
+ * Copyright (C) 2006 IBM Corporation
+ *
+ * Author: Stefan Berger [EMAIL PROTECTED]
+ * David Safford [EMAIL PROTECTED]
+ * Adopted for Qemu: Bernhard Kauer [EMAIL PROTECTED]
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ *
+ * Implementation of the TIS interface according to specs at
+ * 
https://www.trustedcomputinggroup.org/groups/pc_client/TCG_PCClientTPMSpecification_1-20_1-00_FINAL.pdf
+ *
+ */
+
+#include sys/types.h
+#include sys/stat.h
+#include sys/socket.h
+#include sys/un.h
+#include fcntl.h
+#include errno.h
+#include vl.h
+
+#define DEBUG_TPM
+#define logfile stderr
+
+#define TPM_MAX_PKT  4096
+
+#define VTPM_BAD_INSTANCE (uint32_t)0x
+
+#define TIS_ADDR_BASE 0xFED4
+
+/* tis registers */
+#define TPM_REG_ACCESS0x00
+#define TPM_REG_INT_ENABLE0x08
+#define TPM_REG_INT_VECTOR0x0c
+#define TPM_REG_INT_STATUS0x10
+#define TPM_REG_INTF_CAPABILITY   0x14
+#define TPM_REG_STS   0x18
+#define TPM_REG_DATA_FIFO 0x24
+#define TPM_REG_DID_VID   0xf00
+#define TPM_REG_RID   0xf04
+
+#define STS_VALID(1  7)
+#define STS_COMMAND_READY(1  6)
+#define STS_TPM_GO   (1  5)
+#define STS_DATA_AVAILABLE   (1  4)
+#define STS_EXPECT   (1  3)
+#define STS_RESPONSE_RETRY   (1  1)
+
+#define ACCESS_TPM_REG_VALID_STS (1  7)
+#define ACCESS_ACTIVE_LOCALITY   (1  5)
+#define ACCESS_BEEN_SEIZED   (1  4)
+#define ACCESS_SEIZE (1  3)
+#define ACCESS_PENDING_REQUEST   (1  2)
+#define ACCESS_REQUEST_USE   (1  1)
+#define ACCESS_TPM_ESTABLISHMENT (1  0)
+
+#define INT_ENABLED  (1  31)
+#define INT_DATA_AVAILABLE   (1  0)
+#define INT_LOCALITY_CHANGED (1  2)
+#define INT_COMMAND_READY(1  7)
+
+#define INTERRUPTS_SUPPORTED (INT_LOCALITY_CHANGED | \
+  INT_DATA_AVAILABLE   | \
+  INT_COMMAND_READY)
+#define CAPABILITIES_SUPPORTED   ((1  4) |\
+  INTERRUPTS_SUPPORTED)
+
+enum {
+  STATE_IDLE = 0,
+  STATE_READY,
+  STATE_COMPLETION,
+  STATE_EXECUTION,
+  STATE_RECEPTION
+};
+
+#define NUM_LOCALITIES   5
+#define NO_LOCALITY  0xff
+
+#define IS_VALID_LOC(x) ((x)  NUM_LOCALITIES)
+
+#define TPM_DID  0x0001
+#define TPM_VID  0x0001
+#define TPM_RID  0x0001
+
+/* if the connection to the vTPM should be closed after a successfully
+   received response; set to '0' to allow keeping the connection */
+#define FORCE_CLOSE  0
+
+/* local data structures */
+
+typedef struct TPMTx {
+int fd[2];
+} tpmTx;
+
+typedef struct TPMBuffer {
+uint8_t instance[4];  /* instance number in network byte order */
+uint8_t buf[TPM_MAX_PKT];
+} __attribute__((packed)) tpmBuffer;
+
+/* locality data */
+typedef struct TPMLocal {
+uint32_t state;
+uint8_t access;
+uint8_t sts;
+uint32_t inte;
+uint32_t ints;
+} tpmLoc;
+
+/* overall state of the TPM interface; 's' marks as save upon suspension */
+typedef struct TPMState {
+uint32_t offset;/* s */
+tpmBuffer buffer

[Qemu-devel] [PATCH] i386 return APIC ID with cpuid

2007-03-20 Thread Bernhard Kauer
Hi,

cpuid(01H) on i386 does not return the initial APIC id.
The following patch correct this.


Bernhard Kauer
Index: hw/apic.c
===
RCS file: /sources/qemu/qemu/hw/apic.c,v
retrieving revision 1.12
diff -u -r1.12 apic.c
--- hw/apic.c   31 Jan 2007 12:22:18 -  1.12
+++ hw/apic.c   20 Mar 2007 22:13:09 -
@@ -816,6 +816,7 @@
 env-apic_state = s;
 apic_init_ipi(s);
 s-id = last_apic_id++;
+env-cpuid_apic_id = s-id;
 s-cpu_env = env;
 s-apicbase = 0xfee0 | 
 (s-id ? 0 : MSR_IA32_APICBASE_BSP) | MSR_IA32_APICBASE_ENABLE;
Index: target-i386/cpu.h
===
RCS file: /sources/qemu/qemu/target-i386/cpu.h,v
retrieving revision 1.41
diff -u -r1.41 cpu.h
--- target-i386/cpu.h   5 Feb 2007 22:06:27 -   1.41
+++ target-i386/cpu.h   20 Mar 2007 22:13:09 -
@@ -529,6 +529,7 @@
 uint32_t cpuid_xlevel;
 uint32_t cpuid_model[12];
 uint32_t cpuid_ext2_features;
+uint32_t cpuid_apic_id;
 
 #ifdef USE_KQEMU
 int kqemu_enabled;
Index: target-i386/helper.c
===
RCS file: /sources/qemu/qemu/target-i386/helper.c,v
retrieving revision 1.74
diff -u -r1.74 helper.c
--- target-i386/helper.c1 Feb 2007 22:12:19 -   1.74
+++ target-i386/helper.c20 Mar 2007 22:13:10 -
@@ -1614,7 +1614,7 @@
 break;
 case 1:
 EAX = env-cpuid_version;
-EBX = 8  8; /* CLFLUSH size in quad words, Linux wants it. */
+EBX = (env-cpuid_apic_id  24) | 8  8; /* CLFLUSH size in quad 
words, Linux wants it. */
 ECX = env-cpuid_ext_features;
 EDX = env-cpuid_features;
 break;
___
Qemu-devel mailing list
Qemu-devel@nongnu.org
http://lists.nongnu.org/mailman/listinfo/qemu-devel


[Qemu-devel] [PATCH] TPM TIS device model

2007-03-12 Thread Bernhard Kauer
This patch adds a TIS device model for a v1.2 TPM to qemu.
It is based on the Xen patch from IBM and adopted by removing
the Xen-specific stuff. It works with the tpmd daemon of the
tpm-emulator package.

The following things are still missing:

* locality support
* cmdline option for the socket name


Greetings,

Bernhard Kauer
diff -N -r -u qemu.old/Makefile.target qemu/Makefile.target
--- qemu.old/Makefile.target2007-03-09 02:46:14.024009410 +0100
+++ qemu/Makefile.target2007-03-09 01:03:53.0 +0100
@@ -372,6 +372,7 @@
 VL_OBJS+= fdc.o mc146818rtc.o serial.o i8259.o i8254.o pcspk.o pc.o
 VL_OBJS+= cirrus_vga.o mixeng.o apic.o parallel.o acpi.o piix_pci.o
 VL_OBJS+= usb-uhci.o smbus_eeprom.o
+VL_OBJS+= tpm_tis.o
 CPPFLAGS += -DHAS_AUDIO
 endif
 ifeq ($(TARGET_BASE_ARCH), ppc)
diff -N -r -u qemu.old/hw/pc.c qemu/hw/pc.c
--- qemu.old/hw/pc.c2007-03-09 02:46:14.424026396 +0100
+++ qemu/hw/pc.c2007-03-09 01:14:26.507262699 +0100
@@ -734,6 +734,9 @@
 if (i440fx_state) {
 i440fx_init_memory_mappings(i440fx_state);
 }
+
+tpm_tis_init();
+
 #if 0
 /* ??? Need to figure out some way for the user to
specify SCSI devices.  */
diff -N -r -u qemu.old/hw/tpm_tis.c qemu/hw/tpm_tis.c
--- qemu.old/hw/tpm_tis.c   1970-01-01 01:00:00.0 +0100
+++ qemu/hw/tpm_tis.c   2007-03-09 02:59:13.801196995 +0100
@@ -0,0 +1,992 @@
+/*
+ * tpm_tis.c - QEMU emulator for a 1.2 TPM with TIS interface
+ *
+ * Copyright (C) 2006 IBM Corporation
+ *
+ * Author: Stefan Berger [EMAIL PROTECTED]
+ * David Safford [EMAIL PROTECTED]
+ * Adopted for Qemu: Bernhard Kauer [EMAIL PROTECTED]
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ *
+ * Implementation of the TIS interface according to specs at
+ * 
https://www.trustedcomputinggroup.org/groups/pc_client/TCG_PCClientTPMSpecification_1-20_1-00_FINAL.pdf
+ *
+ */
+
+#include sys/types.h
+#include sys/stat.h
+#include sys/socket.h
+#include sys/un.h
+#include fcntl.h
+#include errno.h
+#include vl.h
+
+#define DEBUG_TPM
+#define logfile stderr
+
+#define TPM_MAX_PKT  4096
+
+#define VTPM_BAD_INSTANCE (uint32_t)0x
+
+#define TIS_ADDR_BASE 0xFED4
+
+/* tis registers */
+#define TPM_REG_ACCESS0x00
+#define TPM_REG_INT_ENABLE0x08
+#define TPM_REG_INT_VECTOR0x0c
+#define TPM_REG_INT_STATUS0x10
+#define TPM_REG_INTF_CAPABILITY   0x14
+#define TPM_REG_STS   0x18
+#define TPM_REG_DATA_FIFO 0x24
+#define TPM_REG_DID_VID   0xf00
+#define TPM_REG_RID   0xf04
+
+#define STS_VALID(1  7)
+#define STS_COMMAND_READY(1  6)
+#define STS_TPM_GO   (1  5)
+#define STS_DATA_AVAILABLE   (1  4)
+#define STS_EXPECT   (1  3)
+#define STS_RESPONSE_RETRY   (1  1)
+
+#define ACCESS_TPM_REG_VALID_STS (1  7)
+#define ACCESS_ACTIVE_LOCALITY   (1  5)
+#define ACCESS_BEEN_SEIZED   (1  4)
+#define ACCESS_SEIZE (1  3)
+#define ACCESS_PENDING_REQUEST   (1  2)
+#define ACCESS_REQUEST_USE   (1  1)
+#define ACCESS_TPM_ESTABLISHMENT (1  0)
+
+#define INT_ENABLED  (1  31)
+#define INT_DATA_AVAILABLE   (1  0)
+#define INT_LOCALITY_CHANGED (1  2)
+#define INT_COMMAND_READY(1  7)
+
+#define INTERRUPTS_SUPPORTED (INT_LOCALITY_CHANGED | \
+  INT_DATA_AVAILABLE   | \
+  INT_COMMAND_READY)
+#define CAPABILITIES_SUPPORTED   ((1  4) |\
+  INTERRUPTS_SUPPORTED)
+
+enum {
+  STATE_IDLE = 0,
+  STATE_READY,
+  STATE_COMPLETION,
+  STATE_EXECUTION,
+  STATE_RECEPTION
+};
+
+#define NUM_LOCALITIES   5
+#define NO_LOCALITY  0xff
+
+#define IS_VALID_LOC(x) ((x)  NUM_LOCALITIES)
+
+#define TPM_DID  0x0001
+#define TPM_VID  0x0001
+#define TPM_RID  0x0001
+
+/* if the connection to the vTPM should be closed after a successfully
+   received response; set to '0' to allow keeping the connection */
+#define FORCE_CLOSE  0
+
+/* local data structures */
+
+typedef struct TPMTx {
+int fd[2];
+} tpmTx;
+
+typedef struct TPMBuffer {
+uint8_t instance[4];  /* instance number in network byte order */
+uint8_t buf[TPM_MAX_PKT];
+} __attribute__((packed)) tpmBuffer;
+
+/* locality data */
+typedef struct TPMLocal {
+uint32_t state;
+uint8_t access;
+uint8_t sts;
+uint32_t inte;
+uint32_t ints;
+} tpmLoc;
+
+/* overall state of the TPM interface; 's' marks as save upon suspension */
+typedef struct TPMState {
+uint32_t offset;/* s */
+tpmBuffer buffer