* [PATCH 6/8] scsi: mvsas: convert tasklets to use new tasklet_setup() API
From: Allen Pais @ 2020-08-17 8:54 UTC (permalink / raw)
To: jejb, martin.petersen, kashyap.desai, sumit.saxena,
shivasharan.srikanteshwara
Cc: keescook, linux-scsi, linux-kernel, Allen Pais, target-devel,
Romain Perier, linuxppc-dev, megaraidlinux.pdl
In-Reply-To: <20200817085409.25268-1-allen.cryptic@gmail.com>
From: Allen Pais <allen.lkml@gmail.com>
In preparation for unconditionally passing the
struct tasklet_struct pointer to all tasklet
callbacks, switch to using the new tasklet_setup()
and from_tasklet() to pass the tasklet pointer explicitly.
Signed-off-by: Romain Perier <romain.perier@gmail.com>
Signed-off-by: Allen Pais <allen.lkml@gmail.com>
---
drivers/scsi/mvsas/mv_init.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/scsi/mvsas/mv_init.c b/drivers/scsi/mvsas/mv_init.c
index 978f5283c883..53b2d463fa13 100644
--- a/drivers/scsi/mvsas/mv_init.c
+++ b/drivers/scsi/mvsas/mv_init.c
@@ -147,13 +147,14 @@ static void mvs_free(struct mvs_info *mvi)
}
#ifdef CONFIG_SCSI_MVSAS_TASKLET
-static void mvs_tasklet(unsigned long opaque)
+static void mvs_tasklet(struct tasklet_struct *t)
{
u32 stat;
u16 core_nr, i = 0;
struct mvs_info *mvi;
- struct sas_ha_struct *sha = (struct sas_ha_struct *)opaque;
+ struct mvs_prv_info *mpi = from_tasklet(mpi, t, mv_tasklet);
+ struct sas_ha_struct *sha = pci_get_drvdata(mpi->mvi[0]->pdev);
core_nr = ((struct mvs_prv_info *)sha->lldd_ha)->n_host;
mvi = ((struct mvs_prv_info *)sha->lldd_ha)->mvi[0];
@@ -564,8 +565,7 @@ static int mvs_pci_init(struct pci_dev *pdev, const struct pci_device_id *ent)
} while (nhost < chip->n_host);
mpi = (struct mvs_prv_info *)(SHOST_TO_SAS_HA(shost)->lldd_ha);
#ifdef CONFIG_SCSI_MVSAS_TASKLET
- tasklet_init(&(mpi->mv_tasklet), mvs_tasklet,
- (unsigned long)SHOST_TO_SAS_HA(shost));
+ tasklet_setup(&(mpi->mv_tasklet), mvs_tasklet);
#endif
mvs_post_sas_ha_init(shost, chip);
--
2.17.1
^ permalink raw reply related
* [PATCH 5/8] scsi: megaraid: convert tasklets to use new tasklet_setup() API
From: Allen Pais @ 2020-08-17 8:54 UTC (permalink / raw)
To: jejb, martin.petersen, kashyap.desai, sumit.saxena,
shivasharan.srikanteshwara
Cc: keescook, linux-scsi, linux-kernel, Allen Pais, target-devel,
Romain Perier, linuxppc-dev, megaraidlinux.pdl
In-Reply-To: <20200817085409.25268-1-allen.cryptic@gmail.com>
From: Allen Pais <allen.lkml@gmail.com>
In preparation for unconditionally passing the
struct tasklet_struct pointer to all tasklet
callbacks, switch to using the new tasklet_setup()
and from_tasklet() to pass the tasklet pointer explicitly.
Signed-off-by: Romain Perier <romain.perier@gmail.com>
Signed-off-by: Allen Pais <allen.lkml@gmail.com>
---
drivers/scsi/megaraid/megaraid_mbox.c | 9 ++++-----
drivers/scsi/megaraid/megaraid_sas.h | 2 +-
drivers/scsi/megaraid/megaraid_sas_base.c | 16 +++++++---------
drivers/scsi/megaraid/megaraid_sas_fusion.c | 14 +++++++-------
4 files changed, 19 insertions(+), 22 deletions(-)
diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c
index 19469a2c0ea3..47b2d8045c9d 100644
--- a/drivers/scsi/megaraid/megaraid_mbox.c
+++ b/drivers/scsi/megaraid/megaraid_mbox.c
@@ -119,7 +119,7 @@ static void megaraid_mbox_prepare_epthru(adapter_t *, scb_t *,
static irqreturn_t megaraid_isr(int, void *);
-static void megaraid_mbox_dpc(unsigned long);
+static void megaraid_mbox_dpc(struct tasklet_struct *t);
static ssize_t megaraid_sysfs_show_app_hndl(struct device *, struct device_attribute *attr, char *);
static ssize_t megaraid_sysfs_show_ldnum(struct device *, struct device_attribute *attr, char *);
@@ -878,8 +878,7 @@ megaraid_init_mbox(adapter_t *adapter)
}
// setup tasklet for DPC
- tasklet_init(&adapter->dpc_h, megaraid_mbox_dpc,
- (unsigned long)adapter);
+ tasklet_setup(&adapter->dpc_h, megaraid_mbox_dpc);
con_log(CL_DLEVEL1, (KERN_INFO
"megaraid mbox hba successfully initialized\n"));
@@ -2168,9 +2167,9 @@ megaraid_isr(int irq, void *devp)
* it is being called.
*/
static void
-megaraid_mbox_dpc(unsigned long devp)
+megaraid_mbox_dpc(struct tasklet_struct *t)
{
- adapter_t *adapter = (adapter_t *)devp;
+ adapter_t *adapter = from_tasklet(adapter, t, dpc_h);
mraid_device_t *raid_dev;
struct list_head clist;
struct scatterlist *sgl;
diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
index 5e4137f10e0e..ce361b2b9f14 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -2531,7 +2531,7 @@ struct megasas_instance_template {
int (*check_reset)(struct megasas_instance *, \
struct megasas_register_set __iomem *);
irqreturn_t (*service_isr)(int irq, void *devp);
- void (*tasklet)(unsigned long);
+ void (*tasklet)(struct tasklet_struct *t);
u32 (*init_adapter)(struct megasas_instance *);
u32 (*build_and_issue_cmd) (struct megasas_instance *,
struct scsi_cmnd *);
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c
index 861f7140f52e..dba60cc1cf41 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -217,7 +217,7 @@ megasas_init_adapter_mfi(struct megasas_instance *instance);
u32
megasas_build_and_issue_cmd(struct megasas_instance *instance,
struct scsi_cmnd *scmd);
-static void megasas_complete_cmd_dpc(unsigned long instance_addr);
+static void megasas_complete_cmd_dpc(struct tasklet_struct *t);
int
wait_and_poll(struct megasas_instance *instance, struct megasas_cmd *cmd,
int seconds);
@@ -2217,14 +2217,14 @@ megasas_check_and_restore_queue_depth(struct megasas_instance *instance)
*
* Tasklet to complete cmds
*/
-static void megasas_complete_cmd_dpc(unsigned long instance_addr)
+static void megasas_complete_cmd_dpc(struct tasklet_struct *t)
{
u32 producer;
u32 consumer;
u32 context;
struct megasas_cmd *cmd;
- struct megasas_instance *instance =
- (struct megasas_instance *)instance_addr;
+ struct megasas_instance *instance = from_tasklet(instance, t,
+ isr_tasklet);
unsigned long flags;
/* If we have already declared adapter dead, donot complete cmds */
@@ -2769,7 +2769,7 @@ static int megasas_wait_for_outstanding(struct megasas_instance *instance)
* Call cmd completion routine. Cmd to be
* be completed directly without depending on isr.
*/
- megasas_complete_cmd_dpc((unsigned long)instance);
+ megasas_complete_cmd_dpc(&instance->isr_tasklet);
}
msleep(1000);
@@ -6180,8 +6180,7 @@ static int megasas_init_fw(struct megasas_instance *instance)
dev_info(&instance->pdev->dev,
"RDPQ mode\t: (%s)\n", instance->is_rdpq ? "enabled" : "disabled");
- tasklet_init(&instance->isr_tasklet, instance->instancet->tasklet,
- (unsigned long)instance);
+ tasklet_setup(&instance->isr_tasklet, instance->instancet->tasklet);
/*
* Below are default value for legacy Firmware.
@@ -7719,8 +7718,7 @@ megasas_resume(struct pci_dev *pdev)
if (megasas_get_ctrl_info(instance) != DCMD_SUCCESS)
goto fail_init_mfi;
- tasklet_init(&instance->isr_tasklet, instance->instancet->tasklet,
- (unsigned long)instance);
+ tasklet_setup(&instance->isr_tasklet, instance->instancet->tasklet);
if (instance->msix_vectors ?
megasas_setup_irqs_msix(instance, 0) :
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index 0824410f78f8..67b07660971a 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -3705,15 +3705,15 @@ int megasas_irqpoll(struct irq_poll *irqpoll, int budget)
/**
* megasas_complete_cmd_dpc_fusion - Completes command
- * @instance_addr: Adapter soft state address
+ * @t: Instance of the tasklet being run
*
* Tasklet to complete cmds
*/
static void
-megasas_complete_cmd_dpc_fusion(unsigned long instance_addr)
+megasas_complete_cmd_dpc_fusion(struct tasklet_struct *t)
{
- struct megasas_instance *instance =
- (struct megasas_instance *)instance_addr;
+ struct megasas_instance *instance = from_tasklet(instance, t,
+ isr_tasklet);
u32 count, MSIxIndex;
count = instance->msix_vectors > 0 ? instance->msix_vectors : 1;
@@ -4062,7 +4062,7 @@ megasas_wait_for_outstanding_fusion(struct megasas_instance *instance,
if (reason == MFI_IO_TIMEOUT_OCR) {
dev_info(&instance->pdev->dev,
"MFI command is timed out\n");
- megasas_complete_cmd_dpc_fusion((unsigned long)instance);
+ megasas_complete_cmd_dpc_fusion(&instance->isr_tasklet);
if (instance->snapdump_wait_time)
megasas_trigger_snap_dump(instance);
retval = 1;
@@ -4078,7 +4078,7 @@ megasas_wait_for_outstanding_fusion(struct megasas_instance *instance,
"FW in FAULT state Fault code:0x%x subcode:0x%x func:%s\n",
abs_state & MFI_STATE_FAULT_CODE,
abs_state & MFI_STATE_FAULT_SUBCODE, __func__);
- megasas_complete_cmd_dpc_fusion((unsigned long)instance);
+ megasas_complete_cmd_dpc_fusion(&instance->isr_tasklet);
if (instance->requestorId && reason) {
dev_warn(&instance->pdev->dev, "SR-IOV Found FW in FAULT"
" state while polling during"
@@ -4122,7 +4122,7 @@ megasas_wait_for_outstanding_fusion(struct megasas_instance *instance,
}
}
- megasas_complete_cmd_dpc_fusion((unsigned long)instance);
+ megasas_complete_cmd_dpc_fusion(&instance->isr_tasklet);
outstanding = atomic_read(&instance->fw_outstanding);
if (!outstanding)
goto out;
--
2.17.1
^ permalink raw reply related
* [PATCH 4/8] scsi: isci: convert tasklets to use new tasklet_setup() API
From: Allen Pais @ 2020-08-17 8:54 UTC (permalink / raw)
To: jejb, martin.petersen, kashyap.desai, sumit.saxena,
shivasharan.srikanteshwara
Cc: keescook, linux-scsi, linux-kernel, Allen Pais, target-devel,
Romain Perier, linuxppc-dev, megaraidlinux.pdl
In-Reply-To: <20200817085409.25268-1-allen.cryptic@gmail.com>
From: Allen Pais <allen.lkml@gmail.com>
In preparation for unconditionally passing the
struct tasklet_struct pointer to all tasklet
callbacks, switch to using the new tasklet_setup()
and from_tasklet() to pass the tasklet pointer explicitly.
Signed-off-by: Romain Perier <romain.perier@gmail.com>
Signed-off-by: Allen Pais <allen.lkml@gmail.com>
---
drivers/scsi/isci/host.c | 4 ++--
drivers/scsi/isci/host.h | 2 +-
drivers/scsi/isci/init.c | 3 +--
3 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/drivers/scsi/isci/host.c b/drivers/scsi/isci/host.c
index 7b5deae68d33..599adebd039e 100644
--- a/drivers/scsi/isci/host.c
+++ b/drivers/scsi/isci/host.c
@@ -1113,9 +1113,9 @@ void ireq_done(struct isci_host *ihost, struct isci_request *ireq, struct sas_ta
* @data: This parameter specifies the ISCI host object
*
*/
-void isci_host_completion_routine(unsigned long data)
+void isci_host_completion_routine(struct tasklet_struct *t)
{
- struct isci_host *ihost = (struct isci_host *)data;
+ struct isci_host *ihost = from_tasklet(ihost, t, completion_tasklet);
u16 active;
spin_lock_irq(&ihost->scic_lock);
diff --git a/drivers/scsi/isci/host.h b/drivers/scsi/isci/host.h
index 6bc3f022630a..6abe23682d9b 100644
--- a/drivers/scsi/isci/host.h
+++ b/drivers/scsi/isci/host.h
@@ -478,7 +478,7 @@ void isci_tci_free(struct isci_host *ihost, u16 tci);
void ireq_done(struct isci_host *ihost, struct isci_request *ireq, struct sas_task *task);
int isci_host_init(struct isci_host *);
-void isci_host_completion_routine(unsigned long data);
+void isci_host_completion_routine(struct tasklet_struct *t);
void isci_host_deinit(struct isci_host *);
void sci_controller_disable_interrupts(struct isci_host *ihost);
bool sci_controller_has_remote_devices_stopping(struct isci_host *ihost);
diff --git a/drivers/scsi/isci/init.c b/drivers/scsi/isci/init.c
index 085e285f427d..32a0117b5ff4 100644
--- a/drivers/scsi/isci/init.c
+++ b/drivers/scsi/isci/init.c
@@ -511,8 +511,7 @@ static struct isci_host *isci_host_alloc(struct pci_dev *pdev, int id)
init_waitqueue_head(&ihost->eventq);
ihost->sas_ha.dev = &ihost->pdev->dev;
ihost->sas_ha.lldd_ha = ihost;
- tasklet_init(&ihost->completion_tasklet,
- isci_host_completion_routine, (unsigned long)ihost);
+ tasklet_setup(&ihost->completion_tasklet, isci_host_completion_routine);
/* validate module parameters */
/* TODO: kill struct sci_user_parameters and reference directly */
--
2.17.1
^ permalink raw reply related
* [PATCH 3/8] scsi: ibmvscsi: convert tasklets to use new tasklet_setup() API
From: Allen Pais @ 2020-08-17 8:54 UTC (permalink / raw)
To: jejb, martin.petersen, kashyap.desai, sumit.saxena,
shivasharan.srikanteshwara
Cc: keescook, linux-scsi, linux-kernel, Allen Pais, target-devel,
Romain Perier, linuxppc-dev, megaraidlinux.pdl
In-Reply-To: <20200817085409.25268-1-allen.cryptic@gmail.com>
From: Allen Pais <allen.lkml@gmail.com>
In preparation for unconditionally passing the
struct tasklet_struct pointer to all tasklet
callbacks, switch to using the new tasklet_setup()
and from_tasklet() to pass the tasklet pointer explicitly.
Signed-off-by: Romain Perier <romain.perier@gmail.com>
Signed-off-by: Allen Pais <allen.lkml@gmail.com>
---
drivers/scsi/ibmvscsi/ibmvfc.c | 6 +++---
drivers/scsi/ibmvscsi/ibmvscsi.c | 8 ++++----
drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c | 7 +++----
3 files changed, 10 insertions(+), 11 deletions(-)
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index 77f4d37d5bd6..50f025cdabbd 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -3204,9 +3204,9 @@ static irqreturn_t ibmvfc_interrupt(int irq, void *dev_instance)
* Returns:
* Nothing
**/
-static void ibmvfc_tasklet(void *data)
+static void ibmvfc_tasklet(struct tasklet_struct *t)
{
- struct ibmvfc_host *vhost = data;
+ struct ibmvfc_host *vhost = from_tasklet(vhost, t, tasklet);
struct vio_dev *vdev = to_vio_dev(vhost->dev);
struct ibmvfc_crq *crq;
struct ibmvfc_async_crq *async;
@@ -4676,7 +4676,7 @@ static int ibmvfc_init_crq(struct ibmvfc_host *vhost)
retrc = 0;
- tasklet_init(&vhost->tasklet, (void *)ibmvfc_tasklet, (unsigned long)vhost);
+ tasklet_setup(&vhost->tasklet, (void *)ibmvfc_tasklet);
if ((rc = request_irq(vdev->irq, ibmvfc_interrupt, 0, IBMVFC_NAME, vhost))) {
dev_err(dev, "Couldn't register irq 0x%x. rc=%d\n", vdev->irq, rc);
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c
index b1f3017b6547..46b818daa957 100644
--- a/drivers/scsi/ibmvscsi/ibmvscsi.c
+++ b/drivers/scsi/ibmvscsi/ibmvscsi.c
@@ -208,9 +208,10 @@ static int ibmvscsi_send_crq(struct ibmvscsi_host_data *hostdata,
* ibmvscsi_task: - Process srps asynchronously
* @data: ibmvscsi_host_data of host
*/
-static void ibmvscsi_task(void *data)
+static void ibmvscsi_task(struct tasklet_struct *t)
{
- struct ibmvscsi_host_data *hostdata = (struct ibmvscsi_host_data *)data;
+ struct ibmvscsi_host_data *hostdata = from_tasklet(hostdata, t,
+ srp_task);
struct vio_dev *vdev = to_vio_dev(hostdata->dev);
struct viosrp_crq *crq;
int done = 0;
@@ -366,8 +367,7 @@ static int ibmvscsi_init_crq_queue(struct crq_queue *queue,
queue->cur = 0;
spin_lock_init(&queue->lock);
- tasklet_init(&hostdata->srp_task, (void *)ibmvscsi_task,
- (unsigned long)hostdata);
+ tasklet_setup(&hostdata->srp_task, ibmvscsi_task);
if (request_irq(vdev->irq,
ibmvscsi_handle_event,
diff --git a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
index d9e94e81da01..e62fd6c67001 100644
--- a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
+++ b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
@@ -3328,9 +3328,9 @@ static int ibmvscsis_rdma(struct ibmvscsis_cmd *cmd, struct scatterlist *sg,
*
* Note: this is an edge triggered interrupt. It can not be shared.
*/
-static void ibmvscsis_handle_crq(unsigned long data)
+static void ibmvscsis_handle_crq(struct tasklet_struct *t)
{
- struct scsi_info *vscsi = (struct scsi_info *)data;
+ struct scsi_info *vscsi = from_tasklet(vscsi, t, work_task);
struct viosrp_crq *crq;
long rc;
bool ack = true;
@@ -3541,8 +3541,7 @@ static int ibmvscsis_probe(struct vio_dev *vdev,
dev_dbg(&vscsi->dev, "probe hrc %ld, client partition num %d\n",
hrc, vscsi->client_data.partition_number);
- tasklet_init(&vscsi->work_task, ibmvscsis_handle_crq,
- (unsigned long)vscsi);
+ tasklet_setup(&vscsi->work_task, ibmvscsis_handle_crq);
init_completion(&vscsi->wait_idle);
init_completion(&vscsi->unconfig);
--
2.17.1
^ permalink raw reply related
* [PATCH 2/8] scsi: esas2r: convert tasklets to use new tasklet_setup() API
From: Allen Pais @ 2020-08-17 8:54 UTC (permalink / raw)
To: jejb, martin.petersen, kashyap.desai, sumit.saxena,
shivasharan.srikanteshwara
Cc: keescook, linux-scsi, linux-kernel, Allen Pais, target-devel,
Romain Perier, linuxppc-dev, megaraidlinux.pdl
In-Reply-To: <20200817085409.25268-1-allen.cryptic@gmail.com>
From: Allen Pais <allen.lkml@gmail.com>
In preparation for unconditionally passing the
struct tasklet_struct pointer to all tasklet
callbacks, switch to using the new tasklet_setup()
and from_tasklet() to pass the tasklet pointer explicitly.
Signed-off-by: Romain Perier <romain.perier@gmail.com>
Signed-off-by: Allen Pais <allen.lkml@gmail.com>
---
drivers/scsi/esas2r/esas2r.h | 2 +-
drivers/scsi/esas2r/esas2r_init.c | 4 +---
drivers/scsi/esas2r/esas2r_main.c | 4 ++--
3 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/drivers/scsi/esas2r/esas2r.h b/drivers/scsi/esas2r/esas2r.h
index e30d2f1f5368..b99434e24868 100644
--- a/drivers/scsi/esas2r/esas2r.h
+++ b/drivers/scsi/esas2r/esas2r.h
@@ -992,7 +992,7 @@ int esas2r_write_vda(struct esas2r_adapter *a, const char *buf, long off,
int esas2r_read_fs(struct esas2r_adapter *a, char *buf, long off, int count);
int esas2r_write_fs(struct esas2r_adapter *a, const char *buf, long off,
int count);
-void esas2r_adapter_tasklet(unsigned long context);
+void esas2r_adapter_tasklet(struct tasklet_struct *t);
irqreturn_t esas2r_interrupt(int irq, void *dev_id);
irqreturn_t esas2r_msi_interrupt(int irq, void *dev_id);
void esas2r_kickoff_timer(struct esas2r_adapter *a);
diff --git a/drivers/scsi/esas2r/esas2r_init.c b/drivers/scsi/esas2r/esas2r_init.c
index eb7d139ffc00..55387c14fb8d 100644
--- a/drivers/scsi/esas2r/esas2r_init.c
+++ b/drivers/scsi/esas2r/esas2r_init.c
@@ -401,9 +401,7 @@ int esas2r_init_adapter(struct Scsi_Host *host, struct pci_dev *pcid,
return 0;
}
- tasklet_init(&a->tasklet,
- esas2r_adapter_tasklet,
- (unsigned long)a);
+ tasklet_setup(&a->tasklet, esas2r_adapter_tasklet);
/*
* Disable chip interrupts to prevent spurious interrupts
diff --git a/drivers/scsi/esas2r/esas2r_main.c b/drivers/scsi/esas2r/esas2r_main.c
index 7b49e2e9fcde..7ffa9406ab4d 100644
--- a/drivers/scsi/esas2r/esas2r_main.c
+++ b/drivers/scsi/esas2r/esas2r_main.c
@@ -1546,9 +1546,9 @@ void esas2r_complete_request_cb(struct esas2r_adapter *a,
}
/* Run tasklet to handle stuff outside of interrupt context. */
-void esas2r_adapter_tasklet(unsigned long context)
+void esas2r_adapter_tasklet(struct tasklet_struct *t)
{
- struct esas2r_adapter *a = (struct esas2r_adapter *)context;
+ struct esas2r_adapter *a = from_tasklet(a, t, tasklet);
if (unlikely(test_bit(AF2_TIMER_TICK, &a->flags2))) {
clear_bit(AF2_TIMER_TICK, &a->flags2);
--
2.17.1
^ permalink raw reply related
* [PATCH 0/8] scsi: convert tasklets to use new tasklet_setup()
From: Allen Pais @ 2020-08-17 8:54 UTC (permalink / raw)
To: jejb, martin.petersen, kashyap.desai, sumit.saxena,
shivasharan.srikanteshwara
Cc: keescook, linux-scsi, linux-kernel, Allen Pais, target-devel,
linuxppc-dev, megaraidlinux.pdl
From: Allen Pais <allen.lkml@gmail.com>
Commit 12cc923f1ccc ("tasklet: Introduce new initialization API")'
introduced a new tasklet initialization API. This series converts
all the scsi drivers to use the new tasklet_setup() API
Allen Pais (8):
scsi: aic94xx: convert tasklets to use new tasklet_setup() API
scsi: esas2r: convert tasklets to use new tasklet_setup() API
scsi: ibmvscsi: convert tasklets to use new tasklet_setup() API
scsi: isci: convert tasklets to use new tasklet_setup() API
scsi: megaraid: convert tasklets to use new tasklet_setup() API
scsi: mvsas: convert tasklets to use new tasklet_setup() API
scsi: pm8001: convert tasklets to use new tasklet_setup() API
scsi: pmcraid: convert tasklets to use new tasklet_setup() API
drivers/scsi/aic94xx/aic94xx_hwi.c | 9 ++--
drivers/scsi/esas2r/esas2r.h | 2 +-
drivers/scsi/esas2r/esas2r_init.c | 4 +-
drivers/scsi/esas2r/esas2r_main.c | 4 +-
drivers/scsi/ibmvscsi/ibmvfc.c | 6 +--
drivers/scsi/ibmvscsi/ibmvscsi.c | 8 +--
drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c | 7 ++-
drivers/scsi/isci/host.c | 4 +-
drivers/scsi/isci/host.h | 2 +-
drivers/scsi/isci/init.c | 3 +-
drivers/scsi/megaraid/megaraid_mbox.c | 9 ++--
drivers/scsi/megaraid/megaraid_sas.h | 2 +-
drivers/scsi/megaraid/megaraid_sas_base.c | 16 +++---
drivers/scsi/megaraid/megaraid_sas_fusion.c | 14 +++---
drivers/scsi/mvsas/mv_init.c | 8 +--
drivers/scsi/pm8001/pm8001_init.c | 55 ++++++++++++---------
drivers/scsi/pm8001/pm8001_sas.h | 6 ++-
drivers/scsi/pmcraid.c | 29 +++++------
drivers/scsi/pmcraid.h | 9 +++-
19 files changed, 104 insertions(+), 93 deletions(-)
--
2.17.1
^ permalink raw reply
* [PATCH 1/8] scsi: aic94xx: convert tasklets to use new tasklet_setup() API
From: Allen Pais @ 2020-08-17 8:54 UTC (permalink / raw)
To: jejb, martin.petersen, kashyap.desai, sumit.saxena,
shivasharan.srikanteshwara
Cc: keescook, linux-scsi, linux-kernel, Allen Pais, target-devel,
Romain Perier, linuxppc-dev, megaraidlinux.pdl
In-Reply-To: <20200817085409.25268-1-allen.cryptic@gmail.com>
From: Allen Pais <allen.lkml@gmail.com>
In preparation for unconditionally passing the
struct tasklet_struct pointer to all tasklet
callbacks, switch to using the new tasklet_setup()
and from_tasklet() to pass the tasklet pointer explicitly.
Signed-off-by: Romain Perier <romain.perier@gmail.com>
Signed-off-by: Allen Pais <allen.lkml@gmail.com>
---
drivers/scsi/aic94xx/aic94xx_hwi.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/drivers/scsi/aic94xx/aic94xx_hwi.c b/drivers/scsi/aic94xx/aic94xx_hwi.c
index 9256ab7b2522..1e4d32246cb9 100644
--- a/drivers/scsi/aic94xx/aic94xx_hwi.c
+++ b/drivers/scsi/aic94xx/aic94xx_hwi.c
@@ -248,7 +248,7 @@ static void asd_get_max_scb_ddb(struct asd_ha_struct *asd_ha)
/* ---------- Done List initialization ---------- */
-static void asd_dl_tasklet_handler(unsigned long);
+static void asd_dl_tasklet_handler(struct tasklet_struct *t);
static int asd_init_dl(struct asd_ha_struct *asd_ha)
{
@@ -261,8 +261,7 @@ static int asd_init_dl(struct asd_ha_struct *asd_ha)
asd_ha->seq.dl = asd_ha->seq.actual_dl->vaddr;
asd_ha->seq.dl_toggle = ASD_DEF_DL_TOGGLE;
asd_ha->seq.dl_next = 0;
- tasklet_init(&asd_ha->seq.dl_tasklet, asd_dl_tasklet_handler,
- (unsigned long) asd_ha);
+ tasklet_setup(&asd_ha->seq.dl_tasklet, asd_dl_tasklet_handler);
return 0;
}
@@ -711,9 +710,9 @@ static void asd_chip_reset(struct asd_ha_struct *asd_ha)
/* ---------- Done List Routines ---------- */
-static void asd_dl_tasklet_handler(unsigned long data)
+static void asd_dl_tasklet_handler(struct tasklet_struct *t)
{
- struct asd_ha_struct *asd_ha = (struct asd_ha_struct *) data;
+ struct asd_ha_struct *asd_ha = from_tasklet(asd_ha, t, seq.dl_tasklet);
struct asd_seq_data *seq = &asd_ha->seq;
unsigned long flags;
--
2.17.1
^ permalink raw reply related
* Re: [PATCH v2 1/3] powerpc/numa: Introduce logical numa id
From: Srikar Dronamraju @ 2020-08-17 10:59 UTC (permalink / raw)
To: Aneesh Kumar K.V; +Cc: Nathan Lynch, linuxppc-dev
In-Reply-To: <20200817103238.158133-1-aneesh.kumar@linux.ibm.com>
* Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com> [2020-08-17 16:02:36]:
> We use ibm,associativity and ibm,associativity-lookup-arrays to derive the numa
> node numbers. These device tree properties are firmware indicated grouping of
> resources based on their hierarchy in the platform. These numbers (group id) are
> not sequential and hypervisor/firmware can follow different numbering schemes.
> For ex: on powernv platforms, we group them in the below order.
>
> * - CCM node ID
> * - HW card ID
> * - HW module ID
> * - Chip ID
> * - Core ID
>
> Based on ibm,associativity-reference-points we use one of the above group ids as
> Linux NUMA node id. (On PowerNV platform Chip ID is used). This results
> in Linux reporting non-linear NUMA node id and which also results in Linux
> reporting empty node 0 NUMA nodes.
>
> This can be resolved by mapping the firmware provided group id to a logical Linux
> NUMA id. In this patch, we do this only for pseries platforms considering the
> firmware group id is a virtualized entity and users would not have drawn any
> conclusion based on the Linux Numa Node id.
>
> On PowerNV platform since we have historically mapped Chip ID as Linux NUMA node
> id, we keep the existing Linux NUMA node id numbering.
I still dont understand how you are going to handle numa distances.
With your patch, have you tried dlpar add/remove on a sparsely noded machine?
--
Thanks and Regards
Srikar Dronamraju
^ permalink raw reply
* [PATCH] powerpc/pkeys: Fix build error with PPC_MEM_KEYS disabled
From: Aneesh Kumar K.V @ 2020-08-17 10:33 UTC (permalink / raw)
To: linuxppc-dev, mpe; +Cc: Aneesh Kumar K.V
IS_ENABLED() instead of #ifdef still requires variable declaration.
In this specific case, default_uamor is declared in asm/pkeys.h which
is only included if PPC_MEM_KEYS is enabled.
arch/powerpc/mm/book3s64/hash_utils.c: In function ‘hash__early_init_mmu_secondary’:
arch/powerpc/mm/book3s64/hash_utils.c:1119:21: error: ‘default_uamor’ undeclared (first use in this function)
1119 | mtspr(SPRN_UAMOR, default_uamor);
| ^~~~~~~~~~~~~
Fixes: 6553fb799f60 ("powerpc/pkeys: Fix boot failures with Nemo board (A-EON AmigaOne X1000)")
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
---
arch/powerpc/mm/book3s64/hash_utils.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/mm/book3s64/hash_utils.c b/arch/powerpc/mm/book3s64/hash_utils.c
index 1da9dbba9217..890a71c5293e 100644
--- a/arch/powerpc/mm/book3s64/hash_utils.c
+++ b/arch/powerpc/mm/book3s64/hash_utils.c
@@ -1115,8 +1115,10 @@ void hash__early_init_mmu_secondary(void)
&& cpu_has_feature(CPU_FTR_HVMODE))
tlbiel_all();
- if (IS_ENABLED(CONFIG_PPC_MEM_KEYS) && mmu_has_feature(MMU_FTR_PKEY))
+#ifdef CONFIG_PPC_MEM_KEYS
+ if (mmu_has_feature(MMU_FTR_PKEY))
mtspr(SPRN_UAMOR, default_uamor);
+#endif
}
#endif /* CONFIG_SMP */
--
2.26.2
^ permalink raw reply related
* [PATCH v2 3/3] powerpc/numa: Move POWER4 restriction to the helper
From: Aneesh Kumar K.V @ 2020-08-17 10:32 UTC (permalink / raw)
To: linuxppc-dev, mpe; +Cc: Nathan Lynch, Aneesh Kumar K.V, Srikar Dronamraju
In-Reply-To: <20200817103238.158133-1-aneesh.kumar@linux.ibm.com>
Even though the comment says POWER4 usage, I guess it applies to all
platforms since there is no PVR check there. This patch moves the check
to the helper.
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
---
arch/powerpc/mm/numa.c | 10 ++--------
1 file changed, 2 insertions(+), 8 deletions(-)
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index d29f60e15777..7319084345e1 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -250,7 +250,8 @@ int affinity_domain_to_nid(struct affinity_domain *domain)
if (!firmware_has_feature(FW_FEATURE_LPAR))
return domain_id;
- if (domain_id == -1)
+ /* POWER4 LPAR uses 0xffff as invalid node */
+ if (domain_id == -1 || domain_id == 0xffff)
return NUMA_NO_NODE;
nid = __affinity_domain_to_nid(domain_id, last_nid);
@@ -283,10 +284,6 @@ static int associativity_to_nid(const __be32 *associativity)
if (of_read_number(associativity, 1) >= min_common_depth)
domain.id = of_read_number(&associativity[min_common_depth], 1);
- /* POWER4 LPAR uses 0xffff as invalid node */
- if (domain.id == 0xffff)
- domain.id = -1;
-
nid = affinity_domain_to_nid(&domain);
if (nid > 0 &&
@@ -499,9 +496,6 @@ static int of_drconf_to_nid_single(struct drmem_lmb *lmb)
index = lmb->aa_index * aa.array_sz + min_common_depth - 1;
domain.id = of_read_number(&aa.arrays[index], 1);
- if (domain.id == 0xffff)
- domain.id = -1;
-
nid = affinity_domain_to_nid(&domain);
if (nid > 0) {
--
2.26.2
^ permalink raw reply related
* [PATCH v2 2/3] powerpc/powernv/cpufreq: Don't assume chip id is same as Linux node id
From: Aneesh Kumar K.V @ 2020-08-17 10:32 UTC (permalink / raw)
To: linuxppc-dev, mpe
Cc: Nathan Lynch, Aneesh Kumar K.V, Srikar Dronamraju,
Gautham R . Shenoy
In-Reply-To: <20200817103238.158133-1-aneesh.kumar@linux.ibm.com>
On PowerNV platforms we always have 1:1 mapping between chip ID and
firmware group id. Use the helper to convert firmware group id to
node id instead of directly using chip ID as Linux node id.
NOTE: This doesn't have any functional change. On PowerNV platforms
we continue to have 1:1 mapping between firmware group id and
Linux node id.
Reviewed-by: Gautham R. Shenoy <ego@linux.vnet.ibm.com>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
---
drivers/cpufreq/powernv-cpufreq.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/drivers/cpufreq/powernv-cpufreq.c b/drivers/cpufreq/powernv-cpufreq.c
index a9af15e994cc..d7e6eb8aaba1 100644
--- a/drivers/cpufreq/powernv-cpufreq.c
+++ b/drivers/cpufreq/powernv-cpufreq.c
@@ -27,6 +27,7 @@
#include <asm/reg.h>
#include <asm/smp.h> /* Required for cpu_sibling_mask() in UP configs */
#include <asm/opal.h>
+#include <asm/topology.h>
#include <linux/timer.h>
#define POWERNV_MAX_PSTATES_ORDER 8
@@ -1070,8 +1071,16 @@ static int init_chip_info(void)
}
for (i = 0; i < nr_chips; i++) {
+ struct affinity_domain domain;
+ unsigned int nid;
+
chips[i].id = chip[i];
- cpumask_copy(&chips[i].mask, cpumask_of_node(chip[i]));
+ /*
+ * On powervn platforms affinity domain id is same as chipd id.
+ */
+ domain.id = chip[i];
+ nid = affinity_domain_to_nid(&domain);
+ cpumask_copy(&chips[i].mask, cpumask_of_node(nid));
INIT_WORK(&chips[i].throttle, powernv_cpufreq_work_fn);
for_each_cpu(cpu, &chips[i].mask)
per_cpu(chip_info, cpu) = &chips[i];
--
2.26.2
^ permalink raw reply related
* [PATCH v2 1/3] powerpc/numa: Introduce logical numa id
From: Aneesh Kumar K.V @ 2020-08-17 10:32 UTC (permalink / raw)
To: linuxppc-dev, mpe; +Cc: Nathan Lynch, Aneesh Kumar K.V, Srikar Dronamraju
We use ibm,associativity and ibm,associativity-lookup-arrays to derive the numa
node numbers. These device tree properties are firmware indicated grouping of
resources based on their hierarchy in the platform. These numbers (group id) are
not sequential and hypervisor/firmware can follow different numbering schemes.
For ex: on powernv platforms, we group them in the below order.
* - CCM node ID
* - HW card ID
* - HW module ID
* - Chip ID
* - Core ID
Based on ibm,associativity-reference-points we use one of the above group ids as
Linux NUMA node id. (On PowerNV platform Chip ID is used). This results
in Linux reporting non-linear NUMA node id and which also results in Linux
reporting empty node 0 NUMA nodes.
This can be resolved by mapping the firmware provided group id to a logical Linux
NUMA id. In this patch, we do this only for pseries platforms considering the
firmware group id is a virtualized entity and users would not have drawn any
conclusion based on the Linux Numa Node id.
On PowerNV platform since we have historically mapped Chip ID as Linux NUMA node
id, we keep the existing Linux NUMA node id numbering.
Before Fix:
# numactl -H
available: 2 nodes (0-1)
node 0 cpus:
node 0 size: 0 MB
node 0 free: 0 MB
node 1 cpus: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
node 1 size: 50912 MB
node 1 free: 45248 MB
node distances:
node 0 1
0: 10 40
1: 40 10
after fix
# numactl -H
available: 1 nodes (0)
node 0 cpus: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
node 0 size: 50912 MB
node 0 free: 49724 MB
node distances:
node 0
0: 10
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
---
arch/powerpc/include/asm/topology.h | 5 ++
arch/powerpc/mm/numa.c | 74 ++++++++++++++++++++++++-----
2 files changed, 68 insertions(+), 11 deletions(-)
diff --git a/arch/powerpc/include/asm/topology.h b/arch/powerpc/include/asm/topology.h
index f0b6300e7dd3..7c18883cee9c 100644
--- a/arch/powerpc/include/asm/topology.h
+++ b/arch/powerpc/include/asm/topology.h
@@ -118,5 +118,10 @@ int get_physical_package_id(int cpu);
#endif
#endif
+struct affinity_domain {
+ int id;
+};
+
+int affinity_domain_to_nid(struct affinity_domain *domain);
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_TOPOLOGY_H */
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index 1f61fa2148b5..d29f60e15777 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -221,26 +221,76 @@ static void initialize_distance_lookup_table(int nid,
}
}
+
+static int domain_id_map[MAX_NUMNODES] = {[0 ... MAX_NUMNODES - 1] = -1 };
+
+static int __affinity_domain_to_nid(int domain_id, int max_nid)
+{
+ int i;
+
+ for (i = 0; i < max_nid; i++) {
+ if (domain_id_map[i] == domain_id)
+ return i;
+ }
+ return NUMA_NO_NODE;
+}
+
+int affinity_domain_to_nid(struct affinity_domain *domain)
+{
+ int nid, domain_id;
+ static int last_nid = 0;
+ static DEFINE_SPINLOCK(node_id_lock);
+
+ domain_id = domain->id;
+ /*
+ * For PowerNV we don't change the node id. This helps to avoid
+ * confusion w.r.t the expected node ids. On pseries, node numbers
+ * are virtualized. Hence do logical node id for pseries.
+ */
+ if (!firmware_has_feature(FW_FEATURE_LPAR))
+ return domain_id;
+
+ if (domain_id == -1)
+ return NUMA_NO_NODE;
+
+ nid = __affinity_domain_to_nid(domain_id, last_nid);
+ if (nid == NUMA_NO_NODE) {
+ spin_lock(&node_id_lock);
+ /* recheck with lock held */
+ nid = __affinity_domain_to_nid(domain_id, last_nid);
+ if (nid == NUMA_NO_NODE && last_nid < MAX_NUMNODES) {
+ nid = last_nid++;
+ domain_id_map[nid] = domain_id;
+ }
+ spin_unlock(&node_id_lock);
+ }
+
+ return nid;
+}
+
/*
* Returns nid in the range [0..nr_node_ids], or -1 if no useful NUMA
* info is found.
*/
static int associativity_to_nid(const __be32 *associativity)
{
+ struct affinity_domain domain = { .id = -1 };
int nid = NUMA_NO_NODE;
if (!numa_enabled)
goto out;
if (of_read_number(associativity, 1) >= min_common_depth)
- nid = of_read_number(&associativity[min_common_depth], 1);
+ domain.id = of_read_number(&associativity[min_common_depth], 1);
/* POWER4 LPAR uses 0xffff as invalid node */
- if (nid == 0xffff || nid >= nr_node_ids)
- nid = NUMA_NO_NODE;
+ if (domain.id == 0xffff)
+ domain.id = -1;
+
+ nid = affinity_domain_to_nid(&domain);
if (nid > 0 &&
- of_read_number(associativity, 1) >= distance_ref_points_depth) {
+ of_read_number(associativity, 1) >= distance_ref_points_depth) {
/*
* Skip the length field and send start of associativity array
*/
@@ -432,25 +482,27 @@ static int of_get_assoc_arrays(struct assoc_arrays *aa)
*/
static int of_drconf_to_nid_single(struct drmem_lmb *lmb)
{
+ struct affinity_domain domain;
struct assoc_arrays aa = { .arrays = NULL };
- int default_nid = NUMA_NO_NODE;
- int nid = default_nid;
+ int nid = NUMA_NO_NODE;
int rc, index;
if ((min_common_depth < 0) || !numa_enabled)
- return default_nid;
+ return NUMA_NO_NODE;
rc = of_get_assoc_arrays(&aa);
if (rc)
- return default_nid;
+ return NUMA_NO_NODE;
if (min_common_depth <= aa.array_sz &&
!(lmb->flags & DRCONF_MEM_AI_INVALID) && lmb->aa_index < aa.n_arrays) {
index = lmb->aa_index * aa.array_sz + min_common_depth - 1;
- nid = of_read_number(&aa.arrays[index], 1);
+ domain.id = of_read_number(&aa.arrays[index], 1);
- if (nid == 0xffff || nid >= nr_node_ids)
- nid = default_nid;
+ if (domain.id == 0xffff)
+ domain.id = -1;
+
+ nid = affinity_domain_to_nid(&domain);
if (nid > 0) {
index = lmb->aa_index * aa.array_sz;
--
2.26.2
^ permalink raw reply related
* [PATCH v4 6/6] powerpc/watchpoint/selftests: Tests for kernel accessing user memory
From: Ravi Bangoria @ 2020-08-17 10:23 UTC (permalink / raw)
To: mpe, christophe.leroy
Cc: ravi.bangoria, mikey, rogealve, linux-kernel, paulus, jniethe5,
pedromfc, naveen.n.rao, linuxppc-dev
In-Reply-To: <20200817102330.777537-1-ravi.bangoria@linux.ibm.com>
Introduce tests to cover simple scenarios where user is watching
memory which can be accessed by kernel as well. We also support
_MODE_EXACT with _SETHWDEBUG interface. Move those testcases out-
side of _BP_RANGE condition. This will help to test _MODE_EXACT
scenarios when CONFIG_HAVE_HW_BREAKPOINT is not set, eg:
$ ./ptrace-hwbreak
...
PTRACE_SET_DEBUGREG, Kernel Access Userspace, len: 8: Ok
PPC_PTRACE_SETHWDEBUG, MODE_EXACT, WO, len: 1: Ok
PPC_PTRACE_SETHWDEBUG, MODE_EXACT, RO, len: 1: Ok
PPC_PTRACE_SETHWDEBUG, MODE_EXACT, RW, len: 1: Ok
PPC_PTRACE_SETHWDEBUG, MODE_EXACT, Kernel Access Userspace, len: 1: Ok
success: ptrace-hwbreak
Suggested-by: Pedro Miraglia Franco de Carvalho <pedromfc@br.ibm.com>
Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
---
.../selftests/powerpc/ptrace/ptrace-hwbreak.c | 48 ++++++++++++++++++-
1 file changed, 46 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/powerpc/ptrace/ptrace-hwbreak.c b/tools/testing/selftests/powerpc/ptrace/ptrace-hwbreak.c
index fc477dfe86a2..2e0d86e0687e 100644
--- a/tools/testing/selftests/powerpc/ptrace/ptrace-hwbreak.c
+++ b/tools/testing/selftests/powerpc/ptrace/ptrace-hwbreak.c
@@ -20,6 +20,8 @@
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
+#include <sys/syscall.h>
+#include <linux/limits.h>
#include "ptrace.h"
#define SPRN_PVR 0x11F
@@ -44,6 +46,7 @@ struct gstruct {
};
static volatile struct gstruct gstruct __attribute__((aligned(512)));
+static volatile char cwd[PATH_MAX] __attribute__((aligned(8)));
static void get_dbginfo(pid_t child_pid, struct ppc_debug_info *dbginfo)
{
@@ -138,6 +141,9 @@ static void test_workload(void)
write_var(len);
}
+ /* PTRACE_SET_DEBUGREG, Kernel Access Userspace test */
+ syscall(__NR_getcwd, &cwd, PATH_MAX);
+
/* PPC_PTRACE_SETHWDEBUG, MODE_EXACT, WO test */
write_var(1);
@@ -150,6 +156,9 @@ static void test_workload(void)
else
read_var(1);
+ /* PPC_PTRACE_SETHWDEBUG, MODE_EXACT, Kernel Access Userspace test */
+ syscall(__NR_getcwd, &cwd, PATH_MAX);
+
/* PPC_PTRACE_SETHWDEBUG, MODE_RANGE, DW ALIGNED, WO test */
gstruct.a[rand() % A_LEN] = 'a';
@@ -293,6 +302,24 @@ static int test_set_debugreg(pid_t child_pid)
return 0;
}
+static int test_set_debugreg_kernel_userspace(pid_t child_pid)
+{
+ unsigned long wp_addr = (unsigned long)cwd;
+ char *name = "PTRACE_SET_DEBUGREG";
+
+ /* PTRACE_SET_DEBUGREG, Kernel Access Userspace test */
+ wp_addr &= ~0x7UL;
+ wp_addr |= (1Ul << DABR_READ_SHIFT);
+ wp_addr |= (1UL << DABR_WRITE_SHIFT);
+ wp_addr |= (1UL << DABR_TRANSLATION_SHIFT);
+ ptrace_set_debugreg(child_pid, wp_addr);
+ ptrace(PTRACE_CONT, child_pid, NULL, 0);
+ check_success(child_pid, name, "Kernel Access Userspace", wp_addr, 8);
+
+ ptrace_set_debugreg(child_pid, 0);
+ return 0;
+}
+
static void get_ppc_hw_breakpoint(struct ppc_hw_breakpoint *info, int type,
unsigned long addr, int len)
{
@@ -338,6 +365,22 @@ static void test_sethwdebug_exact(pid_t child_pid)
ptrace_delhwdebug(child_pid, wh);
}
+static void test_sethwdebug_exact_kernel_userspace(pid_t child_pid)
+{
+ struct ppc_hw_breakpoint info;
+ unsigned long wp_addr = (unsigned long)&cwd;
+ char *name = "PPC_PTRACE_SETHWDEBUG, MODE_EXACT";
+ int len = 1; /* hardcoded in kernel */
+ int wh;
+
+ /* PPC_PTRACE_SETHWDEBUG, MODE_EXACT, Kernel Access Userspace test */
+ get_ppc_hw_breakpoint(&info, PPC_BREAKPOINT_TRIGGER_WRITE, wp_addr, 0);
+ wh = ptrace_sethwdebug(child_pid, &info);
+ ptrace(PTRACE_CONT, child_pid, NULL, 0);
+ check_success(child_pid, name, "Kernel Access Userspace", wp_addr, len);
+ ptrace_delhwdebug(child_pid, wh);
+}
+
static void test_sethwdebug_range_aligned(pid_t child_pid)
{
struct ppc_hw_breakpoint info;
@@ -452,9 +495,10 @@ static void
run_tests(pid_t child_pid, struct ppc_debug_info *dbginfo, bool dawr)
{
test_set_debugreg(child_pid);
+ test_set_debugreg_kernel_userspace(child_pid);
+ test_sethwdebug_exact(child_pid);
+ test_sethwdebug_exact_kernel_userspace(child_pid);
if (dbginfo->features & PPC_DEBUG_FEATURE_DATA_BP_RANGE) {
- test_sethwdebug_exact(child_pid);
-
test_sethwdebug_range_aligned(child_pid);
if (dawr || is_8xx) {
test_sethwdebug_range_unaligned(child_pid);
--
2.26.2
^ permalink raw reply related
* [PATCH v4 5/6] powerpc/watchpoint/ptrace: Introduce PPC_DEBUG_FEATURE_DATA_BP_ARCH_31
From: Ravi Bangoria @ 2020-08-17 10:23 UTC (permalink / raw)
To: mpe, christophe.leroy
Cc: ravi.bangoria, mikey, rogealve, linux-kernel, paulus, jniethe5,
pedromfc, naveen.n.rao, linuxppc-dev
In-Reply-To: <20200817102330.777537-1-ravi.bangoria@linux.ibm.com>
PPC_DEBUG_FEATURE_DATA_BP_ARCH_31 can be used to determine whether
we are running on an ISA 3.1 compliant machine. Which is needed to
determine DAR behaviour, 512 byte boundary limit etc. This was
requested by Pedro Miraglia Franco de Carvalho for extending
watchpoint features in gdb. Note that availability of 2nd DAWR is
independent of this flag and should be checked using
ppc_debug_info->num_data_bps.
Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
---
Documentation/powerpc/ptrace.rst | 1 +
arch/powerpc/include/uapi/asm/ptrace.h | 1 +
arch/powerpc/kernel/ptrace/ptrace-noadv.c | 2 ++
3 files changed, 4 insertions(+)
diff --git a/Documentation/powerpc/ptrace.rst b/Documentation/powerpc/ptrace.rst
index 864d4b6dddd1..77725d69eb4a 100644
--- a/Documentation/powerpc/ptrace.rst
+++ b/Documentation/powerpc/ptrace.rst
@@ -46,6 +46,7 @@ features will have bits indicating whether there is support for::
#define PPC_DEBUG_FEATURE_DATA_BP_RANGE 0x4
#define PPC_DEBUG_FEATURE_DATA_BP_MASK 0x8
#define PPC_DEBUG_FEATURE_DATA_BP_DAWR 0x10
+ #define PPC_DEBUG_FEATURE_DATA_BP_ARCH_31 0x20
2. PTRACE_SETHWDEBUG
diff --git a/arch/powerpc/include/uapi/asm/ptrace.h b/arch/powerpc/include/uapi/asm/ptrace.h
index f5f1ccc740fc..7004cfea3f5f 100644
--- a/arch/powerpc/include/uapi/asm/ptrace.h
+++ b/arch/powerpc/include/uapi/asm/ptrace.h
@@ -222,6 +222,7 @@ struct ppc_debug_info {
#define PPC_DEBUG_FEATURE_DATA_BP_RANGE 0x0000000000000004
#define PPC_DEBUG_FEATURE_DATA_BP_MASK 0x0000000000000008
#define PPC_DEBUG_FEATURE_DATA_BP_DAWR 0x0000000000000010
+#define PPC_DEBUG_FEATURE_DATA_BP_ARCH_31 0x0000000000000020
#ifndef __ASSEMBLY__
diff --git a/arch/powerpc/kernel/ptrace/ptrace-noadv.c b/arch/powerpc/kernel/ptrace/ptrace-noadv.c
index 081c39842d84..1d0235db3c1b 100644
--- a/arch/powerpc/kernel/ptrace/ptrace-noadv.c
+++ b/arch/powerpc/kernel/ptrace/ptrace-noadv.c
@@ -57,6 +57,8 @@ void ppc_gethwdinfo(struct ppc_debug_info *dbginfo)
} else {
dbginfo->features = 0;
}
+ if (cpu_has_feature(CPU_FTR_ARCH_31))
+ dbginfo->features |= PPC_DEBUG_FEATURE_DATA_BP_ARCH_31;
}
int ptrace_get_debugreg(struct task_struct *child, unsigned long addr,
--
2.26.2
^ permalink raw reply related
* [PATCH v4 4/6] powerpc/watchpoint: Add hw_len wherever missing
From: Ravi Bangoria @ 2020-08-17 10:23 UTC (permalink / raw)
To: mpe, christophe.leroy
Cc: ravi.bangoria, mikey, rogealve, linux-kernel, paulus, jniethe5,
pedromfc, naveen.n.rao, linuxppc-dev
In-Reply-To: <20200817102330.777537-1-ravi.bangoria@linux.ibm.com>
There are couple of places where we set len but not hw_len. For
ptrace/perf watchpoints, when CONFIG_HAVE_HW_BREAKPOINT=Y, hw_len
will be calculated and set internally while parsing watchpoint.
But when CONFIG_HAVE_HW_BREAKPOINT=N, we need to manually set
'hw_len'. Similarly for xmon as well, hw_len needs to be set
directly.
Fixes: b57aeab811db ("powerpc/watchpoint: Fix length calculation for unaligned target")
Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
---
arch/powerpc/kernel/ptrace/ptrace-noadv.c | 1 +
arch/powerpc/xmon/xmon.c | 1 +
2 files changed, 2 insertions(+)
diff --git a/arch/powerpc/kernel/ptrace/ptrace-noadv.c b/arch/powerpc/kernel/ptrace/ptrace-noadv.c
index 866597b407bc..081c39842d84 100644
--- a/arch/powerpc/kernel/ptrace/ptrace-noadv.c
+++ b/arch/powerpc/kernel/ptrace/ptrace-noadv.c
@@ -219,6 +219,7 @@ long ppc_set_hwdebug(struct task_struct *child, struct ppc_hw_breakpoint *bp_inf
brk.address = ALIGN_DOWN(bp_info->addr, HW_BREAKPOINT_SIZE);
brk.type = HW_BRK_TYPE_TRANSLATE | HW_BRK_TYPE_PRIV_ALL;
brk.len = DABR_MAX_LEN;
+ brk.hw_len = DABR_MAX_LEN;
if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_READ)
brk.type |= HW_BRK_TYPE_READ;
if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE)
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index df7bca00f5ec..55c43a6c9111 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -969,6 +969,7 @@ static void insert_cpu_bpts(void)
brk.address = dabr[i].address;
brk.type = (dabr[i].enabled & HW_BRK_TYPE_DABR) | HW_BRK_TYPE_PRIV_ALL;
brk.len = 8;
+ brk.hw_len = 8;
__set_breakpoint(i, &brk);
}
}
--
2.26.2
^ permalink raw reply related
* [PATCH v4 3/6] powerpc/watchpoint: Fix exception handling for CONFIG_HAVE_HW_BREAKPOINT=N
From: Ravi Bangoria @ 2020-08-17 10:23 UTC (permalink / raw)
To: mpe, christophe.leroy
Cc: ravi.bangoria, mikey, rogealve, linux-kernel, paulus, jniethe5,
pedromfc, naveen.n.rao, linuxppc-dev
In-Reply-To: <20200817102330.777537-1-ravi.bangoria@linux.ibm.com>
On powerpc, ptrace watchpoint works in one-shot mode. i.e. kernel
disables event every time it fires and user has to re-enable it.
Also, in case of ptrace watchpoint, kernel notifies ptrace user
before executing instruction.
With CONFIG_HAVE_HW_BREAKPOINT=N, kernel is missing to disable
ptrace event and thus it's causing infinite loop of exceptions.
This is especially harmful when user watches on a data which is
also read/written by kernel, eg syscall parameters. In such case,
infinite exceptions happens in kernel mode which causes soft-lockup.
Fixes: 9422de3e953d ("powerpc: Hardware breakpoints rewrite to handle non DABR breakpoint registers")
Reported-by: Pedro Miraglia Franco de Carvalho <pedromfc@br.ibm.com>
Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
---
arch/powerpc/include/asm/hw_breakpoint.h | 3 ++
arch/powerpc/kernel/process.c | 48 +++++++++++++++++++++++
arch/powerpc/kernel/ptrace/ptrace-noadv.c | 5 +++
3 files changed, 56 insertions(+)
diff --git a/arch/powerpc/include/asm/hw_breakpoint.h b/arch/powerpc/include/asm/hw_breakpoint.h
index f71f08a7e2e0..90d5b3a9f433 100644
--- a/arch/powerpc/include/asm/hw_breakpoint.h
+++ b/arch/powerpc/include/asm/hw_breakpoint.h
@@ -18,6 +18,7 @@ struct arch_hw_breakpoint {
u16 type;
u16 len; /* length of the target data symbol */
u16 hw_len; /* length programmed in hw */
+ u8 flags;
};
/* Note: Don't change the first 6 bits below as they are in the same order
@@ -37,6 +38,8 @@ struct arch_hw_breakpoint {
#define HW_BRK_TYPE_PRIV_ALL (HW_BRK_TYPE_USER | HW_BRK_TYPE_KERNEL | \
HW_BRK_TYPE_HYP)
+#define HW_BRK_FLAG_DISABLED 0x1
+
/* Minimum granularity */
#ifdef CONFIG_PPC_8xx
#define HW_BREAKPOINT_SIZE 0x4
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index e4fcc817c46c..cab6febe6eb6 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -636,6 +636,44 @@ void do_send_trap(struct pt_regs *regs, unsigned long address,
(void __user *)address);
}
#else /* !CONFIG_PPC_ADV_DEBUG_REGS */
+
+static void do_break_handler(struct pt_regs *regs)
+{
+ struct arch_hw_breakpoint null_brk = {0};
+ struct arch_hw_breakpoint *info;
+ struct ppc_inst instr = ppc_inst(0);
+ int type = 0;
+ int size = 0;
+ unsigned long ea;
+ int i;
+
+ /*
+ * If underneath hw supports only one watchpoint, we know it
+ * caused exception. 8xx also falls into this category.
+ */
+ if (nr_wp_slots() == 1) {
+ __set_breakpoint(0, &null_brk);
+ current->thread.hw_brk[0] = null_brk;
+ current->thread.hw_brk[0].flags |= HW_BRK_FLAG_DISABLED;
+ return;
+ }
+
+ /* Otherwise findout which DAWR caused exception and disable it. */
+ wp_get_instr_detail(regs, &instr, &type, &size, &ea);
+
+ for (i = 0; i < nr_wp_slots(); i++) {
+ info = ¤t->thread.hw_brk[i];
+ if (!info->address)
+ continue;
+
+ if (wp_check_constraints(regs, instr, ea, type, size, info)) {
+ __set_breakpoint(i, &null_brk);
+ current->thread.hw_brk[i] = null_brk;
+ current->thread.hw_brk[i].flags |= HW_BRK_FLAG_DISABLED;
+ }
+ }
+}
+
void do_break (struct pt_regs *regs, unsigned long address,
unsigned long error_code)
{
@@ -647,6 +685,16 @@ void do_break (struct pt_regs *regs, unsigned long address,
if (debugger_break_match(regs))
return;
+ /*
+ * We reach here only when watchpoint exception is generated by ptrace
+ * event (or hw is buggy!). Now if CONFIG_HAVE_HW_BREAKPOINT is set,
+ * watchpoint is already handled by hw_breakpoint_handler() so we don't
+ * have to do anything. But when CONFIG_HAVE_HW_BREAKPOINT is not set,
+ * we need to manually handle the watchpoint here.
+ */
+ if (!IS_ENABLED(CONFIG_HAVE_HW_BREAKPOINT))
+ do_break_handler(regs);
+
/* Deliver the signal to userspace */
force_sig_fault(SIGTRAP, TRAP_HWBKPT, (void __user *)address);
}
diff --git a/arch/powerpc/kernel/ptrace/ptrace-noadv.c b/arch/powerpc/kernel/ptrace/ptrace-noadv.c
index 57a0ab822334..866597b407bc 100644
--- a/arch/powerpc/kernel/ptrace/ptrace-noadv.c
+++ b/arch/powerpc/kernel/ptrace/ptrace-noadv.c
@@ -286,11 +286,16 @@ long ppc_del_hwdebug(struct task_struct *child, long data)
}
return ret;
#else /* CONFIG_HAVE_HW_BREAKPOINT */
+ if (child->thread.hw_brk[data - 1].flags & HW_BRK_FLAG_DISABLED)
+ goto del;
+
if (child->thread.hw_brk[data - 1].address == 0)
return -ENOENT;
+del:
child->thread.hw_brk[data - 1].address = 0;
child->thread.hw_brk[data - 1].type = 0;
+ child->thread.hw_brk[data - 1].flags = 0;
#endif /* CONFIG_HAVE_HW_BREAKPOINT */
return 0;
--
2.26.2
^ permalink raw reply related
* [PATCH v4 1/6] powerpc/watchpoint/ptrace: Fix SETHWDEBUG when CONFIG_HAVE_HW_BREAKPOINT=N
From: Ravi Bangoria @ 2020-08-17 10:23 UTC (permalink / raw)
To: mpe, christophe.leroy
Cc: ravi.bangoria, mikey, rogealve, linux-kernel, paulus, jniethe5,
pedromfc, naveen.n.rao, linuxppc-dev
In-Reply-To: <20200817102330.777537-1-ravi.bangoria@linux.ibm.com>
When kernel is compiled with CONFIG_HAVE_HW_BREAKPOINT=N, user can
still create watchpoint using PPC_PTRACE_SETHWDEBUG, with limited
functionalities. But, such watchpoints are never firing because of
the missing privilege settings. Fix that.
It's safe to set HW_BRK_TYPE_PRIV_ALL because we don't really leak
any kernel address in signal info. Setting HW_BRK_TYPE_PRIV_ALL will
also help to find scenarios when kernel corrupts user memory.
Reported-by: Pedro Miraglia Franco de Carvalho <pedromfc@br.ibm.com>
Suggested-by: Pedro Miraglia Franco de Carvalho <pedromfc@br.ibm.com>
Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
---
arch/powerpc/kernel/ptrace/ptrace-noadv.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/kernel/ptrace/ptrace-noadv.c b/arch/powerpc/kernel/ptrace/ptrace-noadv.c
index 697c7e4b5877..57a0ab822334 100644
--- a/arch/powerpc/kernel/ptrace/ptrace-noadv.c
+++ b/arch/powerpc/kernel/ptrace/ptrace-noadv.c
@@ -217,7 +217,7 @@ long ppc_set_hwdebug(struct task_struct *child, struct ppc_hw_breakpoint *bp_inf
return -EIO;
brk.address = ALIGN_DOWN(bp_info->addr, HW_BREAKPOINT_SIZE);
- brk.type = HW_BRK_TYPE_TRANSLATE;
+ brk.type = HW_BRK_TYPE_TRANSLATE | HW_BRK_TYPE_PRIV_ALL;
brk.len = DABR_MAX_LEN;
if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_READ)
brk.type |= HW_BRK_TYPE_READ;
--
2.26.2
^ permalink raw reply related
* [PATCH v4 2/6] powerpc/watchpoint: Move DAWR detection logic outside of hw_breakpoint.c
From: Ravi Bangoria @ 2020-08-17 10:23 UTC (permalink / raw)
To: mpe, christophe.leroy
Cc: ravi.bangoria, mikey, rogealve, linux-kernel, paulus, jniethe5,
pedromfc, naveen.n.rao, linuxppc-dev
In-Reply-To: <20200817102330.777537-1-ravi.bangoria@linux.ibm.com>
Power10 hw has multiple DAWRs but hw doesn't tell which DAWR caused
the exception. So we have a sw logic to detect that in hw_breakpoint.c.
But hw_breakpoint.c gets compiled only with CONFIG_HAVE_HW_BREAKPOINT=Y.
Move DAWR detection logic outside of hw_breakpoint.c so that it can be
reused when CONFIG_HAVE_HW_BREAKPOINT is not set.
Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.ibm.com>
---
arch/powerpc/include/asm/hw_breakpoint.h | 8 +
arch/powerpc/kernel/Makefile | 3 +-
arch/powerpc/kernel/hw_breakpoint.c | 149 +----------------
.../kernel/hw_breakpoint_constraints.c | 152 ++++++++++++++++++
4 files changed, 164 insertions(+), 148 deletions(-)
create mode 100644 arch/powerpc/kernel/hw_breakpoint_constraints.c
diff --git a/arch/powerpc/include/asm/hw_breakpoint.h b/arch/powerpc/include/asm/hw_breakpoint.h
index db206a7f38e2..f71f08a7e2e0 100644
--- a/arch/powerpc/include/asm/hw_breakpoint.h
+++ b/arch/powerpc/include/asm/hw_breakpoint.h
@@ -10,6 +10,7 @@
#define _PPC_BOOK3S_64_HW_BREAKPOINT_H
#include <asm/cpu_has_feature.h>
+#include <asm/inst.h>
#ifdef __KERNEL__
struct arch_hw_breakpoint {
@@ -51,6 +52,13 @@ static inline int nr_wp_slots(void)
return cpu_has_feature(CPU_FTR_DAWR1) ? 2 : 1;
}
+bool wp_check_constraints(struct pt_regs *regs, struct ppc_inst instr,
+ unsigned long ea, int type, int size,
+ struct arch_hw_breakpoint *info);
+
+void wp_get_instr_detail(struct pt_regs *regs, struct ppc_inst *instr,
+ int *type, int *size, unsigned long *ea);
+
#ifdef CONFIG_HAVE_HW_BREAKPOINT
#include <linux/kdebug.h>
#include <asm/reg.h>
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index d4d5946224f8..286f85a103de 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -45,7 +45,8 @@ obj-y := cputable.o syscalls.o \
signal.o sysfs.o cacheinfo.o time.o \
prom.o traps.o setup-common.o \
udbg.o misc.o io.o misc_$(BITS).o \
- of_platform.o prom_parse.o firmware.o
+ of_platform.o prom_parse.o firmware.o \
+ hw_breakpoint_constraints.o
obj-y += ptrace/
obj-$(CONFIG_PPC64) += setup_64.o \
paca.o nvram_64.o note.o syscall_64.o
diff --git a/arch/powerpc/kernel/hw_breakpoint.c b/arch/powerpc/kernel/hw_breakpoint.c
index 1f4a1efa0074..f4e8f21046f5 100644
--- a/arch/powerpc/kernel/hw_breakpoint.c
+++ b/arch/powerpc/kernel/hw_breakpoint.c
@@ -494,151 +494,6 @@ void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs)
}
}
-static bool dar_in_user_range(unsigned long dar, struct arch_hw_breakpoint *info)
-{
- return ((info->address <= dar) && (dar - info->address < info->len));
-}
-
-static bool ea_user_range_overlaps(unsigned long ea, int size,
- struct arch_hw_breakpoint *info)
-{
- return ((ea < info->address + info->len) &&
- (ea + size > info->address));
-}
-
-static bool dar_in_hw_range(unsigned long dar, struct arch_hw_breakpoint *info)
-{
- unsigned long hw_start_addr, hw_end_addr;
-
- hw_start_addr = ALIGN_DOWN(info->address, HW_BREAKPOINT_SIZE);
- hw_end_addr = ALIGN(info->address + info->len, HW_BREAKPOINT_SIZE);
-
- return ((hw_start_addr <= dar) && (hw_end_addr > dar));
-}
-
-static bool ea_hw_range_overlaps(unsigned long ea, int size,
- struct arch_hw_breakpoint *info)
-{
- unsigned long hw_start_addr, hw_end_addr;
-
- hw_start_addr = ALIGN_DOWN(info->address, HW_BREAKPOINT_SIZE);
- hw_end_addr = ALIGN(info->address + info->len, HW_BREAKPOINT_SIZE);
-
- return ((ea < hw_end_addr) && (ea + size > hw_start_addr));
-}
-
-/*
- * If hw has multiple DAWR registers, we also need to check all
- * dawrx constraint bits to confirm this is _really_ a valid event.
- * If type is UNKNOWN, but privilege level matches, consider it as
- * a positive match.
- */
-static bool check_dawrx_constraints(struct pt_regs *regs, int type,
- struct arch_hw_breakpoint *info)
-{
- if (OP_IS_LOAD(type) && !(info->type & HW_BRK_TYPE_READ))
- return false;
-
- /*
- * The Cache Management instructions other than dcbz never
- * cause a match. i.e. if type is CACHEOP, the instruction
- * is dcbz, and dcbz is treated as Store.
- */
- if ((OP_IS_STORE(type) || type == CACHEOP) && !(info->type & HW_BRK_TYPE_WRITE))
- return false;
-
- if (is_kernel_addr(regs->nip) && !(info->type & HW_BRK_TYPE_KERNEL))
- return false;
-
- if (user_mode(regs) && !(info->type & HW_BRK_TYPE_USER))
- return false;
-
- return true;
-}
-
-/*
- * Return true if the event is valid wrt dawr configuration,
- * including extraneous exception. Otherwise return false.
- */
-static bool check_constraints(struct pt_regs *regs, struct ppc_inst instr,
- unsigned long ea, int type, int size,
- struct arch_hw_breakpoint *info)
-{
- bool in_user_range = dar_in_user_range(regs->dar, info);
- bool dawrx_constraints;
-
- /*
- * 8xx supports only one breakpoint and thus we can
- * unconditionally return true.
- */
- if (IS_ENABLED(CONFIG_PPC_8xx)) {
- if (!in_user_range)
- info->type |= HW_BRK_TYPE_EXTRANEOUS_IRQ;
- return true;
- }
-
- if (unlikely(ppc_inst_equal(instr, ppc_inst(0)))) {
- if (cpu_has_feature(CPU_FTR_ARCH_31) &&
- !dar_in_hw_range(regs->dar, info))
- return false;
-
- return true;
- }
-
- dawrx_constraints = check_dawrx_constraints(regs, type, info);
-
- if (type == UNKNOWN) {
- if (cpu_has_feature(CPU_FTR_ARCH_31) &&
- !dar_in_hw_range(regs->dar, info))
- return false;
-
- return dawrx_constraints;
- }
-
- if (ea_user_range_overlaps(ea, size, info))
- return dawrx_constraints;
-
- if (ea_hw_range_overlaps(ea, size, info)) {
- if (dawrx_constraints) {
- info->type |= HW_BRK_TYPE_EXTRANEOUS_IRQ;
- return true;
- }
- }
- return false;
-}
-
-static int cache_op_size(void)
-{
-#ifdef __powerpc64__
- return ppc64_caches.l1d.block_size;
-#else
- return L1_CACHE_BYTES;
-#endif
-}
-
-static void get_instr_detail(struct pt_regs *regs, struct ppc_inst *instr,
- int *type, int *size, unsigned long *ea)
-{
- struct instruction_op op;
-
- if (__get_user_instr_inatomic(*instr, (void __user *)regs->nip))
- return;
-
- analyse_instr(&op, regs, *instr);
- *type = GETTYPE(op.type);
- *ea = op.ea;
-#ifdef __powerpc64__
- if (!(regs->msr & MSR_64BIT))
- *ea &= 0xffffffffUL;
-#endif
-
- *size = GETSIZE(op.type);
- if (*type == CACHEOP) {
- *size = cache_op_size();
- *ea &= ~(*size - 1);
- }
-}
-
static bool is_larx_stcx_instr(int type)
{
return type == LARX || type == STCX;
@@ -722,7 +577,7 @@ int hw_breakpoint_handler(struct die_args *args)
rcu_read_lock();
if (!IS_ENABLED(CONFIG_PPC_8xx))
- get_instr_detail(regs, &instr, &type, &size, &ea);
+ wp_get_instr_detail(regs, &instr, &type, &size, &ea);
for (i = 0; i < nr_wp_slots(); i++) {
bp[i] = __this_cpu_read(bp_per_reg[i]);
@@ -732,7 +587,7 @@ int hw_breakpoint_handler(struct die_args *args)
info[i] = counter_arch_bp(bp[i]);
info[i]->type &= ~HW_BRK_TYPE_EXTRANEOUS_IRQ;
- if (check_constraints(regs, instr, ea, type, size, info[i])) {
+ if (wp_check_constraints(regs, instr, ea, type, size, info[i])) {
if (!IS_ENABLED(CONFIG_PPC_8xx) &&
ppc_inst_equal(instr, ppc_inst(0))) {
handler_error(bp[i], info[i]);
diff --git a/arch/powerpc/kernel/hw_breakpoint_constraints.c b/arch/powerpc/kernel/hw_breakpoint_constraints.c
new file mode 100644
index 000000000000..a4f13026d2e0
--- /dev/null
+++ b/arch/powerpc/kernel/hw_breakpoint_constraints.c
@@ -0,0 +1,152 @@
+// SPDX-License-Identifier: GPL-2.0+
+#include <linux/kernel.h>
+#include <linux/uaccess.h>
+#include <linux/sched.h>
+#include <asm/hw_breakpoint.h>
+#include <asm/sstep.h>
+#include <asm/cache.h>
+
+static bool dar_in_user_range(unsigned long dar, struct arch_hw_breakpoint *info)
+{
+ return ((info->address <= dar) && (dar - info->address < info->len));
+}
+
+static bool ea_user_range_overlaps(unsigned long ea, int size,
+ struct arch_hw_breakpoint *info)
+{
+ return ((ea < info->address + info->len) &&
+ (ea + size > info->address));
+}
+
+static bool dar_in_hw_range(unsigned long dar, struct arch_hw_breakpoint *info)
+{
+ unsigned long hw_start_addr, hw_end_addr;
+
+ hw_start_addr = ALIGN_DOWN(info->address, HW_BREAKPOINT_SIZE);
+ hw_end_addr = ALIGN(info->address + info->len, HW_BREAKPOINT_SIZE);
+
+ return ((hw_start_addr <= dar) && (hw_end_addr > dar));
+}
+
+static bool ea_hw_range_overlaps(unsigned long ea, int size,
+ struct arch_hw_breakpoint *info)
+{
+ unsigned long hw_start_addr, hw_end_addr;
+
+ hw_start_addr = ALIGN_DOWN(info->address, HW_BREAKPOINT_SIZE);
+ hw_end_addr = ALIGN(info->address + info->len, HW_BREAKPOINT_SIZE);
+
+ return ((ea < hw_end_addr) && (ea + size > hw_start_addr));
+}
+
+/*
+ * If hw has multiple DAWR registers, we also need to check all
+ * dawrx constraint bits to confirm this is _really_ a valid event.
+ * If type is UNKNOWN, but privilege level matches, consider it as
+ * a positive match.
+ */
+static bool check_dawrx_constraints(struct pt_regs *regs, int type,
+ struct arch_hw_breakpoint *info)
+{
+ if (OP_IS_LOAD(type) && !(info->type & HW_BRK_TYPE_READ))
+ return false;
+
+ /*
+ * The Cache Management instructions other than dcbz never
+ * cause a match. i.e. if type is CACHEOP, the instruction
+ * is dcbz, and dcbz is treated as Store.
+ */
+ if ((OP_IS_STORE(type) || type == CACHEOP) && !(info->type & HW_BRK_TYPE_WRITE))
+ return false;
+
+ if (is_kernel_addr(regs->nip) && !(info->type & HW_BRK_TYPE_KERNEL))
+ return false;
+
+ if (user_mode(regs) && !(info->type & HW_BRK_TYPE_USER))
+ return false;
+
+ return true;
+}
+
+/*
+ * Return true if the event is valid wrt dawr configuration,
+ * including extraneous exception. Otherwise return false.
+ */
+bool wp_check_constraints(struct pt_regs *regs, struct ppc_inst instr,
+ unsigned long ea, int type, int size,
+ struct arch_hw_breakpoint *info)
+{
+ bool in_user_range = dar_in_user_range(regs->dar, info);
+ bool dawrx_constraints;
+
+ /*
+ * 8xx supports only one breakpoint and thus we can
+ * unconditionally return true.
+ */
+ if (IS_ENABLED(CONFIG_PPC_8xx)) {
+ if (!in_user_range)
+ info->type |= HW_BRK_TYPE_EXTRANEOUS_IRQ;
+ return true;
+ }
+
+ if (unlikely(ppc_inst_equal(instr, ppc_inst(0)))) {
+ if (cpu_has_feature(CPU_FTR_ARCH_31) &&
+ !dar_in_hw_range(regs->dar, info))
+ return false;
+
+ return true;
+ }
+
+ dawrx_constraints = check_dawrx_constraints(regs, type, info);
+
+ if (type == UNKNOWN) {
+ if (cpu_has_feature(CPU_FTR_ARCH_31) &&
+ !dar_in_hw_range(regs->dar, info))
+ return false;
+
+ return dawrx_constraints;
+ }
+
+ if (ea_user_range_overlaps(ea, size, info))
+ return dawrx_constraints;
+
+ if (ea_hw_range_overlaps(ea, size, info)) {
+ if (dawrx_constraints) {
+ info->type |= HW_BRK_TYPE_EXTRANEOUS_IRQ;
+ return true;
+ }
+ }
+ return false;
+}
+
+static int cache_op_size(void)
+{
+#ifdef __powerpc64__
+ return ppc64_caches.l1d.block_size;
+#else
+ return L1_CACHE_BYTES;
+#endif
+}
+
+void wp_get_instr_detail(struct pt_regs *regs, struct ppc_inst *instr,
+ int *type, int *size, unsigned long *ea)
+{
+ struct instruction_op op;
+
+ if (__get_user_instr_inatomic(*instr, (void __user *)regs->nip))
+ return;
+
+ analyse_instr(&op, regs, *instr);
+ *type = GETTYPE(op.type);
+ *ea = op.ea;
+#ifdef __powerpc64__
+ if (!(regs->msr & MSR_64BIT))
+ *ea &= 0xffffffffUL;
+#endif
+
+ *size = GETSIZE(op.type);
+ if (*type == CACHEOP) {
+ *size = cache_op_size();
+ *ea &= ~(*size - 1);
+ }
+}
--
2.26.2
^ permalink raw reply related
* [PATCH v4 0/6] powerpc/watchpoint: Bug fixes plus new feature flag
From: Ravi Bangoria @ 2020-08-17 10:23 UTC (permalink / raw)
To: mpe, christophe.leroy
Cc: ravi.bangoria, mikey, rogealve, linux-kernel, paulus, jniethe5,
pedromfc, naveen.n.rao, linuxppc-dev
Patch #1 fixes a bug about watchpoint not firing when created with
ptrace PPC_PTRACE_SETHWDEBUG and CONFIG_HAVE_HW_BREAKPOINT=N.
The fix uses HW_BRK_TYPE_PRIV_ALL for ptrace user which, I
guess, should be fine because we don't leak any kernel
addresses and PRIV_ALL will also help to cover scenarios when
kernel accesses user memory.
Patch #2,#3 fixes infinite exception bug, again the bug happens only
with CONFIG_HAVE_HW_BREAKPOINT=N.
Patch #4 fixes two places where we are missing to set hw_len.
Patch #5 introduce new feature bit PPC_DEBUG_FEATURE_DATA_BP_ARCH_31
which will be set when running on ISA 3.1 compliant machine.
Patch #6 finally adds selftest to test scenarios fixed by patch#2,#3
and also moves MODE_EXACT tests outside of BP_RANGE condition.
Christophe, let me know if this series breaks something for 8xx.
v3: https://lore.kernel.org/r/20200805062750.290289-1-ravi.bangoria@linux.ibm.com
v3->v4:
- Patch #1. Allow HW_BRK_TYPE_PRIV_ALL instead of HW_BRK_TYPE_USER
- Patch #2, #3, #4 and #6 are new.
- Rebased to powerpc/next.
Ravi Bangoria (6):
powerpc/watchpoint/ptrace: Fix SETHWDEBUG when
CONFIG_HAVE_HW_BREAKPOINT=N
powerpc/watchpoint: Move DAWR detection logic outside of
hw_breakpoint.c
powerpc/watchpoint: Fix exception handling for
CONFIG_HAVE_HW_BREAKPOINT=N
powerpc/watchpoint: Add hw_len wherever missing
powerpc/watchpoint/ptrace: Introduce PPC_DEBUG_FEATURE_DATA_BP_ARCH_31
powerpc/watchpoint/selftests: Tests for kernel accessing user memory
Documentation/powerpc/ptrace.rst | 1 +
arch/powerpc/include/asm/hw_breakpoint.h | 11 ++
arch/powerpc/include/uapi/asm/ptrace.h | 1 +
arch/powerpc/kernel/Makefile | 3 +-
arch/powerpc/kernel/hw_breakpoint.c | 149 +----------------
.../kernel/hw_breakpoint_constraints.c | 152 ++++++++++++++++++
arch/powerpc/kernel/process.c | 48 ++++++
arch/powerpc/kernel/ptrace/ptrace-noadv.c | 10 +-
arch/powerpc/xmon/xmon.c | 1 +
.../selftests/powerpc/ptrace/ptrace-hwbreak.c | 48 +++++-
10 files changed, 273 insertions(+), 151 deletions(-)
create mode 100644 arch/powerpc/kernel/hw_breakpoint_constraints.c
--
2.26.2
^ permalink raw reply
* Re: [PATCH] swiotlb: Allow allocating buffer anywhere in memory
From: Christoph Hellwig @ 2020-08-17 10:20 UTC (permalink / raw)
To: Thiago Jung Bauermann
Cc: Konrad Rzeszutek Wilk, Robin Murphy, Ram Pai, linux-kernel, iommu,
Satheesh Rajendran, linuxppc-dev, Christoph Hellwig,
Mike Rapoport, Marek Szyprowski
In-Reply-To: <20200815204536.663801-1-bauerman@linux.ibm.com>
On Sat, Aug 15, 2020 at 05:45:36PM -0300, Thiago Jung Bauermann wrote:
> POWER secure guests (i.e., guests which use the Protection Execution
> Facility) need to use SWIOTLB to be able to do I/O with the hypervisor, but
> they don't need the SWIOTLB memory to be in low addresses since the
> hypervisor doesn't have any addressing limitation.
>
> This solves a SWIOTLB initialization problem we are seeing in secure guests
> with 128 GB of RAM: they are configured with 4 GB of crashkernel reserved
> memory, which leaves no space for SWIOTLB in low addresses.
What about just open coding the allocation and using
swiotlb_init_with_tbl?
>
> Signed-off-by: Thiago Jung Bauermann <bauerman@linux.ibm.com>
> ---
> arch/powerpc/mm/mem.c | 7 ++++++-
> include/linux/swiotlb.h | 8 +++++++-
> kernel/dma/swiotlb.c | 10 +++++++---
> 3 files changed, 20 insertions(+), 5 deletions(-)
>
> Normally I would split changes like this into one patch touching generic
> code and another for the arch-specific part, but in this case I thought it
> would be unneeded complexity. I can split though if people prefer it that
> way.
>
> diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
> index c2c11eb8dcfc..13f2e3aff8b5 100644
> --- a/arch/powerpc/mm/mem.c
> +++ b/arch/powerpc/mm/mem.c
> @@ -50,6 +50,7 @@
> #include <asm/swiotlb.h>
> #include <asm/rtas.h>
> #include <asm/kasan.h>
> +#include <asm/svm.h>
>
> #include <mm/mmu_decl.h>
>
> @@ -290,7 +291,11 @@ void __init mem_init(void)
> * back to to-down.
> */
> memblock_set_bottom_up(true);
> - swiotlb_init(0);
> + /*
> + * SVM guests can use the SWIOTLB wherever it is in memory,
> + * even if not DMA-able.
> + */
> + swiotlb_init_anywhere(0, is_secure_guest());
> #endif
>
> high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
> diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h
> index 046bb94bd4d6..433f3dbb35b5 100644
> --- a/include/linux/swiotlb.h
> +++ b/include/linux/swiotlb.h
> @@ -29,7 +29,13 @@ enum swiotlb_force {
> */
> #define IO_TLB_SHIFT 11
>
> -extern void swiotlb_init(int verbose);
> +void __init swiotlb_init_anywhere(int verbose, bool allocate_anywhere);
> +
> +static inline void swiotlb_init(int verbose)
> +{
> + swiotlb_init_anywhere(verbose, false);
> +}
> +
> int swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose);
> extern unsigned long swiotlb_nr_tbl(void);
> unsigned long swiotlb_size_or_default(void);
> diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c
> index c19379fabd20..27070aa59e34 100644
> --- a/kernel/dma/swiotlb.c
> +++ b/kernel/dma/swiotlb.c
> @@ -244,7 +244,7 @@ int __init swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose)
> * structures for the software IO TLB used to implement the DMA API.
> */
> void __init
> -swiotlb_init(int verbose)
> +swiotlb_init_anywhere(int verbose, bool allocate_anywhere)
> {
> size_t default_size = IO_TLB_DEFAULT_SIZE;
> unsigned char *vstart;
> @@ -257,8 +257,12 @@ swiotlb_init(int verbose)
>
> bytes = io_tlb_nslabs << IO_TLB_SHIFT;
>
> - /* Get IO TLB memory from the low pages */
> - vstart = memblock_alloc_low(PAGE_ALIGN(bytes), PAGE_SIZE);
> + if (allocate_anywhere)
> + vstart = memblock_alloc(PAGE_ALIGN(bytes), PAGE_SIZE);
> + else
> + /* Get IO TLB memory from the low pages */
> + vstart = memblock_alloc_low(PAGE_ALIGN(bytes), PAGE_SIZE);
> +
> if (vstart && !swiotlb_init_with_tbl(vstart, io_tlb_nslabs, verbose))
> return;
>
---end quoted text---
^ permalink raw reply
* Re: [PATCH 00/10] sound: convert tasklets to use new tasklet_setup()
From: Takashi Iwai @ 2020-08-17 9:43 UTC (permalink / raw)
To: Allen Pais
Cc: alsa-devel, keescook, timur, Xiubo.Lee, linux-kernel, clemens,
tiwai, o-takashi, nicoleotsuka, Allen Pais, perex, linuxppc-dev
In-Reply-To: <CAEogwTAGHOfBe4ztkx9To0gQGwHwFWzCBxn8nzWJP=wRJUJ56A@mail.gmail.com>
On Mon, 17 Aug 2020 11:18:53 +0200,
Allen Pais wrote:
>
> >
> > Is this targeted for 5.9 or 5.10?
>
> This is targeted for 5.9.
Well, then at the next time, please mention it explicitly in the cover
letter. Usually this kind of API conversion isn't done during rc. Or
it's done systematically via script or such. So unless mentioned,
it's not expected to be carried to 5.9.
In anyway, if the final purpose is to drop the old tasklet API and
that's the plan for 5.9, all tree-wide changes have to be done in
5.9 beforehand. Was that the decision?
> > I have a patch set to drop the whole tasklet usage in sound/*
> > (destined for 5.10, to be submitted soon), so if that's for 5.10,
> > it'll be likely superfluous.
>
> I have picked patches from your tree to adapt to this new API.
> Those can be picked in 5.10 I suppose.
Adapting the changes are trivial, don't worry. It was just a question
of how to organize changes.
thanks,
Takashi
^ permalink raw reply
* Re: [Virtual ppce500] virtio_gpu virtio0: swiotlb buffer is full
From: Christian Zigotzky @ 2020-08-17 9:19 UTC (permalink / raw)
To: daniel.vetter
Cc: Darren Stevens, mad skateman, Michel Dänzer,
Maling list - DRI developers, kvm-ppc@vger.kernel.org,
R.T.Dickinson, linuxppc-dev
In-Reply-To: <3162da18-462c-72b4-f8f0-eef896c6b162@xenosoft.de>
Hello
I compiled the RC1 of kernel 5.9 today. Unfortunately the issue with the
VirtIO-GPU (see below) still exists. Therefore we still need the patch
(see below) for using the VirtIO-GPU in a virtual e5500 PPC64 QEMU machine.
Could you please check the first bad commit?
Thanks
Christian
On 12 August 2020 at 3:09 pm, Christian Zigotzky wrote:
> Hello Daniel,
>
> The VirtIO-GPU doesn't work anymore with the latest Git kernel in a
> virtual e5500 PPC64 QEMU machine [1,2] after the commit "drm/virtio:
> Call the right shmem helpers". [3]
> The kernel 5.8 works with the VirtIO-GPU in this virtual machine.
>
> I bisected today [4].
>
> Result: drm/virtio: Call the right shmem helpers (
> d323bb44e4d23802eb25d13de1f93f2335bd60d0) [3] is the first bad commit.
>
> I was able to revert the first bad commit. [5] After that I compiled a
> new kernel again. Then I was able to boot Linux with this kernel in a
> virtual e5500 PPC64 QEMU machine with the VirtIO-GPU.
>
> I created a patch. [6] With this patch I can use the VirtIO-GPU again.
>
> Could you please check the first bad commit?
>
> Thanks,
> Christian
>
> [1] QEMU command: qemu-system-ppc64 -M ppce500 -cpu e5500 -enable-kvm
> -m 1024 -kernel uImage -drive
> format=raw,file=fienix-soar_3.0-2020608-net.img,index=0,if=virtio -nic
> user,model=e1000 -append "rw root=/dev/vda2" -device virtio-vga
> -device virtio-mouse-pci -device virtio-keyboard-pci -device
> pci-ohci,id=newusb -device usb-audio,bus=newusb.0 -smp 4
>
> [2] Error messages:
>
> virtio_gpu virtio0: swiotlb buffer is full (sz: 4096 bytes), total 0
> (slots), used 0 (slots)
> BUG: Kernel NULL pointer dereference on read at 0x00000010
> Faulting instruction address: 0xc0000000000c7324
> Oops: Kernel access of bad area, sig: 11 [#1]
> BE PAGE_SIZE=4K PREEMPT SMP NR_CPUS=4 QEMU e500
> Modules linked in:
> CPU: 2 PID: 1678 Comm: kworker/2:2 Not tainted
> 5.9-a3_A-EON_X5000-11735-g06a81c1c7db9-dirty #1
> Workqueue: events .virtio_gpu_dequeue_ctrl_func
> NIP: c0000000000c7324 LR: c0000000000c72e4 CTR: c000000000462930
> REGS: c00000003dba75e0 TRAP: 0300 Not tainted
> (5.9-a3_A-EON_X5000-11735-g06a81c1c7db9-dirty)
> MSR: 0000000090029000 <CE,EE,ME> CR: 24002288 XER: 00000000
> DEAR: 0000000000000010 ESR: 0000000000000000 IRQMASK: 0
> GPR00: c0000000000c6188 c00000003dba7870 c0000000017f2300
> c00000003d893010
> GPR04: 0000000000000000 0000000000000001 0000000000000000
> 0000000000000000
> GPR08: 0000000000000000 0000000000000000 0000000000000000
> 7f7f7f7f7f7f7f7f
> GPR12: 0000000024002284 c00000003fff9200 c00000000008c3a0
> c0000000061566c0
> GPR16: 0000000000000000 0000000000000000 0000000000000000
> 0000000000000000
> GPR20: 0000000000000000 0000000000000000 0000000000000000
> 0000000000000000
> GPR24: 0000000000000001 0000000000110000 0000000000000000
> 0000000000000000
> GPR28: c00000003d893010 0000000000000000 0000000000000000
> c00000003d893010
> NIP [c0000000000c7324] .dma_direct_unmap_sg+0x4c/0xd8
> LR [c0000000000c72e4] .dma_direct_unmap_sg+0xc/0xd8
> Call Trace:
> [c00000003dba7870] [c00000003dba7950] 0xc00000003dba7950 (unreliable)
> [c00000003dba7920] [c0000000000c6188] .dma_unmap_sg_attrs+0x5c/0x98
> [c00000003dba79d0] [c0000000005cd438]
> .drm_gem_shmem_free_object+0x98/0xcc
> [c00000003dba7a50] [c0000000006af5b4]
> .virtio_gpu_cleanup_object+0xc8/0xd4
> [c00000003dba7ad0] [c0000000006ad3bc] .virtio_gpu_cmd_unref_cb+0x1c/0x30
> [c00000003dba7b40] [c0000000006adab8]
> .virtio_gpu_dequeue_ctrl_func+0x208/0x28c
> [c00000003dba7c10] [c000000000086b70] .process_one_work+0x1a4/0x258
> [c00000003dba7cb0] [c0000000000870f4] .worker_thread+0x214/0x284
> [c00000003dba7d70] [c00000000008c4f0] .kthread+0x150/0x158
> [c00000003dba7e20] [c00000000000082c] .ret_from_kernel_thread+0x58/0x60
> Instruction dump:
> f821ff51 7cb82b78 7cdb3378 4e000000 7cfa3b78 3bc00000 7f9ec000 41fc0014
> 382100b0 81810008 7d808120 48bc1ba8 <e93d0010> ebfc0248 833d0018 7fff4850
> ---[ end trace f28d194d9f0955a8 ]---
>
> virtio_gpu virtio0: swiotlb buffer is full (sz: 4096 bytes), total 0
> (slots), used 0 (slots)
> virtio_gpu virtio0: swiotlb buffer is full (sz: 16384 bytes), total 0
> (slots), used 0 (slots)
>
> ---
>
> [3]
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d323bb44e4d23802eb25d13de1f93f2335bd60d0
>
> [4] https://forum.hyperion-entertainment.com/viewtopic.php?p=51377#p51377
>
> [5] git revert d323bb44e4d23802eb25d13de1f93f2335bd60d0 //Output:
> [master 966950f724e4] Revert "drm/virtio: Call the right shmem
> helpers" 1 file changed, 1 insertion(+), 1 deletion(-)
>
> [6]
> diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c
> b/drivers/gpu/drm/virtio/virtgpu_object.c
> index 6ccbd01cd888..346cef5ce251 100644
> --- a/drivers/gpu/drm/virtio/virtgpu_object.c
> +++ b/drivers/gpu/drm/virtio/virtgpu_object.c
> @@ -150,7 +150,7 @@ static int virtio_gpu_object_shmem_init(struct
> virtio_gpu_device *vgdev,
> if (ret < 0)
> return -EINVAL;
>
> - shmem->pages = drm_gem_shmem_get_pages_sgt(&bo->base.base);
> + shmem->pages = drm_gem_shmem_get_sg_table(&bo->base.base);
> if (!shmem->pages) {
> drm_gem_shmem_unpin(&bo->base.base);
> return -EINVAL;
> ---
^ permalink raw reply
* Re: [PATCH 00/10] sound: convert tasklets to use new tasklet_setup()
From: Takashi Iwai @ 2020-08-17 9:08 UTC (permalink / raw)
To: Allen Pais
Cc: alsa-devel, keescook, timur, Xiubo.Lee, linux-kernel, clemens,
tiwai, o-takashi, nicoleotsuka, Allen Pais, perex, linuxppc-dev
In-Reply-To: <20200817085703.25732-1-allen.cryptic@gmail.com>
On Mon, 17 Aug 2020 10:56:53 +0200,
Allen Pais wrote:
>
> From: Allen Pais <allen.lkml@gmail.com>
>
> Commit 12cc923f1ccc ("tasklet: Introduce new initialization API")'
> introduced a new tasklet initialization API. This series converts
> all the sound drivers to use the new tasklet_setup() API
Is this targeted for 5.9 or 5.10?
I have a patch set to drop the whole tasklet usage in sound/*
(destined for 5.10, to be submitted soon), so if that's for 5.10,
it'll be likely superfluous.
thanks,
Takashi
^ permalink raw reply
* [PATCH 20/20] ethernet: smsc: convert tasklets to use new tasklet_setup() API
From: Allen Pais @ 2020-08-17 8:24 UTC (permalink / raw)
To: jes, davem, kuba, kda, dougmill, cooldavid, mlindner, borisp
Cc: keescook, linux-rdma, netdev, linux-kernel, Allen Pais,
oss-drivers, Romain Perier, linuxppc-dev, linux-acenic,
linux-arm-kernel
In-Reply-To: <20200817082434.21176-1-allen.lkml@gmail.com>
In preparation for unconditionally passing the
struct tasklet_struct pointer to all tasklet
callbacks, switch to using the new tasklet_setup()
and from_tasklet() to pass the tasklet pointer explicitly.
Signed-off-by: Romain Perier <romain.perier@gmail.com>
Signed-off-by: Allen Pais <allen.lkml@gmail.com>
---
drivers/net/ethernet/smsc/smc91x.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/smsc/smc91x.c b/drivers/net/ethernet/smsc/smc91x.c
index 1c4fea9c3ec4..7e585aa3031c 100644
--- a/drivers/net/ethernet/smsc/smc91x.c
+++ b/drivers/net/ethernet/smsc/smc91x.c
@@ -535,10 +535,10 @@ static inline void smc_rcv(struct net_device *dev)
/*
* This is called to actually send a packet to the chip.
*/
-static void smc_hardware_send_pkt(unsigned long data)
+static void smc_hardware_send_pkt(struct tasklet_struct *t)
{
- struct net_device *dev = (struct net_device *)data;
- struct smc_local *lp = netdev_priv(dev);
+ struct smc_local *lp = from_tasklet(lp, t, tx_task);
+ struct net_device *dev = lp->dev;
void __iomem *ioaddr = lp->base;
struct sk_buff *skb;
unsigned int packet_no, len;
@@ -688,7 +688,7 @@ smc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
* Allocation succeeded: push packet to the chip's own memory
* immediately.
*/
- smc_hardware_send_pkt((unsigned long)dev);
+ smc_hardware_send_pkt(&lp->tx_task);
}
return NETDEV_TX_OK;
@@ -1965,7 +1965,7 @@ static int smc_probe(struct net_device *dev, void __iomem *ioaddr,
dev->netdev_ops = &smc_netdev_ops;
dev->ethtool_ops = &smc_ethtool_ops;
- tasklet_init(&lp->tx_task, smc_hardware_send_pkt, (unsigned long)dev);
+ tasklet_setup(&lp->tx_task, smc_hardware_send_pkt);
INIT_WORK(&lp->phy_configure, smc_phy_configure);
lp->dev = dev;
lp->mii.phy_id_mask = 0x1f;
--
2.17.1
^ permalink raw reply related
* [PATCH 19/20] ethernet: silan: convert tasklets to use new tasklet_setup() API
From: Allen Pais @ 2020-08-17 8:24 UTC (permalink / raw)
To: jes, davem, kuba, kda, dougmill, cooldavid, mlindner, borisp
Cc: keescook, linux-rdma, netdev, linux-kernel, Allen Pais,
oss-drivers, Romain Perier, linuxppc-dev, linux-acenic,
linux-arm-kernel
In-Reply-To: <20200817082434.21176-1-allen.lkml@gmail.com>
In preparation for unconditionally passing the
struct tasklet_struct pointer to all tasklet
callbacks, switch to using the new tasklet_setup()
and from_tasklet() to pass the tasklet pointer explicitly.
Signed-off-by: Romain Perier <romain.perier@gmail.com>
Signed-off-by: Allen Pais <allen.lkml@gmail.com>
---
drivers/net/ethernet/silan/sc92031.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/silan/sc92031.c b/drivers/net/ethernet/silan/sc92031.c
index f94078f8ebe5..8d56eca5be17 100644
--- a/drivers/net/ethernet/silan/sc92031.c
+++ b/drivers/net/ethernet/silan/sc92031.c
@@ -829,10 +829,11 @@ static void _sc92031_link_tasklet(struct net_device *dev)
}
}
-static void sc92031_tasklet(unsigned long data)
+static void sc92031_tasklet(struct tasklet_struct *t)
{
- struct net_device *dev = (struct net_device *)data;
- struct sc92031_priv *priv = netdev_priv(dev);
+ struct sc92031_priv *priv = from_tasklet(priv, t, tasklet);
+ struct net_device *dev = (struct net_device *)((char *)priv -
+ ALIGN(sizeof(struct net_device), NETDEV_ALIGN));
void __iomem *port_base = priv->port_base;
u32 intr_status, intr_mask;
@@ -1108,7 +1109,7 @@ static void sc92031_poll_controller(struct net_device *dev)
disable_irq(irq);
if (sc92031_interrupt(irq, dev) != IRQ_NONE)
- sc92031_tasklet((unsigned long)dev);
+ sc92031_tasklet(&priv->tasklet);
enable_irq(irq);
}
#endif
@@ -1446,7 +1447,7 @@ static int sc92031_probe(struct pci_dev *pdev, const struct pci_device_id *id)
spin_lock_init(&priv->lock);
priv->port_base = port_base;
priv->pdev = pdev;
- tasklet_init(&priv->tasklet, sc92031_tasklet, (unsigned long)dev);
+ tasklet_setup(&priv->tasklet, sc92031_tasklet);
/* Fudge tasklet count so the call to sc92031_enable_interrupts at
* sc92031_open will work correctly */
tasklet_disable_nosync(&priv->tasklet);
--
2.17.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox