Re: [PATCH 3/3] KVM: PPC: Book3S HV: Implement H_CLEAR_REF and H_CLEAR_MOD

2015-09-12 Thread Nathan Whitehorn

On 09/06/15 16:52, Paul Mackerras wrote:

On Sun, Sep 06, 2015 at 12:47:12PM -0700, Nathan Whitehorn wrote:

Anything I can do to help move these along? It's a big performance
improvement for FreeBSD guests.

These patches are in Paolo's kvm-ppc-next branch and should go into
Linus' tree in the next couple of days.

Paul.



One additional question. What is your preferred way to enable these? 
Since these are part of the mandatory part of the PAPR spec, I think 
there's an argument to add them to the default_hcall_list? Otherwise, 
they should be enabled by default in QEMU (I can take care of sending 
that patch if you prefer this route).

-Nathan

--
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: [PATCH 3/3] KVM: PPC: Book3S HV: Implement H_CLEAR_REF and H_CLEAR_MOD

2015-09-12 Thread Nathan Whitehorn

On 09/06/15 16:52, Paul Mackerras wrote:

On Sun, Sep 06, 2015 at 12:47:12PM -0700, Nathan Whitehorn wrote:

Anything I can do to help move these along? It's a big performance
improvement for FreeBSD guests.

These patches are in Paolo's kvm-ppc-next branch and should go into
Linus' tree in the next couple of days.

Paul.



One additional question. What is your preferred way to enable these? 
Since these are part of the mandatory part of the PAPR spec, I think 
there's an argument to add them to the default_hcall_list? Otherwise, 
they should be enabled by default in QEMU (I can take care of sending 
that patch if you prefer this route).

-Nathan

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


Re: [PATCH 3/3] KVM: PPC: Book3S HV: Implement H_CLEAR_REF and H_CLEAR_MOD

2015-09-06 Thread Nathan Whitehorn

Fantastic, thanks!
-Nathan

On 09/06/15 16:52, Paul Mackerras wrote:

On Sun, Sep 06, 2015 at 12:47:12PM -0700, Nathan Whitehorn wrote:

Anything I can do to help move these along? It's a big performance
improvement for FreeBSD guests.

These patches are in Paolo's kvm-ppc-next branch and should go into
Linus' tree in the next couple of days.

Paul.



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


Re: [PATCH 3/3] KVM: PPC: Book3S HV: Implement H_CLEAR_REF and H_CLEAR_MOD

2015-09-06 Thread Nathan Whitehorn

Fantastic, thanks!
-Nathan

On 09/06/15 16:52, Paul Mackerras wrote:

On Sun, Sep 06, 2015 at 12:47:12PM -0700, Nathan Whitehorn wrote:

Anything I can do to help move these along? It's a big performance
improvement for FreeBSD guests.

These patches are in Paolo's kvm-ppc-next branch and should go into
Linus' tree in the next couple of days.

Paul.



--
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: [PATCH 3/3] KVM: PPC: Book3S HV: Implement H_CLEAR_REF and H_CLEAR_MOD

2015-09-06 Thread Nathan Whitehorn
Anything I can do to help move these along? It's a big performance 
improvement for FreeBSD guests.

-Nathan

On 07/27/15 10:31, Nathan Whitehorn wrote:
I've been running with these patches and a FreeBSD guest for a while 
now and they work very well, providing big performance improvements in 
tight memory situations. Thanks! I did have to patch QEMU to enable 
the hypercalls, however -- it might be worth adding them to the 
default set since these calls are mandated by PAPR as part of the base 
hypercall interface.

-Nathan

On 04/23/15 22:39, Paul Mackerras wrote:

This adds implementations for the H_CLEAR_REF (test and clear reference
bit) and H_CLEAR_MOD (test and clear changed bit) hypercalls.

When clearing the reference or change bit in the guest view of the HPTE,
we also have to clear it in the real HPTE so that we can detect future
references or changes.  When we do so, we transfer the R or C bit value
to the rmap entry for the underlying host page so that kvm_age_hva_hv(),
kvm_test_age_hva_hv() and kvmppc_hv_get_dirty_log() know that the page
has been referenced and/or changed.

These hypercalls are not used by Linux guests and these implementations
are only compile tested.

Signed-off-by: Paul Mackerras <pau...@samba.org>
---
  arch/powerpc/kvm/book3s_hv_rm_mmu.c | 126 
++--

  arch/powerpc/kvm/book3s_hv_rmhandlers.S |   4 +-
  2 files changed, 121 insertions(+), 9 deletions(-)

diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c 
b/arch/powerpc/kvm/book3s_hv_rm_mmu.c

index 24ccc79..479ff7e 100644
--- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c
+++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
@@ -109,25 +109,38 @@ void kvmppc_update_rmap_change(unsigned long 
*rmap, unsigned long psize)

  }
  EXPORT_SYMBOL_GPL(kvmppc_update_rmap_change);
  +/* Returns a pointer to the revmap entry for the page mapped by a 
HPTE */
+static unsigned long *revmap_for_hpte(struct kvm *kvm, unsigned long 
hpte_v,

+  unsigned long hpte_gr)
+{
+struct kvm_memory_slot *memslot;
+unsigned long *rmap;
+unsigned long gfn;
+
+gfn = hpte_rpn(hpte_gr, hpte_page_size(hpte_v, hpte_gr));
+memslot = __gfn_to_memslot(kvm_memslots_raw(kvm), gfn);
+if (!memslot)
+return NULL;
+
+rmap = real_vmalloc_addr(>arch.rmap[gfn - 
memslot->base_gfn]);

+return rmap;
+}
+
  /* Remove this HPTE from the chain for a real page */
  static void remove_revmap_chain(struct kvm *kvm, long pte_index,
  struct revmap_entry *rev,
  unsigned long hpte_v, unsigned long hpte_r)
  {
  struct revmap_entry *next, *prev;
-unsigned long gfn, ptel, head;
-struct kvm_memory_slot *memslot;
+unsigned long ptel, head;
  unsigned long *rmap;
  unsigned long rcbits;
rcbits = hpte_r & (HPTE_R_R | HPTE_R_C);
  ptel = rev->guest_rpte |= rcbits;
-gfn = hpte_rpn(ptel, hpte_page_size(hpte_v, ptel));
-memslot = __gfn_to_memslot(kvm_memslots_raw(kvm), gfn);
-if (!memslot)
+rmap = revmap_for_hpte(kvm, hpte_v, ptel);
+if (!rmap)
  return;
-
-rmap = real_vmalloc_addr(>arch.rmap[gfn - 
memslot->base_gfn]);

  lock_rmap(rmap);
head = *rmap & KVMPPC_RMAP_INDEX;
@@ -662,6 +675,105 @@ long kvmppc_h_read(struct kvm_vcpu *vcpu, 
unsigned long flags,

  return H_SUCCESS;
  }
  +long kvmppc_h_clear_ref(struct kvm_vcpu *vcpu, unsigned long flags,
+unsigned long pte_index)
+{
+struct kvm *kvm = vcpu->kvm;
+__be64 *hpte;
+unsigned long v, r, gr;
+struct revmap_entry *rev;
+unsigned long *rmap;
+long ret = H_NOT_FOUND;
+
+if (pte_index >= kvm->arch.hpt_npte)
+return H_PARAMETER;
+
+rev = real_vmalloc_addr(>arch.revmap[pte_index]);
+hpte = (__be64 *)(kvm->arch.hpt_virt + (pte_index << 4));
+while (!try_lock_hpte(hpte, HPTE_V_HVLOCK))
+cpu_relax();
+v = be64_to_cpu(hpte[0]);
+r = be64_to_cpu(hpte[1]);
+if (!(v & (HPTE_V_VALID | HPTE_V_ABSENT)))
+goto out;
+
+gr = rev->guest_rpte;
+if (rev->guest_rpte & HPTE_R_R) {
+rev->guest_rpte &= ~HPTE_R_R;
+note_hpte_modification(kvm, rev);
+}
+if (v & HPTE_V_VALID) {
+gr |= r & (HPTE_R_R | HPTE_R_C);
+if (r & HPTE_R_R) {
+kvmppc_clear_ref_hpte(kvm, hpte, pte_index);
+rmap = revmap_for_hpte(kvm, v, gr);
+if (rmap) {
+lock_rmap(rmap);
+*rmap |= KVMPPC_RMAP_REFERENCED;
+unlock_rmap(rmap);
+}
+}
+}
+vcpu->arch.gpr[4] = gr;
+ret = H_SUCCESS;
+ out:
+unlock_hpte(hpte, v & ~HPTE_V_HVLOCK);
+return ret;
+}
+
+long kvmppc_h_clear_mod(struct kvm_vcpu *vcpu, unsigned long flags,
+unsigned long pte_index)
+{
+struct kvm *kvm = vcpu->kvm;
+__be64 *hpte;
+unsigned long v, r, gr;
+struct revmap_e

Re: [PATCH 3/3] KVM: PPC: Book3S HV: Implement H_CLEAR_REF and H_CLEAR_MOD

2015-09-06 Thread Nathan Whitehorn
Anything I can do to help move these along? It's a big performance 
improvement for FreeBSD guests.

-Nathan

On 07/27/15 10:31, Nathan Whitehorn wrote:
I've been running with these patches and a FreeBSD guest for a while 
now and they work very well, providing big performance improvements in 
tight memory situations. Thanks! I did have to patch QEMU to enable 
the hypercalls, however -- it might be worth adding them to the 
default set since these calls are mandated by PAPR as part of the base 
hypercall interface.

-Nathan

On 04/23/15 22:39, Paul Mackerras wrote:

This adds implementations for the H_CLEAR_REF (test and clear reference
bit) and H_CLEAR_MOD (test and clear changed bit) hypercalls.

When clearing the reference or change bit in the guest view of the HPTE,
we also have to clear it in the real HPTE so that we can detect future
references or changes.  When we do so, we transfer the R or C bit value
to the rmap entry for the underlying host page so that kvm_age_hva_hv(),
kvm_test_age_hva_hv() and kvmppc_hv_get_dirty_log() know that the page
has been referenced and/or changed.

These hypercalls are not used by Linux guests and these implementations
are only compile tested.

Signed-off-by: Paul Mackerras <pau...@samba.org>
---
  arch/powerpc/kvm/book3s_hv_rm_mmu.c | 126 
++--

  arch/powerpc/kvm/book3s_hv_rmhandlers.S |   4 +-
  2 files changed, 121 insertions(+), 9 deletions(-)

diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c 
b/arch/powerpc/kvm/book3s_hv_rm_mmu.c

index 24ccc79..479ff7e 100644
--- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c
+++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
@@ -109,25 +109,38 @@ void kvmppc_update_rmap_change(unsigned long 
*rmap, unsigned long psize)

  }
  EXPORT_SYMBOL_GPL(kvmppc_update_rmap_change);
  +/* Returns a pointer to the revmap entry for the page mapped by a 
HPTE */
+static unsigned long *revmap_for_hpte(struct kvm *kvm, unsigned long 
hpte_v,

+  unsigned long hpte_gr)
+{
+struct kvm_memory_slot *memslot;
+unsigned long *rmap;
+unsigned long gfn;
+
+gfn = hpte_rpn(hpte_gr, hpte_page_size(hpte_v, hpte_gr));
+memslot = __gfn_to_memslot(kvm_memslots_raw(kvm), gfn);
+if (!memslot)
+return NULL;
+
+rmap = real_vmalloc_addr(>arch.rmap[gfn - 
memslot->base_gfn]);

+return rmap;
+}
+
  /* Remove this HPTE from the chain for a real page */
  static void remove_revmap_chain(struct kvm *kvm, long pte_index,
  struct revmap_entry *rev,
  unsigned long hpte_v, unsigned long hpte_r)
  {
  struct revmap_entry *next, *prev;
-unsigned long gfn, ptel, head;
-struct kvm_memory_slot *memslot;
+unsigned long ptel, head;
  unsigned long *rmap;
  unsigned long rcbits;
rcbits = hpte_r & (HPTE_R_R | HPTE_R_C);
  ptel = rev->guest_rpte |= rcbits;
-gfn = hpte_rpn(ptel, hpte_page_size(hpte_v, ptel));
-memslot = __gfn_to_memslot(kvm_memslots_raw(kvm), gfn);
-if (!memslot)
+rmap = revmap_for_hpte(kvm, hpte_v, ptel);
+if (!rmap)
  return;
-
-rmap = real_vmalloc_addr(>arch.rmap[gfn - 
memslot->base_gfn]);

  lock_rmap(rmap);
head = *rmap & KVMPPC_RMAP_INDEX;
@@ -662,6 +675,105 @@ long kvmppc_h_read(struct kvm_vcpu *vcpu, 
unsigned long flags,

  return H_SUCCESS;
  }
  +long kvmppc_h_clear_ref(struct kvm_vcpu *vcpu, unsigned long flags,
+unsigned long pte_index)
+{
+struct kvm *kvm = vcpu->kvm;
+__be64 *hpte;
+unsigned long v, r, gr;
+struct revmap_entry *rev;
+unsigned long *rmap;
+long ret = H_NOT_FOUND;
+
+if (pte_index >= kvm->arch.hpt_npte)
+return H_PARAMETER;
+
+rev = real_vmalloc_addr(>arch.revmap[pte_index]);
+hpte = (__be64 *)(kvm->arch.hpt_virt + (pte_index << 4));
+while (!try_lock_hpte(hpte, HPTE_V_HVLOCK))
+cpu_relax();
+v = be64_to_cpu(hpte[0]);
+r = be64_to_cpu(hpte[1]);
+if (!(v & (HPTE_V_VALID | HPTE_V_ABSENT)))
+goto out;
+
+gr = rev->guest_rpte;
+if (rev->guest_rpte & HPTE_R_R) {
+rev->guest_rpte &= ~HPTE_R_R;
+note_hpte_modification(kvm, rev);
+}
+if (v & HPTE_V_VALID) {
+gr |= r & (HPTE_R_R | HPTE_R_C);
+if (r & HPTE_R_R) {
+kvmppc_clear_ref_hpte(kvm, hpte, pte_index);
+rmap = revmap_for_hpte(kvm, v, gr);
+if (rmap) {
+lock_rmap(rmap);
+*rmap |= KVMPPC_RMAP_REFERENCED;
+unlock_rmap(rmap);
+}
+}
+}
+vcpu->arch.gpr[4] = gr;
+ret = H_SUCCESS;
+ out:
+unlock_hpte(hpte, v & ~HPTE_V_HVLOCK);
+return ret;
+}
+
+long kvmppc_h_clear_mod(struct kvm_vcpu *vcpu, unsigned long flags,
+unsigned long pte_index)
+{
+struct kvm *kvm = vcpu->kvm;
+__be64 *hpte;
+unsigned long v, r, gr;
+struct revmap_e

Re: [PATCH 3/3] KVM: PPC: Book3S HV: Implement H_CLEAR_REF and H_CLEAR_MOD

2015-07-27 Thread Nathan Whitehorn
I've been running with these patches and a FreeBSD guest for a while now 
and they work very well, providing big performance improvements in tight 
memory situations. Thanks! I did have to patch QEMU to enable the 
hypercalls, however -- it might be worth adding them to the default set 
since these calls are mandated by PAPR as part of the base hypercall 
interface.

-Nathan

On 04/23/15 22:39, Paul Mackerras wrote:

This adds implementations for the H_CLEAR_REF (test and clear reference
bit) and H_CLEAR_MOD (test and clear changed bit) hypercalls.

When clearing the reference or change bit in the guest view of the HPTE,
we also have to clear it in the real HPTE so that we can detect future
references or changes.  When we do so, we transfer the R or C bit value
to the rmap entry for the underlying host page so that kvm_age_hva_hv(),
kvm_test_age_hva_hv() and kvmppc_hv_get_dirty_log() know that the page
has been referenced and/or changed.

These hypercalls are not used by Linux guests and these implementations
are only compile tested.

Signed-off-by: Paul Mackerras pau...@samba.org
---
  arch/powerpc/kvm/book3s_hv_rm_mmu.c | 126 ++--
  arch/powerpc/kvm/book3s_hv_rmhandlers.S |   4 +-
  2 files changed, 121 insertions(+), 9 deletions(-)

diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c 
b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
index 24ccc79..479ff7e 100644
--- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c
+++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
@@ -109,25 +109,38 @@ void kvmppc_update_rmap_change(unsigned long *rmap, 
unsigned long psize)
  }
  EXPORT_SYMBOL_GPL(kvmppc_update_rmap_change);
  
+/* Returns a pointer to the revmap entry for the page mapped by a HPTE */

+static unsigned long *revmap_for_hpte(struct kvm *kvm, unsigned long hpte_v,
+ unsigned long hpte_gr)
+{
+   struct kvm_memory_slot *memslot;
+   unsigned long *rmap;
+   unsigned long gfn;
+
+   gfn = hpte_rpn(hpte_gr, hpte_page_size(hpte_v, hpte_gr));
+   memslot = __gfn_to_memslot(kvm_memslots_raw(kvm), gfn);
+   if (!memslot)
+   return NULL;
+
+   rmap = real_vmalloc_addr(memslot-arch.rmap[gfn - memslot-base_gfn]);
+   return rmap;
+}
+
  /* Remove this HPTE from the chain for a real page */
  static void remove_revmap_chain(struct kvm *kvm, long pte_index,
struct revmap_entry *rev,
unsigned long hpte_v, unsigned long hpte_r)
  {
struct revmap_entry *next, *prev;
-   unsigned long gfn, ptel, head;
-   struct kvm_memory_slot *memslot;
+   unsigned long ptel, head;
unsigned long *rmap;
unsigned long rcbits;
  
  	rcbits = hpte_r  (HPTE_R_R | HPTE_R_C);

ptel = rev-guest_rpte |= rcbits;
-   gfn = hpte_rpn(ptel, hpte_page_size(hpte_v, ptel));
-   memslot = __gfn_to_memslot(kvm_memslots_raw(kvm), gfn);
-   if (!memslot)
+   rmap = revmap_for_hpte(kvm, hpte_v, ptel);
+   if (!rmap)
return;
-
-   rmap = real_vmalloc_addr(memslot-arch.rmap[gfn - memslot-base_gfn]);
lock_rmap(rmap);
  
  	head = *rmap  KVMPPC_RMAP_INDEX;

@@ -662,6 +675,105 @@ long kvmppc_h_read(struct kvm_vcpu *vcpu, unsigned long 
flags,
return H_SUCCESS;
  }
  
+long kvmppc_h_clear_ref(struct kvm_vcpu *vcpu, unsigned long flags,

+   unsigned long pte_index)
+{
+   struct kvm *kvm = vcpu-kvm;
+   __be64 *hpte;
+   unsigned long v, r, gr;
+   struct revmap_entry *rev;
+   unsigned long *rmap;
+   long ret = H_NOT_FOUND;
+
+   if (pte_index = kvm-arch.hpt_npte)
+   return H_PARAMETER;
+
+   rev = real_vmalloc_addr(kvm-arch.revmap[pte_index]);
+   hpte = (__be64 *)(kvm-arch.hpt_virt + (pte_index  4));
+   while (!try_lock_hpte(hpte, HPTE_V_HVLOCK))
+   cpu_relax();
+   v = be64_to_cpu(hpte[0]);
+   r = be64_to_cpu(hpte[1]);
+   if (!(v  (HPTE_V_VALID | HPTE_V_ABSENT)))
+   goto out;
+
+   gr = rev-guest_rpte;
+   if (rev-guest_rpte  HPTE_R_R) {
+   rev-guest_rpte = ~HPTE_R_R;
+   note_hpte_modification(kvm, rev);
+   }
+   if (v  HPTE_V_VALID) {
+   gr |= r  (HPTE_R_R | HPTE_R_C);
+   if (r  HPTE_R_R) {
+   kvmppc_clear_ref_hpte(kvm, hpte, pte_index);
+   rmap = revmap_for_hpte(kvm, v, gr);
+   if (rmap) {
+   lock_rmap(rmap);
+   *rmap |= KVMPPC_RMAP_REFERENCED;
+   unlock_rmap(rmap);
+   }
+   }
+   }
+   vcpu-arch.gpr[4] = gr;
+   ret = H_SUCCESS;
+ out:
+   unlock_hpte(hpte, v  ~HPTE_V_HVLOCK);
+   return ret;
+}
+
+long kvmppc_h_clear_mod(struct kvm_vcpu *vcpu, unsigned long flags,
+   unsigned long pte_index)
+{
+   struct kvm 

Re: [PATCH 3/3] KVM: PPC: Book3S HV: Implement H_CLEAR_REF and H_CLEAR_MOD

2015-07-27 Thread Nathan Whitehorn
I've been running with these patches and a FreeBSD guest for a while now 
and they work very well, providing big performance improvements in tight 
memory situations. Thanks! I did have to patch QEMU to enable the 
hypercalls, however -- it might be worth adding them to the default set 
since these calls are mandated by PAPR as part of the base hypercall 
interface.

-Nathan

On 04/23/15 22:39, Paul Mackerras wrote:

This adds implementations for the H_CLEAR_REF (test and clear reference
bit) and H_CLEAR_MOD (test and clear changed bit) hypercalls.

When clearing the reference or change bit in the guest view of the HPTE,
we also have to clear it in the real HPTE so that we can detect future
references or changes.  When we do so, we transfer the R or C bit value
to the rmap entry for the underlying host page so that kvm_age_hva_hv(),
kvm_test_age_hva_hv() and kvmppc_hv_get_dirty_log() know that the page
has been referenced and/or changed.

These hypercalls are not used by Linux guests and these implementations
are only compile tested.

Signed-off-by: Paul Mackerras pau...@samba.org
---
  arch/powerpc/kvm/book3s_hv_rm_mmu.c | 126 ++--
  arch/powerpc/kvm/book3s_hv_rmhandlers.S |   4 +-
  2 files changed, 121 insertions(+), 9 deletions(-)

diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c 
b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
index 24ccc79..479ff7e 100644
--- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c
+++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
@@ -109,25 +109,38 @@ void kvmppc_update_rmap_change(unsigned long *rmap, 
unsigned long psize)
  }
  EXPORT_SYMBOL_GPL(kvmppc_update_rmap_change);
  
+/* Returns a pointer to the revmap entry for the page mapped by a HPTE */

+static unsigned long *revmap_for_hpte(struct kvm *kvm, unsigned long hpte_v,
+ unsigned long hpte_gr)
+{
+   struct kvm_memory_slot *memslot;
+   unsigned long *rmap;
+   unsigned long gfn;
+
+   gfn = hpte_rpn(hpte_gr, hpte_page_size(hpte_v, hpte_gr));
+   memslot = __gfn_to_memslot(kvm_memslots_raw(kvm), gfn);
+   if (!memslot)
+   return NULL;
+
+   rmap = real_vmalloc_addr(memslot-arch.rmap[gfn - memslot-base_gfn]);
+   return rmap;
+}
+
  /* Remove this HPTE from the chain for a real page */
  static void remove_revmap_chain(struct kvm *kvm, long pte_index,
struct revmap_entry *rev,
unsigned long hpte_v, unsigned long hpte_r)
  {
struct revmap_entry *next, *prev;
-   unsigned long gfn, ptel, head;
-   struct kvm_memory_slot *memslot;
+   unsigned long ptel, head;
unsigned long *rmap;
unsigned long rcbits;
  
  	rcbits = hpte_r  (HPTE_R_R | HPTE_R_C);

ptel = rev-guest_rpte |= rcbits;
-   gfn = hpte_rpn(ptel, hpte_page_size(hpte_v, ptel));
-   memslot = __gfn_to_memslot(kvm_memslots_raw(kvm), gfn);
-   if (!memslot)
+   rmap = revmap_for_hpte(kvm, hpte_v, ptel);
+   if (!rmap)
return;
-
-   rmap = real_vmalloc_addr(memslot-arch.rmap[gfn - memslot-base_gfn]);
lock_rmap(rmap);
  
  	head = *rmap  KVMPPC_RMAP_INDEX;

@@ -662,6 +675,105 @@ long kvmppc_h_read(struct kvm_vcpu *vcpu, unsigned long 
flags,
return H_SUCCESS;
  }
  
+long kvmppc_h_clear_ref(struct kvm_vcpu *vcpu, unsigned long flags,

+   unsigned long pte_index)
+{
+   struct kvm *kvm = vcpu-kvm;
+   __be64 *hpte;
+   unsigned long v, r, gr;
+   struct revmap_entry *rev;
+   unsigned long *rmap;
+   long ret = H_NOT_FOUND;
+
+   if (pte_index = kvm-arch.hpt_npte)
+   return H_PARAMETER;
+
+   rev = real_vmalloc_addr(kvm-arch.revmap[pte_index]);
+   hpte = (__be64 *)(kvm-arch.hpt_virt + (pte_index  4));
+   while (!try_lock_hpte(hpte, HPTE_V_HVLOCK))
+   cpu_relax();
+   v = be64_to_cpu(hpte[0]);
+   r = be64_to_cpu(hpte[1]);
+   if (!(v  (HPTE_V_VALID | HPTE_V_ABSENT)))
+   goto out;
+
+   gr = rev-guest_rpte;
+   if (rev-guest_rpte  HPTE_R_R) {
+   rev-guest_rpte = ~HPTE_R_R;
+   note_hpte_modification(kvm, rev);
+   }
+   if (v  HPTE_V_VALID) {
+   gr |= r  (HPTE_R_R | HPTE_R_C);
+   if (r  HPTE_R_R) {
+   kvmppc_clear_ref_hpte(kvm, hpte, pte_index);
+   rmap = revmap_for_hpte(kvm, v, gr);
+   if (rmap) {
+   lock_rmap(rmap);
+   *rmap |= KVMPPC_RMAP_REFERENCED;
+   unlock_rmap(rmap);
+   }
+   }
+   }
+   vcpu-arch.gpr[4] = gr;
+   ret = H_SUCCESS;
+ out:
+   unlock_hpte(hpte, v  ~HPTE_V_HVLOCK);
+   return ret;
+}
+
+long kvmppc_h_clear_mod(struct kvm_vcpu *vcpu, unsigned long flags,
+   unsigned long pte_index)
+{
+   struct kvm 

Re: H_CLEAR_REF and H_CLEAR_MOD

2015-04-11 Thread Nathan Whitehorn



On 02/18/15 15:33, Nathan Whitehorn wrote:


On 02/18/15 14:00, Paul Mackerras wrote:

On Wed, Feb 18, 2015 at 09:34:54AM +0100, Alexander Graf wrote:
Am 18.02.2015 um 07:12 schrieb Nathan Whitehorn 
nwhiteh...@freebsd.org:


It seems like KVM doesn't implement the H_CLEAR_REF and H_CLEAR_MOD 
hypervisor calls, which are absolutely critical for memory 
management in the FreeBSD kernel (and are marked mandatory in the 
PAPR manual). It seems some patches have been contributed already 
in 
https://lists.ozlabs.org/pipermail/linuxppc-dev/2011-December/095013.html, 
so it would be fantastic if these could end up upstream.
Paul, I guess we never included this because  there was no user. If 
FreeBSD does use it though, I think it makes a lot of sense to 
resend it for inclusion.

I agree.  I just need to check the locking and synchronization around
the reference and change bit recording, then I'll resend it.


Thanks much! Please let me know if I can help at all with this.


Any news on this? I'm happy to test the patch if you like.
-Nathan

--
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: H_CLEAR_REF and H_CLEAR_MOD

2015-04-11 Thread Nathan Whitehorn



On 02/18/15 15:33, Nathan Whitehorn wrote:


On 02/18/15 14:00, Paul Mackerras wrote:

On Wed, Feb 18, 2015 at 09:34:54AM +0100, Alexander Graf wrote:
Am 18.02.2015 um 07:12 schrieb Nathan Whitehorn 
nwhiteh...@freebsd.org:


It seems like KVM doesn't implement the H_CLEAR_REF and H_CLEAR_MOD 
hypervisor calls, which are absolutely critical for memory 
management in the FreeBSD kernel (and are marked mandatory in the 
PAPR manual). It seems some patches have been contributed already 
in 
https://lists.ozlabs.org/pipermail/linuxppc-dev/2011-December/095013.html, 
so it would be fantastic if these could end up upstream.
Paul, I guess we never included this because  there was no user. If 
FreeBSD does use it though, I think it makes a lot of sense to 
resend it for inclusion.

I agree.  I just need to check the locking and synchronization around
the reference and change bit recording, then I'll resend it.


Thanks much! Please let me know if I can help at all with this.


Any news on this? I'm happy to test the patch if you like.
-Nathan

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


Re: H_CLEAR_REF and H_CLEAR_MOD

2015-02-18 Thread Nathan Whitehorn


On 02/18/15 14:00, Paul Mackerras wrote:

On Wed, Feb 18, 2015 at 09:34:54AM +0100, Alexander Graf wrote:

Am 18.02.2015 um 07:12 schrieb Nathan Whitehorn nwhiteh...@freebsd.org:

It seems like KVM doesn't implement the H_CLEAR_REF and H_CLEAR_MOD hypervisor calls, 
which are absolutely critical for memory management in the FreeBSD kernel (and are marked 
mandatory in the PAPR manual). It seems some patches have been contributed 
already in https://lists.ozlabs.org/pipermail/linuxppc-dev/2011-December/095013.html, so 
it would be fantastic if these could end up upstream.

Paul, I guess we never included this because  there was no user. If FreeBSD 
does use it though, I think it makes a lot of sense to resend it for inclusion.

I agree.  I just need to check the locking and synchronization around
the reference and change bit recording, then I'll resend it.


Thanks much! Please let me know if I can help at all with this.


I'm going to try to get some kind of workaround in the meantime so we can at 
least run on existing kernels.

Please don't add hacks in FreeBSD only because kvm is missing a feature. Let's 
just get this done properly :).

Right.


Sounds good -- the possible workarounds are difficult anyway. I have 
added a warning at boot that checks if these return H_FUNCTION and urges 
people to upgrade their kernels if so.

-Nathan


Paul.



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


Re: H_CLEAR_REF and H_CLEAR_MOD

2015-02-18 Thread Nathan Whitehorn


On 02/18/15 14:00, Paul Mackerras wrote:

On Wed, Feb 18, 2015 at 09:34:54AM +0100, Alexander Graf wrote:

Am 18.02.2015 um 07:12 schrieb Nathan Whitehorn nwhiteh...@freebsd.org:

It seems like KVM doesn't implement the H_CLEAR_REF and H_CLEAR_MOD hypervisor calls, 
which are absolutely critical for memory management in the FreeBSD kernel (and are marked 
mandatory in the PAPR manual). It seems some patches have been contributed 
already in https://lists.ozlabs.org/pipermail/linuxppc-dev/2011-December/095013.html, so 
it would be fantastic if these could end up upstream.

Paul, I guess we never included this because  there was no user. If FreeBSD 
does use it though, I think it makes a lot of sense to resend it for inclusion.

I agree.  I just need to check the locking and synchronization around
the reference and change bit recording, then I'll resend it.


Thanks much! Please let me know if I can help at all with this.


I'm going to try to get some kind of workaround in the meantime so we can at 
least run on existing kernels.

Please don't add hacks in FreeBSD only because kvm is missing a feature. Let's 
just get this done properly :).

Right.


Sounds good -- the possible workarounds are difficult anyway. I have 
added a warning at boot that checks if these return H_FUNCTION and urges 
people to upgrade their kernels if so.

-Nathan


Paul.



--
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


H_CLEAR_REF and H_CLEAR_MOD

2015-02-17 Thread Nathan Whitehorn
It seems like KVM doesn't implement the H_CLEAR_REF and H_CLEAR_MOD 
hypervisor calls, which are absolutely critical for memory management in 
the FreeBSD kernel (and are marked mandatory in the PAPR manual). It 
seems some patches have been contributed already in 
https://lists.ozlabs.org/pipermail/linuxppc-dev/2011-December/095013.html, 
so it would be fantastic if these could end up upstream.


I'm going to try to get some kind of workaround in the meantime so we 
can at least run on existing kernels.

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