RE: [PATCH 2/2] kvm/e500v2: mapping guest TLB1 to host TLB0

2010-09-17 Thread Liu Yu-B13201
 

 -Original Message-
 From: kvm-ppc-ow...@vger.kernel.org 
 [mailto:kvm-ppc-ow...@vger.kernel.org] On Behalf Of Alexander Graf
 Sent: Thursday, September 16, 2010 7:44 PM
 To: Liu Yu-B13201
 Cc: kvm@vger.kernel.org; kvm-...@vger.kernel.org
 Subject: Re: [PATCH 2/2] kvm/e500v2: mapping guest TLB1 to host TLB0
 
  
  /*
   * writing shadow tlb entry to host TLB
   */
  -static inline void __write_host_tlbe(struct tlbe *stlbe)
  +static inline void __host_tlbe_write(struct tlbe *stlbe)
  {
mtspr(SPRN_MAS1, stlbe-mas1);
mtspr(SPRN_MAS2, stlbe-mas2);
  @@ -109,25 +110,22 @@ static inline void 

  __write_host_tlbe(struct tlbe *stlbe)
  
__asm__ __volatile__ (tlbwe\n : : );
  }
 
  -static inline void write_host_tlbe(struct kvmppc_vcpu_e500 

  *vcpu_e500,
  
  - int tlbsel, int esel, struct tlbe *stlbe)
  +static inline u32 host_tlb0_write(struct kvmppc_vcpu_e500 

  *vcpu_e500,
  
  +   u32 gvaddr, struct 
 tlbe *stlbe)
  {
  - local_irq_disable();
  - if (tlbsel == 0) {
  - __write_host_tlbe(stlbe);
  - } else {
  - unsigned register mas0;
  + unsigned register mas0;
 
  - mas0 = mfspr(SPRN_MAS0);
  + local_irq_disable();

  Do you have to disable interrupts for a tlb write? If you get 
  preempted before the write, the entry you overwrite could be 
  different. But you don't protect against that either way. And 
  if you get preempted afterwards, you could lose the entry. 
  But since you enable interrupts beyond that, that could 
  happen either way too.
 
  So what's the reason for the disable here?
 
  
 
  Hello Alex,
 
  Doesn't local_irq_disable() also disable preempt?
  The reason to disable interrupts is because it's possible 
 to have tlb
  misses in interrupt service route.

 
 Yes, local_irq_disable disables preempt. That's exactly what I was
 referring to :).
 I don't understand the statement about the service route. A tlb miss
 still arrives with local_irq_disable.
 
 

Use local_irq_disable here is to make sure we update masN in atomic.
If get preempted when we update part of masN,
then we may write wrong TLB entry in hardware.

And local_irq_disable blocks external and decrement interrupts.
Althought it's unlikely to have tlb miss in external and decrement interrrupt 
handler of current kernel.
It still has the possibility..


Thanks,
Yu

--
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 2/2] kvm/e500v2: mapping guest TLB1 to host TLB0

2010-09-17 Thread Alexander Graf

On 17.09.2010, at 10:47, Liu Yu-B13201 wrote:

 
 
 -Original Message-
 From: kvm-ppc-ow...@vger.kernel.org 
 [mailto:kvm-ppc-ow...@vger.kernel.org] On Behalf Of Alexander Graf
 Sent: Thursday, September 16, 2010 7:44 PM
 To: Liu Yu-B13201
 Cc: kvm@vger.kernel.org; kvm-...@vger.kernel.org
 Subject: Re: [PATCH 2/2] kvm/e500v2: mapping guest TLB1 to host TLB0
 
 
 /*
 * writing shadow tlb entry to host TLB
 */
 -static inline void __write_host_tlbe(struct tlbe *stlbe)
 +static inline void __host_tlbe_write(struct tlbe *stlbe)
 {
   mtspr(SPRN_MAS1, stlbe-mas1);
   mtspr(SPRN_MAS2, stlbe-mas2);
 @@ -109,25 +110,22 @@ static inline void 
 
 __write_host_tlbe(struct tlbe *stlbe)
 
   __asm__ __volatile__ (tlbwe\n : : );
 }
 
 -static inline void write_host_tlbe(struct kvmppc_vcpu_e500 
 
 *vcpu_e500,
 
 - int tlbsel, int esel, struct tlbe *stlbe)
 +static inline u32 host_tlb0_write(struct kvmppc_vcpu_e500 
 
 *vcpu_e500,
 
 +   u32 gvaddr, struct 
 tlbe *stlbe)
 {
 - local_irq_disable();
 - if (tlbsel == 0) {
 - __write_host_tlbe(stlbe);
 - } else {
 - unsigned register mas0;
 + unsigned register mas0;
 
 - mas0 = mfspr(SPRN_MAS0);
 + local_irq_disable();
 
 Do you have to disable interrupts for a tlb write? If you get 
 preempted before the write, the entry you overwrite could be 
 different. But you don't protect against that either way. And 
 if you get preempted afterwards, you could lose the entry. 
 But since you enable interrupts beyond that, that could 
 happen either way too.
 
 So what's the reason for the disable here?
 
 
 
 Hello Alex,
 
 Doesn't local_irq_disable() also disable preempt?
 The reason to disable interrupts is because it's possible 
 to have tlb
 misses in interrupt service route.
 
 
 Yes, local_irq_disable disables preempt. That's exactly what I was
 referring to :).
 I don't understand the statement about the service route. A tlb miss
 still arrives with local_irq_disable.
 
 
 
 Use local_irq_disable here is to make sure we update masN in atomic.
 If get preempted when we update part of masN,
 then we may write wrong TLB entry in hardware.

I see, makes sense. Doing the mfmsr of MAS0 in an irq disabled section doesn't 
make sense to me though. Also, wouldn't it be better to do the irq disabling 
inside of __host_tlbe_write using irqsave, not the explicit enable/disable?

 And local_irq_disable blocks external and decrement interrupts.
 Althought it's unlikely to have tlb miss in external and decrement interrrupt 
 handler of current kernel.
 It still has the possibility..

Yup :).


Alex

--
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 2/2] kvm/e500v2: mapping guest TLB1 to host TLB0

2010-09-17 Thread Liu Yu-B13201
 

 -Original Message-
 From: Alexander Graf [mailto:ag...@suse.de] 
 Sent: Friday, September 17, 2010 7:34 PM
 To: Liu Yu-B13201
 Cc: kvm@vger.kernel.org; kvm-...@vger.kernel.org
 Subject: Re: [PATCH 2/2] kvm/e500v2: mapping guest TLB1 to host TLB0
 
 
 On 17.09.2010, at 13:28, Liu Yu-B13201 wrote:
 
  
  
  -Original Message-
  From: Alexander Graf [mailto:ag...@suse.de] 
  Sent: Friday, September 17, 2010 6:20 PM
  To: Liu Yu-B13201
  Cc: kvm@vger.kernel.org; kvm-...@vger.kernel.org
  Subject: Re: [PATCH 2/2] kvm/e500v2: mapping guest TLB1 to 
 host TLB0
  
  
  On 17.09.2010, at 10:47, Liu Yu-B13201 wrote:
  
  
  
  -Original Message-
  From: kvm-ppc-ow...@vger.kernel.org 
  [mailto:kvm-ppc-ow...@vger.kernel.org] On Behalf Of 
 Alexander Graf
  Sent: Thursday, September 16, 2010 7:44 PM
  To: Liu Yu-B13201
  Cc: kvm@vger.kernel.org; kvm-...@vger.kernel.org
  Subject: Re: [PATCH 2/2] kvm/e500v2: mapping guest TLB1 to 
  host TLB0
  
  
  /*
  * writing shadow tlb entry to host TLB
  */
  -static inline void __write_host_tlbe(struct tlbe *stlbe)
  +static inline void __host_tlbe_write(struct tlbe *stlbe)
  {
mtspr(SPRN_MAS1, stlbe-mas1);
mtspr(SPRN_MAS2, stlbe-mas2);
  @@ -109,25 +110,22 @@ static inline void 
  
  __write_host_tlbe(struct tlbe *stlbe)
  
__asm__ __volatile__ (tlbwe\n : : );
  }
  
  -static inline void write_host_tlbe(struct kvmppc_vcpu_e500 
  
  *vcpu_e500,
  
  - int tlbsel, int esel, struct tlbe *stlbe)
  +static inline u32 host_tlb0_write(struct kvmppc_vcpu_e500 
  
  *vcpu_e500,
  
  +   u32 gvaddr, struct 
  tlbe *stlbe)
  {
  - local_irq_disable();
  - if (tlbsel == 0) {
  - __write_host_tlbe(stlbe);
  - } else {
  - unsigned register mas0;
  + unsigned register mas0;
  
  - mas0 = mfspr(SPRN_MAS0);
  + local_irq_disable();
  
  Do you have to disable interrupts for a tlb write? If you get 
  preempted before the write, the entry you overwrite could be 
  different. But you don't protect against that either way. And 
  if you get preempted afterwards, you could lose the entry. 
  But since you enable interrupts beyond that, that could 
  happen either way too.
  
  So what's the reason for the disable here?
  
  
  
  Hello Alex,
  
  Doesn't local_irq_disable() also disable preempt?
  The reason to disable interrupts is because it's possible 
  to have tlb
  misses in interrupt service route.
  
  
  Yes, local_irq_disable disables preempt. That's exactly 
 what I was
  referring to :).
  I don't understand the statement about the service route. 
  A tlb miss
  still arrives with local_irq_disable.
  
  
  
  Use local_irq_disable here is to make sure we update masN 
 in atomic.
  If get preempted when we update part of masN,
  then we may write wrong TLB entry in hardware.
  
  I see, makes sense. Doing the mfmsr of MAS0 in an irq 
  disabled section doesn't make sense to me though. 
  
  Hardware choose the position and put TLB entry by itself.
  I need to get the position from MAS0.
  So that I know exactly which old entry is overrided.
 
 Huh? But you do the mfmsr before the tlb write? Or does MAS0 
 contain the next tlb pointer?

There's no mfmsr.
The MAS0 contain the position we are going to write the entry in.

 
  
  Also, wouldn't it be better to do the irq disabling inside of 
  __host_tlbe_write using irqsave, not the explicit enable/disable?
  
  
  Oh? What benefit we can get from this?
 
 Cleaner structure. If writing a tlb entry needs to happen 
 atomically, the function you call should be atomic. In your 
 case that's reasonably simple to do. Also, you could return 
 MAS0 in that function. That would make things a lot more 
 obvious. While you're at it, a comment explaining what the 
 function does doesn't hurt either :)
 

Sound reasonable.:)
but why using irqsave?


Yu

--
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 2/2] kvm/e500v2: mapping guest TLB1 to host TLB0

2010-09-17 Thread Alexander Graf

On 17.09.2010, at 10:47, Liu Yu-B13201 wrote:

 
 
 -Original Message-
 From: kvm-ppc-ow...@vger.kernel.org 
 [mailto:kvm-ppc-ow...@vger.kernel.org] On Behalf Of Alexander Graf
 Sent: Thursday, September 16, 2010 7:44 PM
 To: Liu Yu-B13201
 Cc: k...@vger.kernel.org; kvm-ppc@vger.kernel.org
 Subject: Re: [PATCH 2/2] kvm/e500v2: mapping guest TLB1 to host TLB0
 
 
 /*
 * writing shadow tlb entry to host TLB
 */
 -static inline void __write_host_tlbe(struct tlbe *stlbe)
 +static inline void __host_tlbe_write(struct tlbe *stlbe)
 {
   mtspr(SPRN_MAS1, stlbe-mas1);
   mtspr(SPRN_MAS2, stlbe-mas2);
 @@ -109,25 +110,22 @@ static inline void 
 
 __write_host_tlbe(struct tlbe *stlbe)
 
   __asm__ __volatile__ (tlbwe\n : : );
 }
 
 -static inline void write_host_tlbe(struct kvmppc_vcpu_e500 
 
 *vcpu_e500,
 
 - int tlbsel, int esel, struct tlbe *stlbe)
 +static inline u32 host_tlb0_write(struct kvmppc_vcpu_e500 
 
 *vcpu_e500,
 
 +   u32 gvaddr, struct 
 tlbe *stlbe)
 {
 - local_irq_disable();
 - if (tlbsel == 0) {
 - __write_host_tlbe(stlbe);
 - } else {
 - unsigned register mas0;
 + unsigned register mas0;
 
 - mas0 = mfspr(SPRN_MAS0);
 + local_irq_disable();
 
 Do you have to disable interrupts for a tlb write? If you get 
 preempted before the write, the entry you overwrite could be 
 different. But you don't protect against that either way. And 
 if you get preempted afterwards, you could lose the entry. 
 But since you enable interrupts beyond that, that could 
 happen either way too.
 
 So what's the reason for the disable here?
 
 
 
 Hello Alex,
 
 Doesn't local_irq_disable() also disable preempt?
 The reason to disable interrupts is because it's possible 
 to have tlb
 misses in interrupt service route.
 
 
 Yes, local_irq_disable disables preempt. That's exactly what I was
 referring to :).
 I don't understand the statement about the service route. A tlb miss
 still arrives with local_irq_disable.
 
 
 
 Use local_irq_disable here is to make sure we update masN in atomic.
 If get preempted when we update part of masN,
 then we may write wrong TLB entry in hardware.

I see, makes sense. Doing the mfmsr of MAS0 in an irq disabled section doesn't 
make sense to me though. Also, wouldn't it be better to do the irq disabling 
inside of __host_tlbe_write using irqsave, not the explicit enable/disable?

 And local_irq_disable blocks external and decrement interrupts.
 Althought it's unlikely to have tlb miss in external and decrement interrrupt 
 handler of current kernel.
 It still has the possibility..

Yup :).


Alex

--
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 2/2] kvm/e500v2: mapping guest TLB1 to host TLB0

2010-09-17 Thread Alexander Graf

On 17.09.2010, at 13:28, Liu Yu-B13201 wrote:

 
 
 -Original Message-
 From: Alexander Graf [mailto:ag...@suse.de] 
 Sent: Friday, September 17, 2010 6:20 PM
 To: Liu Yu-B13201
 Cc: k...@vger.kernel.org; kvm-ppc@vger.kernel.org
 Subject: Re: [PATCH 2/2] kvm/e500v2: mapping guest TLB1 to host TLB0
 
 
 On 17.09.2010, at 10:47, Liu Yu-B13201 wrote:
 
 
 
 -Original Message-
 From: kvm-ppc-ow...@vger.kernel.org 
 [mailto:kvm-ppc-ow...@vger.kernel.org] On Behalf Of Alexander Graf
 Sent: Thursday, September 16, 2010 7:44 PM
 To: Liu Yu-B13201
 Cc: k...@vger.kernel.org; kvm-ppc@vger.kernel.org
 Subject: Re: [PATCH 2/2] kvm/e500v2: mapping guest TLB1 to 
 host TLB0
 
 
 /*
 * writing shadow tlb entry to host TLB
 */
 -static inline void __write_host_tlbe(struct tlbe *stlbe)
 +static inline void __host_tlbe_write(struct tlbe *stlbe)
 {
 mtspr(SPRN_MAS1, stlbe-mas1);
 mtspr(SPRN_MAS2, stlbe-mas2);
 @@ -109,25 +110,22 @@ static inline void 
 
 __write_host_tlbe(struct tlbe *stlbe)
 
 __asm__ __volatile__ (tlbwe\n : : );
 }
 
 -static inline void write_host_tlbe(struct kvmppc_vcpu_e500 
 
 *vcpu_e500,
 
 -   int tlbsel, int esel, struct tlbe *stlbe)
 +static inline u32 host_tlb0_write(struct kvmppc_vcpu_e500 
 
 *vcpu_e500,
 
 +   u32 gvaddr, struct 
 tlbe *stlbe)
 {
 -   local_irq_disable();
 -   if (tlbsel == 0) {
 -   __write_host_tlbe(stlbe);
 -   } else {
 -   unsigned register mas0;
 +   unsigned register mas0;
 
 -   mas0 = mfspr(SPRN_MAS0);
 +   local_irq_disable();
 
 Do you have to disable interrupts for a tlb write? If you get 
 preempted before the write, the entry you overwrite could be 
 different. But you don't protect against that either way. And 
 if you get preempted afterwards, you could lose the entry. 
 But since you enable interrupts beyond that, that could 
 happen either way too.
 
 So what's the reason for the disable here?
 
 
 
 Hello Alex,
 
 Doesn't local_irq_disable() also disable preempt?
 The reason to disable interrupts is because it's possible 
 to have tlb
 misses in interrupt service route.
 
 
 Yes, local_irq_disable disables preempt. That's exactly what I was
 referring to :).
 I don't understand the statement about the service route. 
 A tlb miss
 still arrives with local_irq_disable.
 
 
 
 Use local_irq_disable here is to make sure we update masN in atomic.
 If get preempted when we update part of masN,
 then we may write wrong TLB entry in hardware.
 
 I see, makes sense. Doing the mfmsr of MAS0 in an irq 
 disabled section doesn't make sense to me though. 
 
 Hardware choose the position and put TLB entry by itself.
 I need to get the position from MAS0.
 So that I know exactly which old entry is overrided.

Huh? But you do the mfmsr before the tlb write? Or does MAS0 contain the next 
tlb pointer?

 
 Also, wouldn't it be better to do the irq disabling inside of 
 __host_tlbe_write using irqsave, not the explicit enable/disable?
 
 
 Oh? What benefit we can get from this?

Cleaner structure. If writing a tlb entry needs to happen atomically, the 
function you call should be atomic. In your case that's reasonably simple to 
do. Also, you could return MAS0 in that function. That would make things a lot 
more obvious. While you're at it, a comment explaining what the function does 
doesn't hurt either :)


Alex

--
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 2/2] kvm/e500v2: mapping guest TLB1 to host TLB0

2010-09-17 Thread Liu Yu-B13201
 

 -Original Message-
 From: Alexander Graf [mailto:ag...@suse.de] 
 Sent: Friday, September 17, 2010 7:34 PM
 To: Liu Yu-B13201
 Cc: k...@vger.kernel.org; kvm-ppc@vger.kernel.org
 Subject: Re: [PATCH 2/2] kvm/e500v2: mapping guest TLB1 to host TLB0
 
 
 On 17.09.2010, at 13:28, Liu Yu-B13201 wrote:
 
  
  
  -Original Message-
  From: Alexander Graf [mailto:ag...@suse.de] 
  Sent: Friday, September 17, 2010 6:20 PM
  To: Liu Yu-B13201
  Cc: k...@vger.kernel.org; kvm-ppc@vger.kernel.org
  Subject: Re: [PATCH 2/2] kvm/e500v2: mapping guest TLB1 to 
 host TLB0
  
  
  On 17.09.2010, at 10:47, Liu Yu-B13201 wrote:
  
  
  
  -Original Message-
  From: kvm-ppc-ow...@vger.kernel.org 
  [mailto:kvm-ppc-ow...@vger.kernel.org] On Behalf Of 
 Alexander Graf
  Sent: Thursday, September 16, 2010 7:44 PM
  To: Liu Yu-B13201
  Cc: k...@vger.kernel.org; kvm-ppc@vger.kernel.org
  Subject: Re: [PATCH 2/2] kvm/e500v2: mapping guest TLB1 to 
  host TLB0
  
  
  /*
  * writing shadow tlb entry to host TLB
  */
  -static inline void __write_host_tlbe(struct tlbe *stlbe)
  +static inline void __host_tlbe_write(struct tlbe *stlbe)
  {
mtspr(SPRN_MAS1, stlbe-mas1);
mtspr(SPRN_MAS2, stlbe-mas2);
  @@ -109,25 +110,22 @@ static inline void 
  
  __write_host_tlbe(struct tlbe *stlbe)
  
__asm__ __volatile__ (tlbwe\n : : );
  }
  
  -static inline void write_host_tlbe(struct kvmppc_vcpu_e500 
  
  *vcpu_e500,
  
  - int tlbsel, int esel, struct tlbe *stlbe)
  +static inline u32 host_tlb0_write(struct kvmppc_vcpu_e500 
  
  *vcpu_e500,
  
  +   u32 gvaddr, struct 
  tlbe *stlbe)
  {
  - local_irq_disable();
  - if (tlbsel == 0) {
  - __write_host_tlbe(stlbe);
  - } else {
  - unsigned register mas0;
  + unsigned register mas0;
  
  - mas0 = mfspr(SPRN_MAS0);
  + local_irq_disable();
  
  Do you have to disable interrupts for a tlb write? If you get 
  preempted before the write, the entry you overwrite could be 
  different. But you don't protect against that either way. And 
  if you get preempted afterwards, you could lose the entry. 
  But since you enable interrupts beyond that, that could 
  happen either way too.
  
  So what's the reason for the disable here?
  
  
  
  Hello Alex,
  
  Doesn't local_irq_disable() also disable preempt?
  The reason to disable interrupts is because it's possible 
  to have tlb
  misses in interrupt service route.
  
  
  Yes, local_irq_disable disables preempt. That's exactly 
 what I was
  referring to :).
  I don't understand the statement about the service route. 
  A tlb miss
  still arrives with local_irq_disable.
  
  
  
  Use local_irq_disable here is to make sure we update masN 
 in atomic.
  If get preempted when we update part of masN,
  then we may write wrong TLB entry in hardware.
  
  I see, makes sense. Doing the mfmsr of MAS0 in an irq 
  disabled section doesn't make sense to me though. 
  
  Hardware choose the position and put TLB entry by itself.
  I need to get the position from MAS0.
  So that I know exactly which old entry is overrided.
 
 Huh? But you do the mfmsr before the tlb write? Or does MAS0 
 contain the next tlb pointer?

There's no mfmsr.
The MAS0 contain the position we are going to write the entry in.

 
  
  Also, wouldn't it be better to do the irq disabling inside of 
  __host_tlbe_write using irqsave, not the explicit enable/disable?
  
  
  Oh? What benefit we can get from this?
 
 Cleaner structure. If writing a tlb entry needs to happen 
 atomically, the function you call should be atomic. In your 
 case that's reasonably simple to do. Also, you could return 
 MAS0 in that function. That would make things a lot more 
 obvious. While you're at it, a comment explaining what the 
 function does doesn't hurt either :)
 

Sound reasonable.:)
but why using irqsave?


Yu

--
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 2/2] kvm/e500v2: mapping guest TLB1 to host TLB0

2010-09-17 Thread Alexander Graf

On 17.09.2010, at 14:33, Liu Yu-B13201 wrote:

 
 
 -Original Message-
 From: Alexander Graf [mailto:ag...@suse.de] 
 Sent: Friday, September 17, 2010 7:34 PM
 To: Liu Yu-B13201
 Cc: k...@vger.kernel.org; kvm-ppc@vger.kernel.org
 Subject: Re: [PATCH 2/2] kvm/e500v2: mapping guest TLB1 to host TLB0
 
 
 On 17.09.2010, at 13:28, Liu Yu-B13201 wrote:
 
 
 
 -Original Message-
 From: Alexander Graf [mailto:ag...@suse.de] 
 Sent: Friday, September 17, 2010 6:20 PM
 To: Liu Yu-B13201
 Cc: k...@vger.kernel.org; kvm-ppc@vger.kernel.org
 Subject: Re: [PATCH 2/2] kvm/e500v2: mapping guest TLB1 to 
 host TLB0
 
 
 On 17.09.2010, at 10:47, Liu Yu-B13201 wrote:
 
 
 
 -Original Message-
 From: kvm-ppc-ow...@vger.kernel.org 
 [mailto:kvm-ppc-ow...@vger.kernel.org] On Behalf Of 
 Alexander Graf
 Sent: Thursday, September 16, 2010 7:44 PM
 To: Liu Yu-B13201
 Cc: k...@vger.kernel.org; kvm-ppc@vger.kernel.org
 Subject: Re: [PATCH 2/2] kvm/e500v2: mapping guest TLB1 to 
 host TLB0
 
 
 /*
 * writing shadow tlb entry to host TLB
 */
 -static inline void __write_host_tlbe(struct tlbe *stlbe)
 +static inline void __host_tlbe_write(struct tlbe *stlbe)
 {
   mtspr(SPRN_MAS1, stlbe-mas1);
   mtspr(SPRN_MAS2, stlbe-mas2);
 @@ -109,25 +110,22 @@ static inline void 
 
 __write_host_tlbe(struct tlbe *stlbe)
 
   __asm__ __volatile__ (tlbwe\n : : );
 }
 
 -static inline void write_host_tlbe(struct kvmppc_vcpu_e500 
 
 *vcpu_e500,
 
 - int tlbsel, int esel, struct tlbe *stlbe)
 +static inline u32 host_tlb0_write(struct kvmppc_vcpu_e500 
 
 *vcpu_e500,
 
 +   u32 gvaddr, struct 
 tlbe *stlbe)
 {
 - local_irq_disable();
 - if (tlbsel == 0) {
 - __write_host_tlbe(stlbe);
 - } else {
 - unsigned register mas0;
 + unsigned register mas0;
 
 - mas0 = mfspr(SPRN_MAS0);
 + local_irq_disable();
 
 Do you have to disable interrupts for a tlb write? If you get 
 preempted before the write, the entry you overwrite could be 
 different. But you don't protect against that either way. And 
 if you get preempted afterwards, you could lose the entry. 
 But since you enable interrupts beyond that, that could 
 happen either way too.
 
 So what's the reason for the disable here?
 
 
 
 Hello Alex,
 
 Doesn't local_irq_disable() also disable preempt?
 The reason to disable interrupts is because it's possible 
 to have tlb
 misses in interrupt service route.
 
 
 Yes, local_irq_disable disables preempt. That's exactly 
 what I was
 referring to :).
 I don't understand the statement about the service route. 
 A tlb miss
 still arrives with local_irq_disable.
 
 
 
 Use local_irq_disable here is to make sure we update masN 
 in atomic.
 If get preempted when we update part of masN,
 then we may write wrong TLB entry in hardware.
 
 I see, makes sense. Doing the mfmsr of MAS0 in an irq 
 disabled section doesn't make sense to me though. 
 
 Hardware choose the position and put TLB entry by itself.
 I need to get the position from MAS0.
 So that I know exactly which old entry is overrided.
 
 Huh? But you do the mfmsr before the tlb write? Or does MAS0 
 contain the next tlb pointer?
 
 There's no mfmsr.
 The MAS0 contain the position we are going to write the entry in.
 
 
 
 Also, wouldn't it be better to do the irq disabling inside of 
 __host_tlbe_write using irqsave, not the explicit enable/disable?
 
 
 Oh? What benefit we can get from this?
 
 Cleaner structure. If writing a tlb entry needs to happen 
 atomically, the function you call should be atomic. In your 
 case that's reasonably simple to do. Also, you could return 
 MAS0 in that function. That would make things a lot more 
 obvious. While you're at it, a comment explaining what the 
 function does doesn't hurt either :)
 
 
 Sound reasonable.:)
 but why using irqsave?

So the same function can be used from an irq disabled and an irq enabled 
context. Explicit irq_disable/irq_enable calls don't stack well ;)

Alex

--
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 2/2] kvm/e500v2: mapping guest TLB1 to host TLB0

2010-09-16 Thread Liu Yu-B13201
 

 -Original Message-
 From: Alexander Graf [mailto:ag...@suse.de] 
 Sent: Friday, September 10, 2010 7:24 AM
 To: Liu Yu-B13201
 Cc: kvm@vger.kernel.org; kvm-...@vger.kernel.org
 Subject: Re: [PATCH 2/2] kvm/e500v2: mapping guest TLB1 to host TLB0
 
 
 On 08.09.2010, at 11:40, Liu Yu wrote:
 
  Current guest TLB1 is mapped to host TLB1.
  As host kernel only provides 4K uncontinuous pages,
  we have to break guest large mapping into 4K shadow mappings.
  These 4K shadow mappings are then mapped into host TLB1 on fly.
  As host TLB1 only has 13 free entries, there's serious tlb miss.
  
  Since e500v2 has a big number of TLB0 entries,
  it should be help to map those 4K shadow mappings to host TLB0.
  To achieve this, we need to unlink guest tlb and host tlb,
  So that guest TLB1 mappings can route to any host TLB0 
 entries freely.
  
  Pages/mappings are considerred in the same kind as host tlb entry.
  This patch remove the link between pages and guest tlb 
 entry to do the unlink.
  And keep host_tlb0_ref in each vcpu to trace pages.
  Then it's easy to map guest TLB1 to host TLB0.
  
  In guest ramdisk boot test(guest mainly uses TLB1),
  with this patch, the tlb miss number get down 90%.
  
  Signed-off-by: Liu Yu yu@freescale.com
  ---
  arch/powerpc/include/asm/kvm_e500.h |7 +-
  arch/powerpc/kvm/e500.c |4 +
  arch/powerpc/kvm/e500_tlb.c |  280 
 ---
  arch/powerpc/kvm/e500_tlb.h |1 +
  4 files changed, 104 insertions(+), 188 deletions(-)
  

 
  
  -static unsigned int tlb1_entry_num;
  +static inline unsigned int get_tlb0_entry_offset(u32 
 eaddr, u32 esel)
  +{
  +   return ((eaddr  0x7F000)  (12 - host_tlb0_assoc_bit) |
  +   (esel  (host_tlb0_assoc - 1)));
  +}
  
  void kvmppc_dump_tlbs(struct kvm_vcpu *vcpu)
  {
  @@ -62,11 +68,6 @@ static inline unsigned int tlb0_get_next_victim(
  return victim;
  }
  
  -static inline unsigned int tlb1_max_shadow_size(void)
  -{
  -   return tlb1_entry_num - tlbcam_index;
  -}
  -
  static inline int tlbe_is_writable(struct tlbe *tlbe)
  {
  return tlbe-mas3  (MAS3_SW|MAS3_UW);
  @@ -100,7 +101,7 @@ static inline u32 
 e500_shadow_mas2_attrib(u32 mas2, int usermode)
  /*
   * writing shadow tlb entry to host TLB
   */
  -static inline void __write_host_tlbe(struct tlbe *stlbe)
  +static inline void __host_tlbe_write(struct tlbe *stlbe)
  {
  mtspr(SPRN_MAS1, stlbe-mas1);
  mtspr(SPRN_MAS2, stlbe-mas2);
  @@ -109,25 +110,22 @@ static inline void 
 __write_host_tlbe(struct tlbe *stlbe)
  __asm__ __volatile__ (tlbwe\n : : );
  }
  
  -static inline void write_host_tlbe(struct kvmppc_vcpu_e500 
 *vcpu_e500,
  -   int tlbsel, int esel, struct tlbe *stlbe)
  +static inline u32 host_tlb0_write(struct kvmppc_vcpu_e500 
 *vcpu_e500,
  +   u32 gvaddr, struct tlbe *stlbe)
  {
  -   local_irq_disable();
  -   if (tlbsel == 0) {
  -   __write_host_tlbe(stlbe);
  -   } else {
  -   unsigned register mas0;
  +   unsigned register mas0;
  
  -   mas0 = mfspr(SPRN_MAS0);
  +   local_irq_disable();
 
 Do you have to disable interrupts for a tlb write? If you get 
 preempted before the write, the entry you overwrite could be 
 different. But you don't protect against that either way. And 
 if you get preempted afterwards, you could lose the entry. 
 But since you enable interrupts beyond that, that could 
 happen either way too.
 
 So what's the reason for the disable here?
 

Hello Alex,

Doesn't local_irq_disable() also disable preempt?
The reason to disable interrupts is because it's possible to have tlb
misses in interrupt service route.


Thanks,
Yu

--
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 2/2] kvm/e500v2: mapping guest TLB1 to host TLB0

2010-09-16 Thread Alexander Graf
Liu Yu-B13201 wrote:
  

   
 -Original Message-
 From: Alexander Graf [mailto:ag...@suse.de] 
 Sent: Friday, September 10, 2010 7:24 AM
 To: Liu Yu-B13201
 Cc: kvm@vger.kernel.org; kvm-...@vger.kernel.org
 Subject: Re: [PATCH 2/2] kvm/e500v2: mapping guest TLB1 to host TLB0


 On 08.09.2010, at 11:40, Liu Yu wrote:

 
 Current guest TLB1 is mapped to host TLB1.
 As host kernel only provides 4K uncontinuous pages,
 we have to break guest large mapping into 4K shadow mappings.
 These 4K shadow mappings are then mapped into host TLB1 on fly.
 As host TLB1 only has 13 free entries, there's serious tlb miss.

 Since e500v2 has a big number of TLB0 entries,
 it should be help to map those 4K shadow mappings to host TLB0.
 To achieve this, we need to unlink guest tlb and host tlb,
 So that guest TLB1 mappings can route to any host TLB0 
   
 entries freely.
 
 Pages/mappings are considerred in the same kind as host tlb entry.
 This patch remove the link between pages and guest tlb 
   
 entry to do the unlink.
 
 And keep host_tlb0_ref in each vcpu to trace pages.
 Then it's easy to map guest TLB1 to host TLB0.

 In guest ramdisk boot test(guest mainly uses TLB1),
 with this patch, the tlb miss number get down 90%.

 Signed-off-by: Liu Yu yu@freescale.com
 ---
 arch/powerpc/include/asm/kvm_e500.h |7 +-
 arch/powerpc/kvm/e500.c |4 +
 arch/powerpc/kvm/e500_tlb.c |  280 
   
 ---
 
 arch/powerpc/kvm/e500_tlb.h |1 +
 4 files changed, 104 insertions(+), 188 deletions(-)

   

   
 -static unsigned int tlb1_entry_num;
 +static inline unsigned int get_tlb0_entry_offset(u32 
   
 eaddr, u32 esel)
 
 +{
 +   return ((eaddr  0x7F000)  (12 - host_tlb0_assoc_bit) |
 +   (esel  (host_tlb0_assoc - 1)));
 +}

 void kvmppc_dump_tlbs(struct kvm_vcpu *vcpu)
 {
 @@ -62,11 +68,6 @@ static inline unsigned int tlb0_get_next_victim(
 return victim;
 }

 -static inline unsigned int tlb1_max_shadow_size(void)
 -{
 -   return tlb1_entry_num - tlbcam_index;
 -}
 -
 static inline int tlbe_is_writable(struct tlbe *tlbe)
 {
 return tlbe-mas3  (MAS3_SW|MAS3_UW);
 @@ -100,7 +101,7 @@ static inline u32 
   
 e500_shadow_mas2_attrib(u32 mas2, int usermode)
 
 /*
  * writing shadow tlb entry to host TLB
  */
 -static inline void __write_host_tlbe(struct tlbe *stlbe)
 +static inline void __host_tlbe_write(struct tlbe *stlbe)
 {
 mtspr(SPRN_MAS1, stlbe-mas1);
 mtspr(SPRN_MAS2, stlbe-mas2);
 @@ -109,25 +110,22 @@ static inline void 
   
 __write_host_tlbe(struct tlbe *stlbe)
 
 __asm__ __volatile__ (tlbwe\n : : );
 }

 -static inline void write_host_tlbe(struct kvmppc_vcpu_e500 
   
 *vcpu_e500,
 
 -   int tlbsel, int esel, struct tlbe *stlbe)
 +static inline u32 host_tlb0_write(struct kvmppc_vcpu_e500 
   
 *vcpu_e500,
 
 +   u32 gvaddr, struct tlbe *stlbe)
 {
 -   local_irq_disable();
 -   if (tlbsel == 0) {
 -   __write_host_tlbe(stlbe);
 -   } else {
 -   unsigned register mas0;
 +   unsigned register mas0;

 -   mas0 = mfspr(SPRN_MAS0);
 +   local_irq_disable();
   
 Do you have to disable interrupts for a tlb write? If you get 
 preempted before the write, the entry you overwrite could be 
 different. But you don't protect against that either way. And 
 if you get preempted afterwards, you could lose the entry. 
 But since you enable interrupts beyond that, that could 
 happen either way too.

 So what's the reason for the disable here?

 

 Hello Alex,

 Doesn't local_irq_disable() also disable preempt?
 The reason to disable interrupts is because it's possible to have tlb
 misses in interrupt service route.
   

Yes, local_irq_disable disables preempt. That's exactly what I was
referring to :).
I don't understand the statement about the service route. A tlb miss
still arrives with local_irq_disable.


Alex

--
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 2/2] kvm/e500v2: mapping guest TLB1 to host TLB0

2010-09-16 Thread Liu Yu-B13201
 

 -Original Message-
 From: Alexander Graf [mailto:ag...@suse.de] 
 Sent: Friday, September 10, 2010 7:24 AM
 To: Liu Yu-B13201
 Cc: k...@vger.kernel.org; kvm-ppc@vger.kernel.org
 Subject: Re: [PATCH 2/2] kvm/e500v2: mapping guest TLB1 to host TLB0
 
 
 On 08.09.2010, at 11:40, Liu Yu wrote:
 
  Current guest TLB1 is mapped to host TLB1.
  As host kernel only provides 4K uncontinuous pages,
  we have to break guest large mapping into 4K shadow mappings.
  These 4K shadow mappings are then mapped into host TLB1 on fly.
  As host TLB1 only has 13 free entries, there's serious tlb miss.
  
  Since e500v2 has a big number of TLB0 entries,
  it should be help to map those 4K shadow mappings to host TLB0.
  To achieve this, we need to unlink guest tlb and host tlb,
  So that guest TLB1 mappings can route to any host TLB0 
 entries freely.
  
  Pages/mappings are considerred in the same kind as host tlb entry.
  This patch remove the link between pages and guest tlb 
 entry to do the unlink.
  And keep host_tlb0_ref in each vcpu to trace pages.
  Then it's easy to map guest TLB1 to host TLB0.
  
  In guest ramdisk boot test(guest mainly uses TLB1),
  with this patch, the tlb miss number get down 90%.
  
  Signed-off-by: Liu Yu yu@freescale.com
  ---
  arch/powerpc/include/asm/kvm_e500.h |7 +-
  arch/powerpc/kvm/e500.c |4 +
  arch/powerpc/kvm/e500_tlb.c |  280 
 ---
  arch/powerpc/kvm/e500_tlb.h |1 +
  4 files changed, 104 insertions(+), 188 deletions(-)
  

 
  
  -static unsigned int tlb1_entry_num;
  +static inline unsigned int get_tlb0_entry_offset(u32 
 eaddr, u32 esel)
  +{
  +   return ((eaddr  0x7F000)  (12 - host_tlb0_assoc_bit) |
  +   (esel  (host_tlb0_assoc - 1)));
  +}
  
  void kvmppc_dump_tlbs(struct kvm_vcpu *vcpu)
  {
  @@ -62,11 +68,6 @@ static inline unsigned int tlb0_get_next_victim(
  return victim;
  }
  
  -static inline unsigned int tlb1_max_shadow_size(void)
  -{
  -   return tlb1_entry_num - tlbcam_index;
  -}
  -
  static inline int tlbe_is_writable(struct tlbe *tlbe)
  {
  return tlbe-mas3  (MAS3_SW|MAS3_UW);
  @@ -100,7 +101,7 @@ static inline u32 
 e500_shadow_mas2_attrib(u32 mas2, int usermode)
  /*
   * writing shadow tlb entry to host TLB
   */
  -static inline void __write_host_tlbe(struct tlbe *stlbe)
  +static inline void __host_tlbe_write(struct tlbe *stlbe)
  {
  mtspr(SPRN_MAS1, stlbe-mas1);
  mtspr(SPRN_MAS2, stlbe-mas2);
  @@ -109,25 +110,22 @@ static inline void 
 __write_host_tlbe(struct tlbe *stlbe)
  __asm__ __volatile__ (tlbwe\n : : );
  }
  
  -static inline void write_host_tlbe(struct kvmppc_vcpu_e500 
 *vcpu_e500,
  -   int tlbsel, int esel, struct tlbe *stlbe)
  +static inline u32 host_tlb0_write(struct kvmppc_vcpu_e500 
 *vcpu_e500,
  +   u32 gvaddr, struct tlbe *stlbe)
  {
  -   local_irq_disable();
  -   if (tlbsel == 0) {
  -   __write_host_tlbe(stlbe);
  -   } else {
  -   unsigned register mas0;
  +   unsigned register mas0;
  
  -   mas0 = mfspr(SPRN_MAS0);
  +   local_irq_disable();
 
 Do you have to disable interrupts for a tlb write? If you get 
 preempted before the write, the entry you overwrite could be 
 different. But you don't protect against that either way. And 
 if you get preempted afterwards, you could lose the entry. 
 But since you enable interrupts beyond that, that could 
 happen either way too.
 
 So what's the reason for the disable here?
 

Hello Alex,

Doesn't local_irq_disable() also disable preempt?
The reason to disable interrupts is because it's possible to have tlb
misses in interrupt service route.


Thanks,
Yu

--
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 2/2] kvm/e500v2: mapping guest TLB1 to host TLB0

2010-09-16 Thread Alexander Graf
Liu Yu-B13201 wrote:
  

   
 -Original Message-
 From: Alexander Graf [mailto:ag...@suse.de] 
 Sent: Friday, September 10, 2010 7:24 AM
 To: Liu Yu-B13201
 Cc: k...@vger.kernel.org; kvm-ppc@vger.kernel.org
 Subject: Re: [PATCH 2/2] kvm/e500v2: mapping guest TLB1 to host TLB0


 On 08.09.2010, at 11:40, Liu Yu wrote:

 
 Current guest TLB1 is mapped to host TLB1.
 As host kernel only provides 4K uncontinuous pages,
 we have to break guest large mapping into 4K shadow mappings.
 These 4K shadow mappings are then mapped into host TLB1 on fly.
 As host TLB1 only has 13 free entries, there's serious tlb miss.

 Since e500v2 has a big number of TLB0 entries,
 it should be help to map those 4K shadow mappings to host TLB0.
 To achieve this, we need to unlink guest tlb and host tlb,
 So that guest TLB1 mappings can route to any host TLB0 
   
 entries freely.
 
 Pages/mappings are considerred in the same kind as host tlb entry.
 This patch remove the link between pages and guest tlb 
   
 entry to do the unlink.
 
 And keep host_tlb0_ref in each vcpu to trace pages.
 Then it's easy to map guest TLB1 to host TLB0.

 In guest ramdisk boot test(guest mainly uses TLB1),
 with this patch, the tlb miss number get down 90%.

 Signed-off-by: Liu Yu yu@freescale.com
 ---
 arch/powerpc/include/asm/kvm_e500.h |7 +-
 arch/powerpc/kvm/e500.c |4 +
 arch/powerpc/kvm/e500_tlb.c |  280 
   
 ---
 
 arch/powerpc/kvm/e500_tlb.h |1 +
 4 files changed, 104 insertions(+), 188 deletions(-)

   

   
 -static unsigned int tlb1_entry_num;
 +static inline unsigned int get_tlb0_entry_offset(u32 
   
 eaddr, u32 esel)
 
 +{
 +   return ((eaddr  0x7F000)  (12 - host_tlb0_assoc_bit) |
 +   (esel  (host_tlb0_assoc - 1)));
 +}

 void kvmppc_dump_tlbs(struct kvm_vcpu *vcpu)
 {
 @@ -62,11 +68,6 @@ static inline unsigned int tlb0_get_next_victim(
 return victim;
 }

 -static inline unsigned int tlb1_max_shadow_size(void)
 -{
 -   return tlb1_entry_num - tlbcam_index;
 -}
 -
 static inline int tlbe_is_writable(struct tlbe *tlbe)
 {
 return tlbe-mas3  (MAS3_SW|MAS3_UW);
 @@ -100,7 +101,7 @@ static inline u32 
   
 e500_shadow_mas2_attrib(u32 mas2, int usermode)
 
 /*
  * writing shadow tlb entry to host TLB
  */
 -static inline void __write_host_tlbe(struct tlbe *stlbe)
 +static inline void __host_tlbe_write(struct tlbe *stlbe)
 {
 mtspr(SPRN_MAS1, stlbe-mas1);
 mtspr(SPRN_MAS2, stlbe-mas2);
 @@ -109,25 +110,22 @@ static inline void 
   
 __write_host_tlbe(struct tlbe *stlbe)
 
 __asm__ __volatile__ (tlbwe\n : : );
 }

 -static inline void write_host_tlbe(struct kvmppc_vcpu_e500 
   
 *vcpu_e500,
 
 -   int tlbsel, int esel, struct tlbe *stlbe)
 +static inline u32 host_tlb0_write(struct kvmppc_vcpu_e500 
   
 *vcpu_e500,
 
 +   u32 gvaddr, struct tlbe *stlbe)
 {
 -   local_irq_disable();
 -   if (tlbsel == 0) {
 -   __write_host_tlbe(stlbe);
 -   } else {
 -   unsigned register mas0;
 +   unsigned register mas0;

 -   mas0 = mfspr(SPRN_MAS0);
 +   local_irq_disable();
   
 Do you have to disable interrupts for a tlb write? If you get 
 preempted before the write, the entry you overwrite could be 
 different. But you don't protect against that either way. And 
 if you get preempted afterwards, you could lose the entry. 
 But since you enable interrupts beyond that, that could 
 happen either way too.

 So what's the reason for the disable here?

 

 Hello Alex,

 Doesn't local_irq_disable() also disable preempt?
 The reason to disable interrupts is because it's possible to have tlb
 misses in interrupt service route.
   

Yes, local_irq_disable disables preempt. That's exactly what I was
referring to :).
I don't understand the statement about the service route. A tlb miss
still arrives with local_irq_disable.


Alex

--
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 2/2] kvm/e500v2: mapping guest TLB1 to host TLB0

2010-09-15 Thread Alexander Graf
Liu, ping?


On 10.09.2010, at 01:24, Alexander Graf wrote:

 
 On 08.09.2010, at 11:40, Liu Yu wrote:
 
 Current guest TLB1 is mapped to host TLB1.
 As host kernel only provides 4K uncontinuous pages,
 we have to break guest large mapping into 4K shadow mappings.
 These 4K shadow mappings are then mapped into host TLB1 on fly.
 As host TLB1 only has 13 free entries, there's serious tlb miss.
 
 Since e500v2 has a big number of TLB0 entries,
 it should be help to map those 4K shadow mappings to host TLB0.
 To achieve this, we need to unlink guest tlb and host tlb,
 So that guest TLB1 mappings can route to any host TLB0 entries freely.
 
 Pages/mappings are considerred in the same kind as host tlb entry.
 This patch remove the link between pages and guest tlb entry to do the 
 unlink.
 And keep host_tlb0_ref in each vcpu to trace pages.
 Then it's easy to map guest TLB1 to host TLB0.
 
 In guest ramdisk boot test(guest mainly uses TLB1),
 with this patch, the tlb miss number get down 90%.
 
 Signed-off-by: Liu Yu yu@freescale.com
 ---
 arch/powerpc/include/asm/kvm_e500.h |7 +-
 arch/powerpc/kvm/e500.c |4 +
 arch/powerpc/kvm/e500_tlb.c |  280 
 ---
 arch/powerpc/kvm/e500_tlb.h |1 +
 4 files changed, 104 insertions(+), 188 deletions(-)

[snip]


Alex--
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 2/2] kvm/e500v2: mapping guest TLB1 to host TLB0

2010-09-15 Thread Alexander Graf
Liu, ping?


On 10.09.2010, at 01:24, Alexander Graf wrote:

 
 On 08.09.2010, at 11:40, Liu Yu wrote:
 
 Current guest TLB1 is mapped to host TLB1.
 As host kernel only provides 4K uncontinuous pages,
 we have to break guest large mapping into 4K shadow mappings.
 These 4K shadow mappings are then mapped into host TLB1 on fly.
 As host TLB1 only has 13 free entries, there's serious tlb miss.
 
 Since e500v2 has a big number of TLB0 entries,
 it should be help to map those 4K shadow mappings to host TLB0.
 To achieve this, we need to unlink guest tlb and host tlb,
 So that guest TLB1 mappings can route to any host TLB0 entries freely.
 
 Pages/mappings are considerred in the same kind as host tlb entry.
 This patch remove the link between pages and guest tlb entry to do the 
 unlink.
 And keep host_tlb0_ref in each vcpu to trace pages.
 Then it's easy to map guest TLB1 to host TLB0.
 
 In guest ramdisk boot test(guest mainly uses TLB1),
 with this patch, the tlb miss number get down 90%.
 
 Signed-off-by: Liu Yu yu@freescale.com
 ---
 arch/powerpc/include/asm/kvm_e500.h |7 +-
 arch/powerpc/kvm/e500.c |4 +
 arch/powerpc/kvm/e500_tlb.c |  280 
 ---
 arch/powerpc/kvm/e500_tlb.h |1 +
 4 files changed, 104 insertions(+), 188 deletions(-)

[snip]


Alex--
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 2/2] kvm/e500v2: mapping guest TLB1 to host TLB0

2010-09-09 Thread Alexander Graf

On 08.09.2010, at 11:40, Liu Yu wrote:

 Current guest TLB1 is mapped to host TLB1.
 As host kernel only provides 4K uncontinuous pages,
 we have to break guest large mapping into 4K shadow mappings.
 These 4K shadow mappings are then mapped into host TLB1 on fly.
 As host TLB1 only has 13 free entries, there's serious tlb miss.
 
 Since e500v2 has a big number of TLB0 entries,
 it should be help to map those 4K shadow mappings to host TLB0.
 To achieve this, we need to unlink guest tlb and host tlb,
 So that guest TLB1 mappings can route to any host TLB0 entries freely.
 
 Pages/mappings are considerred in the same kind as host tlb entry.
 This patch remove the link between pages and guest tlb entry to do the unlink.
 And keep host_tlb0_ref in each vcpu to trace pages.
 Then it's easy to map guest TLB1 to host TLB0.
 
 In guest ramdisk boot test(guest mainly uses TLB1),
 with this patch, the tlb miss number get down 90%.
 
 Signed-off-by: Liu Yu yu@freescale.com
 ---
 arch/powerpc/include/asm/kvm_e500.h |7 +-
 arch/powerpc/kvm/e500.c |4 +
 arch/powerpc/kvm/e500_tlb.c |  280 ---
 arch/powerpc/kvm/e500_tlb.h |1 +
 4 files changed, 104 insertions(+), 188 deletions(-)
 
 diff --git a/arch/powerpc/include/asm/kvm_e500.h 
 b/arch/powerpc/include/asm/kvm_e500.h
 index cb785f9..16c0ed0 100644
 --- a/arch/powerpc/include/asm/kvm_e500.h
 +++ b/arch/powerpc/include/asm/kvm_e500.h
 @@ -37,13 +37,10 @@ struct tlbe_ref {
 struct kvmppc_vcpu_e500 {
   /* Unmodified copy of the guest's TLB. */
   struct tlbe *guest_tlb[E500_TLB_NUM];
 - /* TLB that's actually used when the guest is running. */
 - struct tlbe *shadow_tlb[E500_TLB_NUM];
 - /* Pages which are referenced in the shadow TLB. */
 - struct tlbe_ref *shadow_refs[E500_TLB_NUM];
 + /* Pages which are referenced in host TLB. */
 + struct tlbe_ref *host_tlb0_ref;
 
   unsigned int guest_tlb_size[E500_TLB_NUM];
 - unsigned int shadow_tlb_size[E500_TLB_NUM];
   unsigned int guest_tlb_nv[E500_TLB_NUM];
 
   u32 host_pid[E500_PID_NUM];
 diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c
 index e8a00b0..14af6d7 100644
 --- a/arch/powerpc/kvm/e500.c
 +++ b/arch/powerpc/kvm/e500.c
 @@ -146,6 +146,10 @@ static int __init kvmppc_e500_init(void)
   if (r)
   return r;
 
 + r = kvmppc_e500_mmu_init();
 + if (r)
 + return r;
 +
   /* copy extra E500 exception handlers */
   ivor[0] = mfspr(SPRN_IVOR32);
   ivor[1] = mfspr(SPRN_IVOR33);
 diff --git a/arch/powerpc/kvm/e500_tlb.c b/arch/powerpc/kvm/e500_tlb.c
 index 0b657af..a6c2320 100644
 --- a/arch/powerpc/kvm/e500_tlb.c
 +++ b/arch/powerpc/kvm/e500_tlb.c
 @@ -25,9 +25,15 @@
 #include e500_tlb.h
 #include trace.h
 
 -#define to_htlb1_esel(esel) (tlb1_entry_num - (esel) - 1)
 +static unsigned int host_tlb0_entry_num;
 +static unsigned int host_tlb0_assoc;
 +static unsigned int host_tlb0_assoc_bit;

bits.

 
 -static unsigned int tlb1_entry_num;
 +static inline unsigned int get_tlb0_entry_offset(u32 eaddr, u32 esel)
 +{
 + return ((eaddr  0x7F000)  (12 - host_tlb0_assoc_bit) |
 + (esel  (host_tlb0_assoc - 1)));
 +}
 
 void kvmppc_dump_tlbs(struct kvm_vcpu *vcpu)
 {
 @@ -62,11 +68,6 @@ static inline unsigned int tlb0_get_next_victim(
   return victim;
 }
 
 -static inline unsigned int tlb1_max_shadow_size(void)
 -{
 - return tlb1_entry_num - tlbcam_index;
 -}
 -
 static inline int tlbe_is_writable(struct tlbe *tlbe)
 {
   return tlbe-mas3  (MAS3_SW|MAS3_UW);
 @@ -100,7 +101,7 @@ static inline u32 e500_shadow_mas2_attrib(u32 mas2, int 
 usermode)
 /*
  * writing shadow tlb entry to host TLB
  */
 -static inline void __write_host_tlbe(struct tlbe *stlbe)
 +static inline void __host_tlbe_write(struct tlbe *stlbe)
 {
   mtspr(SPRN_MAS1, stlbe-mas1);
   mtspr(SPRN_MAS2, stlbe-mas2);
 @@ -109,25 +110,22 @@ static inline void __write_host_tlbe(struct tlbe *stlbe)
   __asm__ __volatile__ (tlbwe\n : : );
 }
 
 -static inline void write_host_tlbe(struct kvmppc_vcpu_e500 *vcpu_e500,
 - int tlbsel, int esel, struct tlbe *stlbe)
 +static inline u32 host_tlb0_write(struct kvmppc_vcpu_e500 *vcpu_e500,
 +   u32 gvaddr, struct tlbe *stlbe)
 {
 - local_irq_disable();
 - if (tlbsel == 0) {
 - __write_host_tlbe(stlbe);
 - } else {
 - unsigned register mas0;
 + unsigned register mas0;
 
 - mas0 = mfspr(SPRN_MAS0);
 + local_irq_disable();

Do you have to disable interrupts for a tlb write? If you get preempted before 
the write, the entry you overwrite could be different. But you don't protect 
against that either way. And if you get preempted afterwards, you could lose 
the entry. But since you enable interrupts beyond that, that could happen 
either way too.

So what's the reason for the disable here?

 
 - 

Re: [PATCH 2/2] kvm/e500v2: mapping guest TLB1 to host TLB0

2010-09-09 Thread Alexander Graf

On 08.09.2010, at 11:40, Liu Yu wrote:

 Current guest TLB1 is mapped to host TLB1.
 As host kernel only provides 4K uncontinuous pages,
 we have to break guest large mapping into 4K shadow mappings.
 These 4K shadow mappings are then mapped into host TLB1 on fly.
 As host TLB1 only has 13 free entries, there's serious tlb miss.
 
 Since e500v2 has a big number of TLB0 entries,
 it should be help to map those 4K shadow mappings to host TLB0.
 To achieve this, we need to unlink guest tlb and host tlb,
 So that guest TLB1 mappings can route to any host TLB0 entries freely.
 
 Pages/mappings are considerred in the same kind as host tlb entry.
 This patch remove the link between pages and guest tlb entry to do the unlink.
 And keep host_tlb0_ref in each vcpu to trace pages.
 Then it's easy to map guest TLB1 to host TLB0.
 
 In guest ramdisk boot test(guest mainly uses TLB1),
 with this patch, the tlb miss number get down 90%.
 
 Signed-off-by: Liu Yu yu@freescale.com
 ---
 arch/powerpc/include/asm/kvm_e500.h |7 +-
 arch/powerpc/kvm/e500.c |4 +
 arch/powerpc/kvm/e500_tlb.c |  280 ---
 arch/powerpc/kvm/e500_tlb.h |1 +
 4 files changed, 104 insertions(+), 188 deletions(-)
 
 diff --git a/arch/powerpc/include/asm/kvm_e500.h 
 b/arch/powerpc/include/asm/kvm_e500.h
 index cb785f9..16c0ed0 100644
 --- a/arch/powerpc/include/asm/kvm_e500.h
 +++ b/arch/powerpc/include/asm/kvm_e500.h
 @@ -37,13 +37,10 @@ struct tlbe_ref {
 struct kvmppc_vcpu_e500 {
   /* Unmodified copy of the guest's TLB. */
   struct tlbe *guest_tlb[E500_TLB_NUM];
 - /* TLB that's actually used when the guest is running. */
 - struct tlbe *shadow_tlb[E500_TLB_NUM];
 - /* Pages which are referenced in the shadow TLB. */
 - struct tlbe_ref *shadow_refs[E500_TLB_NUM];
 + /* Pages which are referenced in host TLB. */
 + struct tlbe_ref *host_tlb0_ref;
 
   unsigned int guest_tlb_size[E500_TLB_NUM];
 - unsigned int shadow_tlb_size[E500_TLB_NUM];
   unsigned int guest_tlb_nv[E500_TLB_NUM];
 
   u32 host_pid[E500_PID_NUM];
 diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c
 index e8a00b0..14af6d7 100644
 --- a/arch/powerpc/kvm/e500.c
 +++ b/arch/powerpc/kvm/e500.c
 @@ -146,6 +146,10 @@ static int __init kvmppc_e500_init(void)
   if (r)
   return r;
 
 + r = kvmppc_e500_mmu_init();
 + if (r)
 + return r;
 +
   /* copy extra E500 exception handlers */
   ivor[0] = mfspr(SPRN_IVOR32);
   ivor[1] = mfspr(SPRN_IVOR33);
 diff --git a/arch/powerpc/kvm/e500_tlb.c b/arch/powerpc/kvm/e500_tlb.c
 index 0b657af..a6c2320 100644
 --- a/arch/powerpc/kvm/e500_tlb.c
 +++ b/arch/powerpc/kvm/e500_tlb.c
 @@ -25,9 +25,15 @@
 #include e500_tlb.h
 #include trace.h
 
 -#define to_htlb1_esel(esel) (tlb1_entry_num - (esel) - 1)
 +static unsigned int host_tlb0_entry_num;
 +static unsigned int host_tlb0_assoc;
 +static unsigned int host_tlb0_assoc_bit;

bits.

 
 -static unsigned int tlb1_entry_num;
 +static inline unsigned int get_tlb0_entry_offset(u32 eaddr, u32 esel)
 +{
 + return ((eaddr  0x7F000)  (12 - host_tlb0_assoc_bit) |
 + (esel  (host_tlb0_assoc - 1)));
 +}
 
 void kvmppc_dump_tlbs(struct kvm_vcpu *vcpu)
 {
 @@ -62,11 +68,6 @@ static inline unsigned int tlb0_get_next_victim(
   return victim;
 }
 
 -static inline unsigned int tlb1_max_shadow_size(void)
 -{
 - return tlb1_entry_num - tlbcam_index;
 -}
 -
 static inline int tlbe_is_writable(struct tlbe *tlbe)
 {
   return tlbe-mas3  (MAS3_SW|MAS3_UW);
 @@ -100,7 +101,7 @@ static inline u32 e500_shadow_mas2_attrib(u32 mas2, int 
 usermode)
 /*
  * writing shadow tlb entry to host TLB
  */
 -static inline void __write_host_tlbe(struct tlbe *stlbe)
 +static inline void __host_tlbe_write(struct tlbe *stlbe)
 {
   mtspr(SPRN_MAS1, stlbe-mas1);
   mtspr(SPRN_MAS2, stlbe-mas2);
 @@ -109,25 +110,22 @@ static inline void __write_host_tlbe(struct tlbe *stlbe)
   __asm__ __volatile__ (tlbwe\n : : );
 }
 
 -static inline void write_host_tlbe(struct kvmppc_vcpu_e500 *vcpu_e500,
 - int tlbsel, int esel, struct tlbe *stlbe)
 +static inline u32 host_tlb0_write(struct kvmppc_vcpu_e500 *vcpu_e500,
 +   u32 gvaddr, struct tlbe *stlbe)
 {
 - local_irq_disable();
 - if (tlbsel == 0) {
 - __write_host_tlbe(stlbe);
 - } else {
 - unsigned register mas0;
 + unsigned register mas0;
 
 - mas0 = mfspr(SPRN_MAS0);
 + local_irq_disable();

Do you have to disable interrupts for a tlb write? If you get preempted before 
the write, the entry you overwrite could be different. But you don't protect 
against that either way. And if you get preempted afterwards, you could lose 
the entry. But since you enable interrupts beyond that, that could happen 
either way too.

So what's the reason for the disable here?

 
 -