SVC Screening

SVC screening provides a way of screening (or intercepting) SVC calls at the task level.  A SVC screen table is created and the address is placed in a TCB.  Any SVC calls from that task that are marked for screening will be intercepted.  Control is passed to the screen routine from the SVC interrupt handler in exactly the same way SVC routines are invoked.

There are several implications of SVC screening.  First we can easily test new SVC code without the need to IPL and perfrom a CLPA or MLPA.  Also the SVC code is only active for tasks were the screening is activated.  With SVC screening we can test a new SVC routine or replace an existing SVC routine.  This applies to both user and system SVC routines.  It also provides a method to front-end SVC calls.

There are two fields in the TCB related to SVC screening.  TCBSVCS is a bit in the TCBFLGS7 field that indicates SVC screening is active if set to one or inactive if set to zero.  TCBSVCA2 is the pointer to the SVC screen table.  The screen table is 264 bytes long.  The first four bytes are the address of the SVC intercept routine that receives control when a screened SVC is invoked by the task.  The next four bytes  are flags that indicate the attributes of the SVC routine.  The first flag byte indicates the SVC type (X’00’ – Type 1, X’80’ – Type 1, X’C0′ – Type 3/4)  The second flag byte is not used and should be binary zeros.  The third and fourth flag bytes indicate the locks to be obtained before passing control to the SVC routine.  Binary zeros indicate no locks are to be obtained.  The next 256 bytes indicate which SVC numbers should be intercepted.  Each byte is a flag for a SVC number.  If the byte is set to X’80’ then the SVC is not to be intercepted.  If they byte is set to X’00’ then the SVC should be intercepted.   The SVC type and locks flags apply to all intercepted SVC numbers.

We now have enough information to write some code to test SVC screening.

SVC02    CSECT ,                                         
         SAVE  (14,12),,SVC02     SAVE CALLERS REGISTERS 
*                                                        
         LR    R12,R15            ESTABLISH              
         USING SVC02,R12                   BASE REGISTER 
*                                                        
         LA    R1,SAVEA           CHAIN                  
         ST    R1,8(,R13)              NEW               
         ST    R13,4(,R1)                 SAVE           
         LR    R13,R1                         AREA       
*

We start with our standard program linkage.

         LA    R1,=C'AUTH'        GET APF AUTHORIZATION    
         SVC   245                                         
*                                                          
         MODESET MODE=SUP         GET INTO SUPERVISOR MODE 
*                                                          
         LA    R1,0               RESET APF AUTHORIZATION  
         SVC   245

Next we obtain APF authorization using the SVC I have installed on my system for testing. You could also run from an APF authorized library. Once APF authorized the MODESET macro is used to swap into supervisor mode and then I clear the APF authorization. This is not really necessary and it shouldnt be necessary to reset it.

         IPK   ,                  GET PSW PROTECT KEY 
         LR    R11,R2             SAVE PK IN R11      
*                                                     
         SPKA  0                  GET INTO KEY ZERO

Next I save the current protect key from the PSW using the IPK instruction. The protect key is placed into register 2 so I copy it to register 11 to save it. I then use the SPKA instruction to get into protect key zero.

         GETMAIN R,LV=264,SP=253

Now we getmain some stroage for our SVC screen table. I use subpool 253 which is Fixed LSQA. This storage is task related and will automaticaly be freed when the task terminates. The storage is not fetch protected and is in key zero.

         LR    R3,R1              SAVE STORAGE ADDRESS         
         XC    0(8,R3),0(R3)      CLEAR FIRST 8 BYTES          
         LA    R1,SVCINT          ADDRESS OF SVC INTERCEPT RTN 
         ST    R1,0(,R3)          SAVE INTO PARMAMETER BLOCK   
         MVI   4(R3),X'C0'        INDICATE TYPE 3/4 SVC

The address of the LSQA storage is copied into register 3 and the first 8 bytes are zeroed out. The address of the routine to receive control from the SVC interrupt handler is placed in the first four bytes. The first flag byte is set to X’C0′ to indicate a Type 3/4 SVC. The lock flags are zero indicating no locks should be obtained.

         LA    R2,8(,R3)          POINT TO 256 BYTE SVC LIST    
         LA    R1,256                                           
INITLOOP DS    0H                                               
         MVI   0(R2),X'80'        INITIALIZE TO DO NOT INTERCEPT
         LA    R2,1(,R2)          NEXT BYTE                     
         BCT   R1,INITLOOP        LOOP BACK

Now we initialize the 256 byte list. Each byte in the list represents one SVC number. The first byte is for SVC 0, the next for SVC 1 and so on. We set each to a value of X’80’ so the SVC is not intercepted.

 *                                                           
          LA    R2,8(,R3)          POINT TO 256 BYTE SVC LIST
          MVI   230(R2),X'00'      INTERCEPT SVC 230         
 *

Now we indicate which SVC requests should be intercepted by setting the corresponding byte to X’00’. I chose to use SVC 230 because it is currently unused on my system. I does not matter how the SVC is defined in the SYSGEN since it is ignored for SVC screening.  Caution should be used to not accidently intercept a SVC that is currently in use on your system.

*                                                                    
         L     R2,16              CVT                                
         L     R2,0(,R2)          OLD/NEW POINTER                    
         L     R2,4(,R2)          TCB ADDRESS                        
         USING TCB,R2                                                
*                                                                    
         ST    R3,TCBSVCA2        STORE SCREEN TABLE ADDRESS INTO TCB
         OI    TCBFLGS7,TCBSVCS   TURN ON SVC SCREENING

Now we locate the address of our current TCB and store the address of the screen table into the TCBSVCA2 field.  Next we set the TCBSVCS bit to activate screening.

         SPKA  0(R11)             RESTORE PROTECT KEY                
*                                                                    
         SVC   230                SHOULD BE CAPTURED BY SVC SCREENING

Now we can restore our PSW protect key.  It is always a good idea to only operate in key zero only when necessary.  Now we issue SVC 230 to test our SVC screening intercept.

         L     R13,4(,R13)        UNCHAIN SAVE AREA         
         LM    R14,R12,12(R13)    RESTORE CALLERS REGISTERS 
         SLR   R15,R15            ZERO RC                   
         BR    R14                RETURN TO CALLER

Now we can exit back to the caller.

SVCINT   DS    0H                                            
         USING SVCINT,R6          SET BASE REGISTER          
*                                                            
         LR    R11,R14            SAVE RETURN ADDRESS        
*                                                            
         WTO   'HELLO FROM SVC SCREEN ROUTINE',ROUTCDE=(1,11)
*                                                            
         LR    R14,R11            RESTORE RETURN ADDRESS     
         BR    R14                EXIT SVC ROUTINE

Here is our SVC intercept routine.  The register contents are standard for a SVC routine.  We use register 6 as our base register.  The return address is saved in register 11.  All our SVC routine does is issue a WTO to write a message to the console.  Since we defined our SVC intercept as a Type 3/4 our SVC routine can issue SVC calls.  We then exit back to our caller.

SAVEA    DS    18F                REGISTER SAVE AREA
*                                                   
         LTORG ,                                    
*                                                   
         PRINT NOGEN                                
         IKJTCB DSECT=YES,LIST=NO                   
*                  
R0       EQU   0   
R1       EQU   1   
R2       EQU   2   
R3       EQU   3   
R4       EQU   4   
R5       EQU   5   
R6       EQU   6   
R7       EQU   7   
R8       EQU   8   
R9       EQU   9   
R10      EQU   10  
R11      EQU   11  
R12      EQU   12  
R13      EQU   13  
R14      EQU   14  
R15      EQU   15  
*                  
         END    ,

We finish up with our data areas and register equates.

JOB 6828  $HASP373 SVC02    STARTED - INIT 12 - CLASS A - SYS TCS3 
JOB 6828  HELLO FROM SVC SCREEN ROUTINE                            
JOB 6828   9.21.07   0.00.00   0.00.00  0000   SVC02     MVSSP     
JOB 6828   9.21.07   0.00.00   0.00.00  0000   SVC02     ########  
JOB 6828  $HASP395 SVC02    ENDED

Now we can assemble, link edit, and execute and we get our message. We have successfully intercepted SVC 230.

*        OI    TCBFLGS7,TCBSVCS   TURN ON SVC SCREENING

Just to prove that we are really intercepting a SVC call I commented out the line that sets the TCBSVCS bit so that SVC screening is not active.  Upon assembling, link editing, and executing we get:

JOB 6831  $HASP100 SVC02    ON INTRDR      RUN TEST PGM           
JOB 6831  $HASP373 SVC02    STARTED - INIT 12 - CLASS A - SYS TCS3
JOB 6831  IEF450I SVC02 MVSSP - ABEND SFE6 U0000 - TIME=08.23.57  
JOB 6831   8.23.57   0.00.00   0.00.00  SFE6   SVC02     MVSSP    
JOB 6831   8.23.57   0.00.00   0.00.00  SFE6   SVC02     ######## 
JOB 6831  $HASP395 SVC02    ENDED

A System ABEND FE6 indicates that SVC X’F6′ (230 decimal) was called but the SVC routine is not installed.