Re: [Xen-devel] [PATCH v3 03/14] AMD/IOMMU: use bit field for control register

2019-07-22 Thread Jan Beulich
On 19.07.2019 20:23,  Woods, Brian  wrote:
> On Tue, Jul 16, 2019 at 04:36:06PM +, Jan Beulich wrote:
>> Also introduce a field in struct amd_iommu caching the most recently
>> written control register. All writes should now happen exclusively from
>> that cached value, such that it is guaranteed to be up to date.
>>
>> Take the opportunity and add further fields. Also convert a few boolean
>> function parameters to bool, such that use of !! can be avoided.
>>
>> Because of there now being definitions beyond bit 31, writel() also gets
>> replaced by writeq() when updating hardware.
>>
>> Signed-off-by: Jan Beulich 
>> Acked-by: Andrew Cooper 
> 
> Acked-by: Brian Woods 

Thanks for this and the other acks. I notice though that you skipped
patches 2 and 13: Are there concerns there? Patch 8 still has a
discussion to settle, so I realize you probably wouldn't want to ack
that one yet.

Jan
___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

Re: [Xen-devel] [PATCH v3 03/14] AMD/IOMMU: use bit field for control register

2019-07-19 Thread Woods, Brian
On Tue, Jul 16, 2019 at 04:36:06PM +, Jan Beulich wrote:
> Also introduce a field in struct amd_iommu caching the most recently
> written control register. All writes should now happen exclusively from
> that cached value, such that it is guaranteed to be up to date.
> 
> Take the opportunity and add further fields. Also convert a few boolean
> function parameters to bool, such that use of !! can be avoided.
> 
> Because of there now being definitions beyond bit 31, writel() also gets
> replaced by writeq() when updating hardware.
> 
> Signed-off-by: Jan Beulich 
> Acked-by: Andrew Cooper 

Acked-by: Brian Woods 

> ---
> v3: Switch boolean bitfields to bool.
> v2: Add domain_id_pne field. Mention writel() -> writeq() change.
> 
> --- a/xen/drivers/passthrough/amd/iommu_guest.c
> +++ b/xen/drivers/passthrough/amd/iommu_guest.c
> @@ -317,7 +317,7 @@ static int do_invalidate_iotlb_pages(str
>   
>   static int do_completion_wait(struct domain *d, cmd_entry_t *cmd)
>   {
> -bool_t com_wait_int_en, com_wait_int, i, s;
> +bool com_wait_int, i, s;
>   struct guest_iommu *iommu;
>   unsigned long gfn;
>   p2m_type_t p2mt;
> @@ -354,12 +354,10 @@ static int do_completion_wait(struct dom
>   unmap_domain_page(vaddr);
>   }
>   
> -com_wait_int_en = iommu_get_bit(iommu->reg_ctrl.lo,
> -IOMMU_CONTROL_COMP_WAIT_INT_SHIFT);
>   com_wait_int = iommu_get_bit(iommu->reg_status.lo,
>IOMMU_STATUS_COMP_WAIT_INT_SHIFT);
>   
> -if ( com_wait_int_en && com_wait_int )
> +if ( iommu->reg_ctrl.com_wait_int_en && com_wait_int )
>   guest_iommu_deliver_msi(d);
>   
>   return 0;
> @@ -521,40 +519,17 @@ static void guest_iommu_process_command(
>   return;
>   }
>   
> -static int guest_iommu_write_ctrl(struct guest_iommu *iommu, uint64_t 
> newctrl)
> +static int guest_iommu_write_ctrl(struct guest_iommu *iommu, uint64_t val)
>   {
> -bool_t cmd_en, event_en, iommu_en, ppr_en, ppr_log_en;
> -bool_t cmd_en_old, event_en_old, iommu_en_old;
> -bool_t cmd_run;
> -
> -iommu_en = iommu_get_bit(newctrl,
> - IOMMU_CONTROL_TRANSLATION_ENABLE_SHIFT);
> -iommu_en_old = iommu_get_bit(iommu->reg_ctrl.lo,
> - IOMMU_CONTROL_TRANSLATION_ENABLE_SHIFT);
> -
> -cmd_en = iommu_get_bit(newctrl,
> -   IOMMU_CONTROL_COMMAND_BUFFER_ENABLE_SHIFT);
> -cmd_en_old = iommu_get_bit(iommu->reg_ctrl.lo,
> -   IOMMU_CONTROL_COMMAND_BUFFER_ENABLE_SHIFT);
> -cmd_run = iommu_get_bit(iommu->reg_status.lo,
> -IOMMU_STATUS_CMD_BUFFER_RUN_SHIFT);
> -event_en = iommu_get_bit(newctrl,
> - IOMMU_CONTROL_EVENT_LOG_ENABLE_SHIFT);
> -event_en_old = iommu_get_bit(iommu->reg_ctrl.lo,
> - IOMMU_CONTROL_EVENT_LOG_ENABLE_SHIFT);
> -
> -ppr_en = iommu_get_bit(newctrl,
> -   IOMMU_CONTROL_PPR_ENABLE_SHIFT);
> -ppr_log_en = iommu_get_bit(newctrl,
> -   IOMMU_CONTROL_PPR_LOG_ENABLE_SHIFT);
> +union amd_iommu_control newctrl = { .raw = val };
>   
> -if ( iommu_en )
> +if ( newctrl.iommu_en )
>   {
>   guest_iommu_enable(iommu);
>   guest_iommu_enable_dev_table(iommu);
>   }
>   
> -if ( iommu_en && cmd_en )
> +if ( newctrl.iommu_en && newctrl.cmd_buf_en )
>   {
>   guest_iommu_enable_ring_buffer(iommu, >cmd_buffer,
>  sizeof(cmd_entry_t));
> @@ -562,7 +537,7 @@ static int guest_iommu_write_ctrl(struct
>   tasklet_schedule(>cmd_buffer_tasklet);
>   }
>   
> -if ( iommu_en && event_en )
> +if ( newctrl.iommu_en && newctrl.event_log_en )
>   {
>   guest_iommu_enable_ring_buffer(iommu, >event_log,
>  sizeof(event_entry_t));
> @@ -570,7 +545,7 @@ static int guest_iommu_write_ctrl(struct
>   guest_iommu_clear_status(iommu, IOMMU_STATUS_EVENT_OVERFLOW_SHIFT);
>   }
>   
> -if ( iommu_en && ppr_en && ppr_log_en )
> +if ( newctrl.iommu_en && newctrl.ppr_en && newctrl.ppr_log_en )
>   {
>   guest_iommu_enable_ring_buffer(iommu, >ppr_log,
>  sizeof(ppr_entry_t));
> @@ -578,19 +553,21 @@ static int guest_iommu_write_ctrl(struct
>   guest_iommu_clear_status(iommu, 
> IOMMU_STATUS_PPR_LOG_OVERFLOW_SHIFT);
>   }
>   
> -if ( iommu_en && cmd_en_old && !cmd_en )
> +if ( newctrl.iommu_en && iommu->reg_ctrl.cmd_buf_en &&
> + !newctrl.cmd_buf_en )
>   {
>   /* Disable iommu command processing */
>   tasklet_kill(>cmd_buffer_tasklet);
>   }
>   
> -if ( event_en_old && !event_en )
> +if ( iommu->reg_ctrl.event_log_en && !newctrl.event_log_en )
>   

[Xen-devel] [PATCH v3 03/14] AMD/IOMMU: use bit field for control register

2019-07-16 Thread Jan Beulich
Also introduce a field in struct amd_iommu caching the most recently
written control register. All writes should now happen exclusively from
that cached value, such that it is guaranteed to be up to date.

Take the opportunity and add further fields. Also convert a few boolean
function parameters to bool, such that use of !! can be avoided.

Because of there now being definitions beyond bit 31, writel() also gets
replaced by writeq() when updating hardware.

Signed-off-by: Jan Beulich 
Acked-by: Andrew Cooper 
---
v3: Switch boolean bitfields to bool.
v2: Add domain_id_pne field. Mention writel() -> writeq() change.

--- a/xen/drivers/passthrough/amd/iommu_guest.c
+++ b/xen/drivers/passthrough/amd/iommu_guest.c
@@ -317,7 +317,7 @@ static int do_invalidate_iotlb_pages(str
  
  static int do_completion_wait(struct domain *d, cmd_entry_t *cmd)
  {
-bool_t com_wait_int_en, com_wait_int, i, s;
+bool com_wait_int, i, s;
  struct guest_iommu *iommu;
  unsigned long gfn;
  p2m_type_t p2mt;
@@ -354,12 +354,10 @@ static int do_completion_wait(struct dom
  unmap_domain_page(vaddr);
  }
  
-com_wait_int_en = iommu_get_bit(iommu->reg_ctrl.lo,
-IOMMU_CONTROL_COMP_WAIT_INT_SHIFT);
  com_wait_int = iommu_get_bit(iommu->reg_status.lo,
   IOMMU_STATUS_COMP_WAIT_INT_SHIFT);
  
-if ( com_wait_int_en && com_wait_int )
+if ( iommu->reg_ctrl.com_wait_int_en && com_wait_int )
  guest_iommu_deliver_msi(d);
  
  return 0;
@@ -521,40 +519,17 @@ static void guest_iommu_process_command(
  return;
  }
  
-static int guest_iommu_write_ctrl(struct guest_iommu *iommu, uint64_t newctrl)
+static int guest_iommu_write_ctrl(struct guest_iommu *iommu, uint64_t val)
  {
-bool_t cmd_en, event_en, iommu_en, ppr_en, ppr_log_en;
-bool_t cmd_en_old, event_en_old, iommu_en_old;
-bool_t cmd_run;
-
-iommu_en = iommu_get_bit(newctrl,
- IOMMU_CONTROL_TRANSLATION_ENABLE_SHIFT);
-iommu_en_old = iommu_get_bit(iommu->reg_ctrl.lo,
- IOMMU_CONTROL_TRANSLATION_ENABLE_SHIFT);
-
-cmd_en = iommu_get_bit(newctrl,
-   IOMMU_CONTROL_COMMAND_BUFFER_ENABLE_SHIFT);
-cmd_en_old = iommu_get_bit(iommu->reg_ctrl.lo,
-   IOMMU_CONTROL_COMMAND_BUFFER_ENABLE_SHIFT);
-cmd_run = iommu_get_bit(iommu->reg_status.lo,
-IOMMU_STATUS_CMD_BUFFER_RUN_SHIFT);
-event_en = iommu_get_bit(newctrl,
- IOMMU_CONTROL_EVENT_LOG_ENABLE_SHIFT);
-event_en_old = iommu_get_bit(iommu->reg_ctrl.lo,
- IOMMU_CONTROL_EVENT_LOG_ENABLE_SHIFT);
-
-ppr_en = iommu_get_bit(newctrl,
-   IOMMU_CONTROL_PPR_ENABLE_SHIFT);
-ppr_log_en = iommu_get_bit(newctrl,
-   IOMMU_CONTROL_PPR_LOG_ENABLE_SHIFT);
+union amd_iommu_control newctrl = { .raw = val };
  
-if ( iommu_en )
+if ( newctrl.iommu_en )
  {
  guest_iommu_enable(iommu);
  guest_iommu_enable_dev_table(iommu);
  }
  
-if ( iommu_en && cmd_en )
+if ( newctrl.iommu_en && newctrl.cmd_buf_en )
  {
  guest_iommu_enable_ring_buffer(iommu, >cmd_buffer,
 sizeof(cmd_entry_t));
@@ -562,7 +537,7 @@ static int guest_iommu_write_ctrl(struct
  tasklet_schedule(>cmd_buffer_tasklet);
  }
  
-if ( iommu_en && event_en )
+if ( newctrl.iommu_en && newctrl.event_log_en )
  {
  guest_iommu_enable_ring_buffer(iommu, >event_log,
 sizeof(event_entry_t));
@@ -570,7 +545,7 @@ static int guest_iommu_write_ctrl(struct
  guest_iommu_clear_status(iommu, IOMMU_STATUS_EVENT_OVERFLOW_SHIFT);
  }
  
-if ( iommu_en && ppr_en && ppr_log_en )
+if ( newctrl.iommu_en && newctrl.ppr_en && newctrl.ppr_log_en )
  {
  guest_iommu_enable_ring_buffer(iommu, >ppr_log,
 sizeof(ppr_entry_t));
@@ -578,19 +553,21 @@ static int guest_iommu_write_ctrl(struct
  guest_iommu_clear_status(iommu, IOMMU_STATUS_PPR_LOG_OVERFLOW_SHIFT);
  }
  
-if ( iommu_en && cmd_en_old && !cmd_en )
+if ( newctrl.iommu_en && iommu->reg_ctrl.cmd_buf_en &&
+ !newctrl.cmd_buf_en )
  {
  /* Disable iommu command processing */
  tasklet_kill(>cmd_buffer_tasklet);
  }
  
-if ( event_en_old && !event_en )
+if ( iommu->reg_ctrl.event_log_en && !newctrl.event_log_en )
  guest_iommu_clear_status(iommu, IOMMU_STATUS_EVENT_LOG_RUN_SHIFT);
  
-if ( iommu_en_old && !iommu_en )
+if ( iommu->reg_ctrl.iommu_en && !newctrl.iommu_en )
  guest_iommu_disable(iommu);
  
-u64_to_reg(>reg_ctrl, newctrl);
+iommu->reg_ctrl = newctrl;
+
  return 0;
  }
  
@@ -632,7 +609,7 @@ static uint64_t