s390_guarded_storage(2)

πŸ’– s390_guarded_storage β€” bestie edition πŸ’–

okay so today we're learning s390_guarded_storage, which is the syscall you use for operations with the z/Architecture guarded storage facility. yes it's a whole vibe. it lives in the System Calls Manual, and it's part of the Standard C library (libc, -lc). come on a journey with me πŸ¦‹


✨ SYNOPSIS ✨

#include <asm/guarded_storage.h> /* Definition of GS_* constants */
#include <sys/syscall.h>         /* Definition of SYS_* constants */
#include <unistd.h>

int syscall(SYS_s390_guarded_storage, int command,
            struct gs_cb *gs_cb);
🚨 real talk: glibc gives you no wrapper for s390_guarded_storage(), so you literally have to go through syscall(2). no shortcuts, bestie. the way that glibc said "do it yourself" 😭

🌸 DESCRIPTION 🌸

So the s390_guarded_storage() system call turns on the use of the Guarded Storage Facility β€” which is a feature specific to z/Architecture β€” for user-space processes. periodt.

The guarded storage facility is a hardware feature that lets you mark up to 64 memory regions (as of z14) as guarded. And here's the iconic part: if you read a pointer with the newly introduced "Load Guarded" (LGG) or "Load Logical and Shift Guarded" (LLGFSG) instructions, it'll do a range check on the value you loaded, and then invoke a (previously set up) user-space handler if one of those guarded regions got affected. like a little security guard but make it silicon πŸ’…

The command argument is how you tell it which function to perform. Here are the commands it supports, collect them all:

  • GS_ENABLE β€” turns the guarded storage facility on for the calling task. the initial content of the guarded storage control block will be all zeros (clean slate bestie ✨). after that's enabled, your user-space code can use the "Load Guarded Storage Controls" (LGSC) instruction β€” or the load_gs_cb() function wrapper that's provided in the asm/guarded_storage.h header β€” to load an arbitrary control block. and while a task is enabled, the kernel will save and restore the calling content of the guarded storage registers on context switch. so considerate fr fr 🫢
  • GS_DISABLE β€” turns the guarded storage facility off for the calling task. the kernel stops saving and restoring the content of the guarded storage registers, and the task-specific content of those registers is lost. gone. evaporated. no takebacks πŸ’€
  • GS_SET_BC_CB β€” sets a broadcast guarded storage control block to the one you pass in the gs_cb argument. this one is called per thread and associates a specific guarded storage control block with the calling task. that control block is what gets used in the broadcast command GS_BROADCAST. πŸ‘‘
  • GS_CLEAR_BC_CB β€” clears the broadcast guarded storage control block. so that control block no longer has the association that was established by the GS_SET_BC_CB command. unbonded, we hate to see it πŸ™ˆ
  • GS_BROADCAST β€” sends a broadcast to all thread siblings of the calling task πŸ”₯ every sibling that has established a broadcast guarded storage control block will load this control block and will be enabled for guarded storage. oh and btw, the broadcast guarded storage control block gets consumed β€” so a second broadcast without a refresh of the stored control block with GS_SET_BC_CB will not have any effect. one and done, no cap.

Also, the gs_cb argument specifies the address of a guarded storage control block structure, and currently it's only used by the GS_SET_BC_CB command. all the other commands I mentioned above just ignore this argument entirely. it's giving background character πŸŽ€


⭐ RETURN VALUE ⭐

On success, s390_guarded_storage() returns 0. slay.

On error, it returns -1, and errno is set to indicate the error. (as is tradition.)


πŸ’… ERRORS πŸ’…

  • EFAULT β€” the command was GS_SET_BC_CB and the copying of the guarded storage control block structure pointed to by the gs_cb argument failed. copy machine said no 😭
  • EINVAL β€” the value you provided in the command argument was not valid. wrong command, bestie.
  • ENOMEM β€” the command was one of GS_ENABLE or GS_SET_BC_CB, and the allocation of a new guarded storage control block failed. out of memory, out of luck.
  • EOPNOTSUPP β€” the guarded storage facility is not supported by the hardware. the vibes are simply not available here πŸ’€

🌈 STANDARDS 🌈

Linux on s390. iykyk.


πŸ•°οΈ HISTORY πŸ•°οΈ

Linux 4.12, System z14. vintage but make it mainframe ✨


🧚 NOTES 🧚

The description of the guarded storage facility, along with the related instructions and the Guarded Storage Control Block and Guarded Storage Event Parameter List structure layouts, is available in "z/Architecture Principles of Operations" beginning from the twelfth edition. so if you want the lore, that's where the lore lives πŸ“–

Now, the gs_cb structure has a field called gsepla (Guarded Storage Event Parameter List Address), which is a user-space pointer to a Guarded Storage Event Parameter List structure. and that structure contains the address of the aforementioned event handler in the gseha field. its layout is available as a gs_epl structure type definition in the asm/guarded_storage.h header. structs inside structs inside headers, it's giving nesting dolls πŸŽ€


🫢 SEE ALSO 🫢


and that's the whole page, bestie! this one came from the Linux man-pages 6.20, dated 2026-02-22, and it's the s390_guarded_storage(2) page. go forth and guard that storage πŸ’–βœ¨πŸŒΈπŸ¦‹

πŸ“¦ where this page comes from
  • arch rolling: man-pages 6.20-1 Β· BSD-2-Clause AND BSD-3-Clause AND BSD-4.3TAHOE AND BSD-4-Clause-UC AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-or-later AND GPL-3.0-or-later AND LGPL-3.0-linking-exception AND LGPL-3.0-or-later AND LicenseRef-Public-Domain AND LicenseRef-UltraPermissive AND Linux-man-pages-1-para AND Linux-man-pages-copyleft AND Linux-man-pages-copyleft-2-para AND Linux-man-pages-copyleft-var AND MIT AND Spencer-94
  • nixpkgs unstable: man-pages 6.20
  • πŸ“œ the page's license: Linux-man-pages-copyleft
  • πŸ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms