Re: KVM: x86: ignore access permissions for hypercall patching

2010-03-11 Thread Stefan Bader
With this patch applied on top, I was able to boot my guest on a AMD host 
system.

Marcelo Tosatti wrote:
 Ignore access permissions while patching hypercall instructions. 
 Otherwise KVM injects a page fault when trying to patch vmcall 
 on read-only text regions:
 
 Freeing initrd memory: 8843k freed
 Freeing unused kernel memory: 660k freed
 Write protecting the kernel text: 4780k
 Write protecting the kernel read-only data: 1912k
 BUG: unable to handle kernel paging request at c01292e3
 IP: [c01292e3] kvm_leave_lazy_mmu+0x43/0x70
 *pde = 00910067 *pte = 00129161
 Oops: 0003 [#1] SMP
 
 CC: sta...@kernel.org
 Reported-by: Stefan Bader stefan.ba...@canonical.com
 Signed-off-by: Marcelo Tosatti mtosa...@redhat.com
Tested-by: Stefan Bader stefan.ba...@canonical.com
 
 diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
 index 703f637..bf5c83f 100644
 --- a/arch/x86/kvm/x86.c
 +++ b/arch/x86/kvm/x86.c
 @@ -3253,12 +3253,17 @@ int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t 
 gpa,
  static int emulator_write_emulated_onepage(unsigned long addr,
  const void *val,
  unsigned int bytes,
 -struct kvm_vcpu *vcpu)
 +struct kvm_vcpu *vcpu,
 +bool guest_initiated)
  {
   gpa_t gpa;
   u32 error_code;
  
 - gpa = kvm_mmu_gva_to_gpa_write(vcpu, addr, error_code);
 +
 + if (guest_initiated)
 + gpa = kvm_mmu_gva_to_gpa_write(vcpu, addr, error_code);
 + else
 + gpa = kvm_mmu_gva_to_gpa_system(vcpu, addr, error_code);
  
   if (gpa == UNMAPPED_GVA) {
   kvm_inject_page_fault(vcpu, addr, error_code);
 @@ -3289,24 +3294,35 @@ mmio:
   return X86EMUL_CONTINUE;
  }
  
 -int emulator_write_emulated(unsigned long addr,
 +int __emulator_write_emulated(unsigned long addr,
  const void *val,
  unsigned int bytes,
 -struct kvm_vcpu *vcpu)
 +struct kvm_vcpu *vcpu,
 +bool guest_initiated)
  {
   /* Crossing a page boundary? */
   if (((addr + bytes - 1) ^ addr)  PAGE_MASK) {
   int rc, now;
  
   now = -addr  ~PAGE_MASK;
 - rc = emulator_write_emulated_onepage(addr, val, now, vcpu);
 + rc = emulator_write_emulated_onepage(addr, val, now, vcpu,
 +  guest_initiated);
   if (rc != X86EMUL_CONTINUE)
   return rc;
   addr += now;
   val += now;
   bytes -= now;
   }
 - return emulator_write_emulated_onepage(addr, val, bytes, vcpu);
 + return emulator_write_emulated_onepage(addr, val, bytes, vcpu,
 +guest_initiated);
 +}
 +
 +int emulator_write_emulated(unsigned long addr,
 +const void *val,
 +unsigned int bytes,
 +struct kvm_vcpu *vcpu)
 +{
 + return __emulator_write_emulated(addr, val, bytes, vcpu, true);
  }
  EXPORT_SYMBOL_GPL(emulator_write_emulated);
  
 @@ -3997,7 +4013,7 @@ int kvm_fix_hypercall(struct kvm_vcpu *vcpu)
  
   kvm_x86_ops-patch_hypercall(vcpu, instruction);
  
 - return emulator_write_emulated(rip, instruction, 3, vcpu);
 + return __emulator_write_emulated(rip, instruction, 3, vcpu, false);
  }
  
  static u64 mk_cr_64(u64 curr_cr, u32 new_val)

--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: KVM: x86: ignore access permissions for hypercall patching

2010-03-11 Thread Gleb Natapov
On Thu, Mar 11, 2010 at 06:16:05PM -0300, Marcelo Tosatti wrote:
 
 Ignore access permissions while patching hypercall instructions. 
 Otherwise KVM injects a page fault when trying to patch vmcall 
 on read-only text regions:
 
 Freeing initrd memory: 8843k freed
 Freeing unused kernel memory: 660k freed
 Write protecting the kernel text: 4780k
 Write protecting the kernel read-only data: 1912k
 BUG: unable to handle kernel paging request at c01292e3
 IP: [c01292e3] kvm_leave_lazy_mmu+0x43/0x70
 *pde = 00910067 *pte = 00129161
 Oops: 0003 [#1] SMP
 
 CC: sta...@kernel.org
 Reported-by: Stefan Bader stefan.ba...@canonical.com
 Signed-off-by: Marcelo Tosatti mtosa...@redhat.com
 
My emulator patch series introduce kvm_write_guest_virt_system(). May be
used it here (only compile tested).


diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 3753c11..9833c25 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -3157,14 +3157,18 @@ static int kvm_read_guest_virt_system(gva_t addr, void 
*val, unsigned int bytes,
return kvm_read_guest_virt_helper(addr, val, bytes, vcpu, 0, error);
 }
 
-static int kvm_write_guest_virt(gva_t addr, void *val, unsigned int bytes,
-   struct kvm_vcpu *vcpu, u32 *error)
+static int kvm_write_guest_virt_helper(gva_t addr, void *val,
+  unsigned int bytes,
+  struct kvm_vcpu *vcpu, u32 access,
+  u32 *error)
 {
void *data = val;
int r = X86EMUL_CONTINUE;
 
+   access |= PFERR_WRITE_MASK;
+
while (bytes) {
-   gpa_t gpa = kvm_mmu_gva_to_gpa_write(vcpu, addr, error);
+   gpa_t gpa =  vcpu-arch.mmu.gva_to_gpa(vcpu, addr, access, 
error);
unsigned offset = addr  (PAGE_SIZE-1);
unsigned towrite = min(bytes, (unsigned)PAGE_SIZE - offset);
int ret;
@@ -3187,6 +3191,19 @@ out:
return r;
 }
 
+static int kvm_write_guest_virt(gva_t addr, void *val, unsigned int bytes,
+   struct kvm_vcpu *vcpu, u32 *error)
+{
+   u32 access = (kvm_x86_ops-get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0;
+   return kvm_write_guest_virt_helper(addr, val, bytes, vcpu, access, 
error);
+}
+
+static int kvm_write_guest_virt_system(gva_t addr, void *val,
+  unsigned int bytes,
+  struct kvm_vcpu *vcpu, u32 *error)
+{
+   return kvm_write_guest_virt_helper(addr, val, bytes, vcpu, 0, error);
+}
 
 static int emulator_read_emulated(unsigned long addr,
  void *val,
@@ -3997,7 +4014,7 @@ int kvm_fix_hypercall(struct kvm_vcpu *vcpu)
 
kvm_x86_ops-patch_hypercall(vcpu, instruction);
 
-   return emulator_write_emulated(rip, instruction, 3, vcpu);
+   return kvm_write_guest_virt_system(rip, instruction, 3, vcpu, NULL);
 }
 
 static u64 mk_cr_64(u64 curr_cr, u32 new_val)
--
Gleb.
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: KVM: x86: ignore access permissions for hypercall patching

2010-03-11 Thread Gleb Natapov
On Fri, Mar 12, 2010 at 07:56:00AM +0200, Gleb Natapov wrote:
 On Thu, Mar 11, 2010 at 06:16:05PM -0300, Marcelo Tosatti wrote:
  
  Ignore access permissions while patching hypercall instructions. 
  Otherwise KVM injects a page fault when trying to patch vmcall 
  on read-only text regions:
  
  Freeing initrd memory: 8843k freed
  Freeing unused kernel memory: 660k freed
  Write protecting the kernel text: 4780k
  Write protecting the kernel read-only data: 1912k
  BUG: unable to handle kernel paging request at c01292e3
  IP: [c01292e3] kvm_leave_lazy_mmu+0x43/0x70
  *pde = 00910067 *pte = 00129161
  Oops: 0003 [#1] SMP
  
  CC: sta...@kernel.org
  Reported-by: Stefan Bader stefan.ba...@canonical.com
  Signed-off-by: Marcelo Tosatti mtosa...@redhat.com
  
 My emulator patch series introduce kvm_write_guest_virt_system(). May be
 used it here (only compile tested).
 
Ignore that, it will not work.

--
Gleb.
--
To unsubscribe from this list: send the line unsubscribe kvm in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html