[PATCH v3 07/14] pc-bios/s390-ccw: Introduce CLP Architecture

jrossi@linux.ibm.com posted 14 patches 1 week, 5 days ago
Maintainers: "Michael S. Tsirkin" <mst@redhat.com>, Marcel Apfelbaum <marcel.apfelbaum@gmail.com>, Christian Borntraeger <borntraeger@linux.ibm.com>, Thomas Huth <thuth@redhat.com>, Jared Rossi <jrossi@linux.ibm.com>, Zhuoying Cai <zycai@linux.ibm.com>, Halil Pasic <pasic@linux.ibm.com>, Eric Farman <farman@linux.ibm.com>, Matthew Rosato <mjrosato@linux.ibm.com>, Richard Henderson <richard.henderson@linaro.org>, Ilya Leoshkevich <iii@linux.ibm.com>, David Hildenbrand <david@kernel.org>, John Snow <jsnow@redhat.com>, Fabiano Rosas <farosas@suse.de>, Laurent Vivier <lvivier@redhat.com>, Paolo Bonzini <pbonzini@redhat.com>
[PATCH v3 07/14] pc-bios/s390-ccw: Introduce CLP Architecture
Posted by jrossi@linux.ibm.com 1 week, 5 days ago
From: Jared Rossi <jrossi@linux.ibm.com>

Call Logical Processor (CLP) Architecture is used for managing PCI functions on
s390x. Define and include the structures and routines needed to interact with
PCI devices during IPL.

Signed-off-by: Jared Rossi <jrossi@linux.ibm.com>
---
 pc-bios/s390-ccw/Makefile |  2 +-
 pc-bios/s390-ccw/clp.c    | 96 +++++++++++++++++++++++++++++++++++++++
 pc-bios/s390-ccw/clp.h    | 24 ++++++++++
 3 files changed, 121 insertions(+), 1 deletion(-)
 create mode 100644 pc-bios/s390-ccw/clp.c
 create mode 100644 pc-bios/s390-ccw/clp.h

diff --git a/pc-bios/s390-ccw/Makefile b/pc-bios/s390-ccw/Makefile
index 259cff09db..9c29548f84 100644
--- a/pc-bios/s390-ccw/Makefile
+++ b/pc-bios/s390-ccw/Makefile
@@ -35,7 +35,7 @@ QEMU_DGFLAGS = -MMD -MP -MT $@ -MF $(@D)/$(*F).d
 
 OBJECTS = start.o main.o bootmap.o jump2ipl.o sclp.o menu.o netmain.o \
 	  virtio.o virtio-net.o virtio-scsi.o virtio-blkdev.o cio.o dasd-ipl.o \
-	  virtio-ccw.o
+	  virtio-ccw.o clp.o
 
 SLOF_DIR := $(SRC_PATH)/../../roms/SLOF
 
diff --git a/pc-bios/s390-ccw/clp.c b/pc-bios/s390-ccw/clp.c
new file mode 100644
index 0000000000..2a14bb9b73
--- /dev/null
+++ b/pc-bios/s390-ccw/clp.c
@@ -0,0 +1,96 @@
+/*
+ * Call Logical Processor (CLP) architecture
+ *
+ * Copyright 2025 IBM Corp.
+ * Author(s): Jared Rossi <jrossi@linux.ibm.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "clp.h"
+#include <stdio.h>
+#include <string.h>
+
+int clp_pci(void *data)
+{
+    struct { uint8_t _[2048]; } *req = data;
+    int cc = 3;
+
+    asm volatile (
+        "     .insn   rrf,0xb9a00000,0,%[req],0,2\n"
+        "     ipm     %[cc]\n"
+        "     srl     %[cc],28\n"
+        : [cc] "+d" (cc), "+m" (*req)
+        : [req] "a" (req)
+        : "cc");
+    return cc;
+}
+
+/*
+ * Get the PCI function entry for a given function ID
+ * Return 0 on success, 1 if the FID is not found, or a negative RC on error
+ */
+int find_pci_function(uint32_t fid, ClpFhListEntry *entry)
+{
+    int count = 0;
+    int limit = PCI_MAX_FUNCTIONS;
+    ClpReqRspListPci rrb;
+
+    rrb.request.hdr.len = 32;
+    rrb.request.hdr.cmd = 0x02;
+    rrb.request.resume_token = 0;
+    rrb.response.hdr.len = sizeof(ClpRspListPci);
+
+    do {
+        if (clp_pci(&rrb) || rrb.response.hdr.rsp != 0x0010) {
+            puts("Failed to list PCI functions");
+            return -1;
+        }
+
+        /* Resume token set when max enteries are returned */
+        if (rrb.response.resume_token) {
+            count = CLP_FH_LIST_NR_ENTRIES;
+            rrb.request.resume_token = rrb.response.resume_token;
+        } else {
+            count = (rrb.response.hdr.len - 32) / sizeof(ClpFhListEntry);
+        }
+
+        limit -= count;
+
+        for (int i = 0; i < count; i++) {
+            if (rrb.response.fh_list[i].fid == fid) {
+                memcpy(entry, &rrb.response.fh_list[i], sizeof(ClpFhListEntry));
+                return 0;
+            }
+        }
+
+    } while (rrb.request.resume_token && limit > 0);
+
+    puts("No function entry found for FID!");
+
+    return 1;
+}
+
+/*
+ * Enable the PCI function associated with a given handle
+ * Return 0 on success or a negative RC on error
+ */
+int enable_pci_function(uint32_t *fhandle)
+{
+    ClpReqRspSetPci rrb;
+
+    rrb.request.hdr.len = 32;
+    rrb.request.hdr.cmd = 0x05;
+    rrb.request.fh = *fhandle;
+    rrb.request.oc = 0;
+    rrb.request.ndas = 1;
+    rrb.response.hdr.len = 32;
+
+    if (clp_pci(&rrb) || rrb.response.hdr.rsp != 0x0010) {
+        puts("Failed to enable PCI function");
+        return -1;
+    }
+
+    *fhandle = rrb.response.fh;
+    return 0;
+}
diff --git a/pc-bios/s390-ccw/clp.h b/pc-bios/s390-ccw/clp.h
new file mode 100644
index 0000000000..1ac2f8c177
--- /dev/null
+++ b/pc-bios/s390-ccw/clp.h
@@ -0,0 +1,24 @@
+/*
+ * Call Logical Processor (CLP) architecture definitions
+ *
+ * Copyright 2025 IBM Corp.
+ * Author(s): Jared Rossi <jrossi@linux.ibm.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef CLP_H
+#define CLP_H
+
+#ifndef QEMU_PACKED
+#define QEMU_PACKED __attribute__((packed))
+#endif
+
+#include <stdint.h>
+#include <s390-pci-clp.h>
+
+int clp_pci(void *data);
+int find_pci_function(uint32_t fid, ClpFhListEntry *entry);
+int enable_pci_function(uint32_t *fhandle);
+
+#endif
-- 
2.52.0
Re: [PATCH v3 07/14] pc-bios/s390-ccw: Introduce CLP Architecture
Posted by Farhan Ali 1 week, 3 days ago
On 1/27/2026 8:15 AM, jrossi@linux.ibm.com wrote:
> From: Jared Rossi <jrossi@linux.ibm.com>
>
> Call Logical Processor (CLP) Architecture is used for managing PCI functions on
> s390x. Define and include the structures and routines needed to interact with
> PCI devices during IPL.
>
> Signed-off-by: Jared Rossi <jrossi@linux.ibm.com>
> ---
>   pc-bios/s390-ccw/Makefile |  2 +-
>   pc-bios/s390-ccw/clp.c    | 96 +++++++++++++++++++++++++++++++++++++++
>   pc-bios/s390-ccw/clp.h    | 24 ++++++++++
>   3 files changed, 121 insertions(+), 1 deletion(-)
>   create mode 100644 pc-bios/s390-ccw/clp.c
>   create mode 100644 pc-bios/s390-ccw/clp.h
>
> diff --git a/pc-bios/s390-ccw/Makefile b/pc-bios/s390-ccw/Makefile
> index 259cff09db..9c29548f84 100644
> --- a/pc-bios/s390-ccw/Makefile
> +++ b/pc-bios/s390-ccw/Makefile
> @@ -35,7 +35,7 @@ QEMU_DGFLAGS = -MMD -MP -MT $@ -MF $(@D)/$(*F).d
>   
>   OBJECTS = start.o main.o bootmap.o jump2ipl.o sclp.o menu.o netmain.o \
>   	  virtio.o virtio-net.o virtio-scsi.o virtio-blkdev.o cio.o dasd-ipl.o \
> -	  virtio-ccw.o
> +	  virtio-ccw.o clp.o
>   
>   SLOF_DIR := $(SRC_PATH)/../../roms/SLOF
>   
> diff --git a/pc-bios/s390-ccw/clp.c b/pc-bios/s390-ccw/clp.c
> new file mode 100644
> index 0000000000..2a14bb9b73
> --- /dev/null
> +++ b/pc-bios/s390-ccw/clp.c
> @@ -0,0 +1,96 @@
> +/*
> + * Call Logical Processor (CLP) architecture
> + *
> + * Copyright 2025 IBM Corp.
> + * Author(s): Jared Rossi <jrossi@linux.ibm.com>
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#include "clp.h"
> +#include <stdio.h>
> +#include <string.h>
> +
> +int clp_pci(void *data)
> +{
> +    struct { uint8_t _[2048]; } *req = data;

The architecture specifies that size of the request + response block 
size can be maximum of 8192 bytes. If I understand correctly I think 
QEMU (similar to kernel) uses CLP_BLK_SIZE when calculating the 
CLP_FH_LIST_NR_ENTRIES, so it assumes that the request + response block 
is 4096. So we can return more than 2048 bytes here and overflow.

I think we should use at least CLP_BLK_SIZE here instead of 2048 or set 
this to the maximum possible value of 8192.

Thanks

Farhan

> +    int cc = 3;
> +
> +    asm volatile (
> +        "     .insn   rrf,0xb9a00000,0,%[req],0,2\n"
> +        "     ipm     %[cc]\n"
> +        "     srl     %[cc],28\n"
> +        : [cc] "+d" (cc), "+m" (*req)
> +        : [req] "a" (req)
> +        : "cc");
> +    return cc;
> +}
> +
>
Re: [PATCH v3 07/14] pc-bios/s390-ccw: Introduce CLP Architecture
Posted by Jared Rossi 1 week ago

On 1/29/26 5:54 PM, Farhan Ali wrote:
>
> On 1/27/2026 8:15 AM, jrossi@linux.ibm.com wrote:
>> From: Jared Rossi <jrossi@linux.ibm.com>
>>
>> Call Logical Processor (CLP) Architecture is used for managing PCI 
>> functions on
>> s390x. Define and include the structures and routines needed to 
>> interact with
>> PCI devices during IPL.
>>
>> Signed-off-by: Jared Rossi <jrossi@linux.ibm.com>
>> ---
>>   pc-bios/s390-ccw/Makefile |  2 +-
>>   pc-bios/s390-ccw/clp.c    | 96 +++++++++++++++++++++++++++++++++++++++
>>   pc-bios/s390-ccw/clp.h    | 24 ++++++++++
>>   3 files changed, 121 insertions(+), 1 deletion(-)
>>   create mode 100644 pc-bios/s390-ccw/clp.c
>>   create mode 100644 pc-bios/s390-ccw/clp.h
>>
>> diff --git a/pc-bios/s390-ccw/Makefile b/pc-bios/s390-ccw/Makefile
>> index 259cff09db..9c29548f84 100644
>> --- a/pc-bios/s390-ccw/Makefile
>> +++ b/pc-bios/s390-ccw/Makefile
>> @@ -35,7 +35,7 @@ QEMU_DGFLAGS = -MMD -MP -MT $@ -MF $(@D)/$(*F).d
>>     OBJECTS = start.o main.o bootmap.o jump2ipl.o sclp.o menu.o 
>> netmain.o \
>>         virtio.o virtio-net.o virtio-scsi.o virtio-blkdev.o cio.o 
>> dasd-ipl.o \
>> -      virtio-ccw.o
>> +      virtio-ccw.o clp.o
>>     SLOF_DIR := $(SRC_PATH)/../../roms/SLOF
>>   diff --git a/pc-bios/s390-ccw/clp.c b/pc-bios/s390-ccw/clp.c
>> new file mode 100644
>> index 0000000000..2a14bb9b73
>> --- /dev/null
>> +++ b/pc-bios/s390-ccw/clp.c
>> @@ -0,0 +1,96 @@
>> +/*
>> + * Call Logical Processor (CLP) architecture
>> + *
>> + * Copyright 2025 IBM Corp.
>> + * Author(s): Jared Rossi <jrossi@linux.ibm.com>
>> + *
>> + * SPDX-License-Identifier: GPL-2.0-or-later
>> + */
>> +
>> +#include "clp.h"
>> +#include <stdio.h>
>> +#include <string.h>
>> +
>> +int clp_pci(void *data)
>> +{
>> +    struct { uint8_t _[2048]; } *req = data;
>
> The architecture specifies that size of the request + response block 
> size can be maximum of 8192 bytes. If I understand correctly I think 
> QEMU (similar to kernel) uses CLP_BLK_SIZE when calculating the 
> CLP_FH_LIST_NR_ENTRIES, so it assumes that the request + response 
> block is 4096. So we can return more than 2048 bytes here and overflow.
>
> I think we should use at least CLP_BLK_SIZE here instead of 2048 or 
> set this to the maximum possible value of 8192.
>
> Thanks
>
> Farhan

Thanks for pointing that out, I'll fix it.

Regards,
Jared Rossi

>
>> +    int cc = 3;
>> +
>> +    asm volatile (
>> +        "     .insn   rrf,0xb9a00000,0,%[req],0,2\n"
>> +        "     ipm     %[cc]\n"
>> +        "     srl     %[cc],28\n"
>> +        : [cc] "+d" (cc), "+m" (*req)
>> +        : [req] "a" (req)
>> +        : "cc");
>> +    return cc;
>> +}
>> +
>>


Re: [PATCH v3 07/14] pc-bios/s390-ccw: Introduce CLP Architecture
Posted by Eric Farman 1 week, 3 days ago
On Tue, 2026-01-27 at 11:15 -0500, jrossi@linux.ibm.com wrote:
> From: Jared Rossi <jrossi@linux.ibm.com>
> 
> Call Logical Processor (CLP) Architecture is used for managing PCI functions on
> s390x. Define and include the structures and routines needed to interact with
> PCI devices during IPL.
> 
> Signed-off-by: Jared Rossi <jrossi@linux.ibm.com>
> ---
>  pc-bios/s390-ccw/Makefile |  2 +-
>  pc-bios/s390-ccw/clp.c    | 96 +++++++++++++++++++++++++++++++++++++++
>  pc-bios/s390-ccw/clp.h    | 24 ++++++++++
>  3 files changed, 121 insertions(+), 1 deletion(-)
>  create mode 100644 pc-bios/s390-ccw/clp.c
>  create mode 100644 pc-bios/s390-ccw/clp.h

First off, this looks like correct according to my reading.

My only question is whether we need any breadcrumbs in case things fail? Dumping the requested FID
in case of an enable, or the response code in either case? (I haven't gotten to the later patches
yet, just looking at the puts here has me wondering if that's enough of a clue.)

> 
> diff --git a/pc-bios/s390-ccw/Makefile b/pc-bios/s390-ccw/Makefile
> index 259cff09db..9c29548f84 100644
> --- a/pc-bios/s390-ccw/Makefile
> +++ b/pc-bios/s390-ccw/Makefile
> @@ -35,7 +35,7 @@ QEMU_DGFLAGS = -MMD -MP -MT $@ -MF $(@D)/$(*F).d
>  
>  OBJECTS = start.o main.o bootmap.o jump2ipl.o sclp.o menu.o netmain.o \
>  	  virtio.o virtio-net.o virtio-scsi.o virtio-blkdev.o cio.o dasd-ipl.o \
> -	  virtio-ccw.o
> +	  virtio-ccw.o clp.o
>  
>  SLOF_DIR := $(SRC_PATH)/../../roms/SLOF
>  
> diff --git a/pc-bios/s390-ccw/clp.c b/pc-bios/s390-ccw/clp.c
> new file mode 100644
> index 0000000000..2a14bb9b73
> --- /dev/null
> +++ b/pc-bios/s390-ccw/clp.c
> @@ -0,0 +1,96 @@
> +/*
> + * Call Logical Processor (CLP) architecture
> + *
> + * Copyright 2025 IBM Corp.
> + * Author(s): Jared Rossi <jrossi@linux.ibm.com>
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#include "clp.h"
> +#include <stdio.h>
> +#include <string.h>
> +
> +int clp_pci(void *data)
> +{
> +    struct { uint8_t _[2048]; } *req = data;
> +    int cc = 3;
> +
> +    asm volatile (
> +        "     .insn   rrf,0xb9a00000,0,%[req],0,2\n"
> +        "     ipm     %[cc]\n"
> +        "     srl     %[cc],28\n"
> +        : [cc] "+d" (cc), "+m" (*req)
> +        : [req] "a" (req)
> +        : "cc");
> +    return cc;
> +}
> +
> +/*
> + * Get the PCI function entry for a given function ID
> + * Return 0 on success, 1 if the FID is not found, or a negative RC on error
> + */
> +int find_pci_function(uint32_t fid, ClpFhListEntry *entry)
> +{
> +    int count = 0;
> +    int limit = PCI_MAX_FUNCTIONS;
> +    ClpReqRspListPci rrb;
> +
> +    rrb.request.hdr.len = 32;
> +    rrb.request.hdr.cmd = 0x02;
> +    rrb.request.resume_token = 0;
> +    rrb.response.hdr.len = sizeof(ClpRspListPci);
> +
> +    do {
> +        if (clp_pci(&rrb) || rrb.response.hdr.rsp != 0x0010) {
> +            puts("Failed to list PCI functions");
> +            return -1;
> +        }
> +
> +        /* Resume token set when max enteries are returned */
> +        if (rrb.response.resume_token) {
> +            count = CLP_FH_LIST_NR_ENTRIES;
> +            rrb.request.resume_token = rrb.response.resume_token;
> +        } else {
> +            count = (rrb.response.hdr.len - 32) / sizeof(ClpFhListEntry);
> +        }
> +
> +        limit -= count;
> +
> +        for (int i = 0; i < count; i++) {
> +            if (rrb.response.fh_list[i].fid == fid) {
> +                memcpy(entry, &rrb.response.fh_list[i], sizeof(ClpFhListEntry));
> +                return 0;
> +            }
> +        }
> +
> +    } while (rrb.request.resume_token && limit > 0);
> +
> +    puts("No function entry found for FID!");
> +
> +    return 1;
> +}
> +
> +/*
> + * Enable the PCI function associated with a given handle
> + * Return 0 on success or a negative RC on error
> + */
> +int enable_pci_function(uint32_t *fhandle)
> +{
> +    ClpReqRspSetPci rrb;
> +
> +    rrb.request.hdr.len = 32;
> +    rrb.request.hdr.cmd = 0x05;
> +    rrb.request.fh = *fhandle;
> +    rrb.request.oc = 0;
> +    rrb.request.ndas = 1;
> +    rrb.response.hdr.len = 32;
> +
> +    if (clp_pci(&rrb) || rrb.response.hdr.rsp != 0x0010) {
> +        puts("Failed to enable PCI function");
> +        return -1;
> +    }
> +
> +    *fhandle = rrb.response.fh;
> +    return 0;
> +}
> diff --git a/pc-bios/s390-ccw/clp.h b/pc-bios/s390-ccw/clp.h
> new file mode 100644
> index 0000000000..1ac2f8c177
> --- /dev/null
> +++ b/pc-bios/s390-ccw/clp.h
> @@ -0,0 +1,24 @@
> +/*
> + * Call Logical Processor (CLP) architecture definitions
> + *
> + * Copyright 2025 IBM Corp.
> + * Author(s): Jared Rossi <jrossi@linux.ibm.com>
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#ifndef CLP_H
> +#define CLP_H
> +
> +#ifndef QEMU_PACKED
> +#define QEMU_PACKED __attribute__((packed))
> +#endif
> +
> +#include <stdint.h>
> +#include <s390-pci-clp.h>
> +
> +int clp_pci(void *data);
> +int find_pci_function(uint32_t fid, ClpFhListEntry *entry);
> +int enable_pci_function(uint32_t *fhandle);
> +
> +#endif
Re: [PATCH v3 07/14] pc-bios/s390-ccw: Introduce CLP Architecture
Posted by Jared Rossi 1 week ago

On 1/29/26 4:52 PM, Eric Farman wrote:
> On Tue, 2026-01-27 at 11:15 -0500, jrossi@linux.ibm.com wrote:
>> From: Jared Rossi <jrossi@linux.ibm.com>
>>
>> Call Logical Processor (CLP) Architecture is used for managing PCI functions on
>> s390x. Define and include the structures and routines needed to interact with
>> PCI devices during IPL.
>>
>> Signed-off-by: Jared Rossi <jrossi@linux.ibm.com>
>> ---
>>   pc-bios/s390-ccw/Makefile |  2 +-
>>   pc-bios/s390-ccw/clp.c    | 96 +++++++++++++++++++++++++++++++++++++++
>>   pc-bios/s390-ccw/clp.h    | 24 ++++++++++
>>   3 files changed, 121 insertions(+), 1 deletion(-)
>>   create mode 100644 pc-bios/s390-ccw/clp.c
>>   create mode 100644 pc-bios/s390-ccw/clp.h
> First off, this looks like correct according to my reading.
>
> My only question is whether we need any breadcrumbs in case things fail? Dumping the requested FID
> in case of an enable, or the response code in either case? (I haven't gotten to the later patches
> yet, just looking at the puts here has me wondering if that's enough of a clue.)

Improving the logging makes sense; I'll add more useful output.

Thanks,
Jared Rossi

>
>> diff --git a/pc-bios/s390-ccw/Makefile b/pc-bios/s390-ccw/Makefile
>> index 259cff09db..9c29548f84 100644
>> --- a/pc-bios/s390-ccw/Makefile
>> +++ b/pc-bios/s390-ccw/Makefile
>> @@ -35,7 +35,7 @@ QEMU_DGFLAGS = -MMD -MP -MT $@ -MF $(@D)/$(*F).d
>>   
>>   OBJECTS = start.o main.o bootmap.o jump2ipl.o sclp.o menu.o netmain.o \
>>   	  virtio.o virtio-net.o virtio-scsi.o virtio-blkdev.o cio.o dasd-ipl.o \
>> -	  virtio-ccw.o
>> +	  virtio-ccw.o clp.o
>>   
>>   SLOF_DIR := $(SRC_PATH)/../../roms/SLOF
>>   
>> diff --git a/pc-bios/s390-ccw/clp.c b/pc-bios/s390-ccw/clp.c
>> new file mode 100644
>> index 0000000000..2a14bb9b73
>> --- /dev/null
>> +++ b/pc-bios/s390-ccw/clp.c
>> @@ -0,0 +1,96 @@
>> +/*
>> + * Call Logical Processor (CLP) architecture
>> + *
>> + * Copyright 2025 IBM Corp.
>> + * Author(s): Jared Rossi <jrossi@linux.ibm.com>
>> + *
>> + * SPDX-License-Identifier: GPL-2.0-or-later
>> + */
>> +
>> +#include "clp.h"
>> +#include <stdio.h>
>> +#include <string.h>
>> +
>> +int clp_pci(void *data)
>> +{
>> +    struct { uint8_t _[2048]; } *req = data;
>> +    int cc = 3;
>> +
>> +    asm volatile (
>> +        "     .insn   rrf,0xb9a00000,0,%[req],0,2\n"
>> +        "     ipm     %[cc]\n"
>> +        "     srl     %[cc],28\n"
>> +        : [cc] "+d" (cc), "+m" (*req)
>> +        : [req] "a" (req)
>> +        : "cc");
>> +    return cc;
>> +}
>> +
>> +/*
>> + * Get the PCI function entry for a given function ID
>> + * Return 0 on success, 1 if the FID is not found, or a negative RC on error
>> + */
>> +int find_pci_function(uint32_t fid, ClpFhListEntry *entry)
>> +{
>> +    int count = 0;
>> +    int limit = PCI_MAX_FUNCTIONS;
>> +    ClpReqRspListPci rrb;
>> +
>> +    rrb.request.hdr.len = 32;
>> +    rrb.request.hdr.cmd = 0x02;
>> +    rrb.request.resume_token = 0;
>> +    rrb.response.hdr.len = sizeof(ClpRspListPci);
>> +
>> +    do {
>> +        if (clp_pci(&rrb) || rrb.response.hdr.rsp != 0x0010) {
>> +            puts("Failed to list PCI functions");
>> +            return -1;
>> +        }
>> +
>> +        /* Resume token set when max enteries are returned */
>> +        if (rrb.response.resume_token) {
>> +            count = CLP_FH_LIST_NR_ENTRIES;
>> +            rrb.request.resume_token = rrb.response.resume_token;
>> +        } else {
>> +            count = (rrb.response.hdr.len - 32) / sizeof(ClpFhListEntry);
>> +        }
>> +
>> +        limit -= count;
>> +
>> +        for (int i = 0; i < count; i++) {
>> +            if (rrb.response.fh_list[i].fid == fid) {
>> +                memcpy(entry, &rrb.response.fh_list[i], sizeof(ClpFhListEntry));
>> +                return 0;
>> +            }
>> +        }
>> +
>> +    } while (rrb.request.resume_token && limit > 0);
>> +
>> +    puts("No function entry found for FID!");
>> +
>> +    return 1;
>> +}
>> +
>> +/*
>> + * Enable the PCI function associated with a given handle
>> + * Return 0 on success or a negative RC on error
>> + */
>> +int enable_pci_function(uint32_t *fhandle)
>> +{
>> +    ClpReqRspSetPci rrb;
>> +
>> +    rrb.request.hdr.len = 32;
>> +    rrb.request.hdr.cmd = 0x05;
>> +    rrb.request.fh = *fhandle;
>> +    rrb.request.oc = 0;
>> +    rrb.request.ndas = 1;
>> +    rrb.response.hdr.len = 32;
>> +
>> +    if (clp_pci(&rrb) || rrb.response.hdr.rsp != 0x0010) {
>> +        puts("Failed to enable PCI function");
>> +        return -1;
>> +    }
>> +
>> +    *fhandle = rrb.response.fh;
>> +    return 0;
>> +}
>> diff --git a/pc-bios/s390-ccw/clp.h b/pc-bios/s390-ccw/clp.h
>> new file mode 100644
>> index 0000000000..1ac2f8c177
>> --- /dev/null
>> +++ b/pc-bios/s390-ccw/clp.h
>> @@ -0,0 +1,24 @@
>> +/*
>> + * Call Logical Processor (CLP) architecture definitions
>> + *
>> + * Copyright 2025 IBM Corp.
>> + * Author(s): Jared Rossi <jrossi@linux.ibm.com>
>> + *
>> + * SPDX-License-Identifier: GPL-2.0-or-later
>> + */
>> +
>> +#ifndef CLP_H
>> +#define CLP_H
>> +
>> +#ifndef QEMU_PACKED
>> +#define QEMU_PACKED __attribute__((packed))
>> +#endif
>> +
>> +#include <stdint.h>
>> +#include <s390-pci-clp.h>
>> +
>> +int clp_pci(void *data);
>> +int find_pci_function(uint32_t fid, ClpFhListEntry *entry);
>> +int enable_pci_function(uint32_t *fhandle);
>> +
>> +#endif
Re: [PATCH v3 07/14] pc-bios/s390-ccw: Introduce CLP Architecture
Posted by Thomas Huth 1 week, 3 days ago
On 27/01/2026 17.15, jrossi@linux.ibm.com wrote:
> From: Jared Rossi <jrossi@linux.ibm.com>
> 
> Call Logical Processor (CLP) Architecture is used for managing PCI functions on
> s390x. Define and include the structures and routines needed to interact with
> PCI devices during IPL.
> 
> Signed-off-by: Jared Rossi <jrossi@linux.ibm.com>
> ---
>   pc-bios/s390-ccw/Makefile |  2 +-
>   pc-bios/s390-ccw/clp.c    | 96 +++++++++++++++++++++++++++++++++++++++
>   pc-bios/s390-ccw/clp.h    | 24 ++++++++++
>   3 files changed, 121 insertions(+), 1 deletion(-)
>   create mode 100644 pc-bios/s390-ccw/clp.c
>   create mode 100644 pc-bios/s390-ccw/clp.h
> 
> diff --git a/pc-bios/s390-ccw/Makefile b/pc-bios/s390-ccw/Makefile
> index 259cff09db..9c29548f84 100644
> --- a/pc-bios/s390-ccw/Makefile
> +++ b/pc-bios/s390-ccw/Makefile
> @@ -35,7 +35,7 @@ QEMU_DGFLAGS = -MMD -MP -MT $@ -MF $(@D)/$(*F).d
>   
>   OBJECTS = start.o main.o bootmap.o jump2ipl.o sclp.o menu.o netmain.o \
>   	  virtio.o virtio-net.o virtio-scsi.o virtio-blkdev.o cio.o dasd-ipl.o \
> -	  virtio-ccw.o
> +	  virtio-ccw.o clp.o
>   
>   SLOF_DIR := $(SRC_PATH)/../../roms/SLOF
>   
> diff --git a/pc-bios/s390-ccw/clp.c b/pc-bios/s390-ccw/clp.c
> new file mode 100644
> index 0000000000..2a14bb9b73
> --- /dev/null
> +++ b/pc-bios/s390-ccw/clp.c
> @@ -0,0 +1,96 @@
> +/*
> + * Call Logical Processor (CLP) architecture
> + *
> + * Copyright 2025 IBM Corp.
> + * Author(s): Jared Rossi <jrossi@linux.ibm.com>
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#include "clp.h"
> +#include <stdio.h>
> +#include <string.h>
> +
> +int clp_pci(void *data)
> +{
> +    struct { uint8_t _[2048]; } *req = data;
> +    int cc = 3;
> +
> +    asm volatile (
> +        "     .insn   rrf,0xb9a00000,0,%[req],0,2\n"
> +        "     ipm     %[cc]\n"
> +        "     srl     %[cc],28\n"
> +        : [cc] "+d" (cc), "+m" (*req)
> +        : [req] "a" (req)
> +        : "cc");
> +    return cc;
> +}

Since this instruction is not part of the public Principles of Operation, 
I'd appreciate if someone from IBM could review this patch.

 From my side, I can only provide:
Acked-by: Thomas Huth <thuth@redhat.com>
Re: [PATCH v3 07/14] pc-bios/s390-ccw: Introduce CLP Architecture
Posted by Matthew Rosato 1 week, 3 days ago
> Since this instruction is not part of the public Principles of Operation, I'd appreciate if someone from IBM could review this patch.
> 

ACK, will get to this in the next couple of days if someone else (e.g. Eric or Farhan) doesn't beat me to it.

Thanks,
Matt