cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

r_heartbeat.c (1945B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2
      3/*
      4 *
      5 * Copyright (C) IBM Corporation, 2004
      6 *
      7 * Author: Max Asböck <amax@us.ibm.com>
      8 */
      9
     10#include <linux/sched/signal.h>
     11#include "ibmasm.h"
     12#include "dot_command.h"
     13
     14/*
     15 * Reverse Heartbeat, i.e. heartbeats sent from the driver to the
     16 * service processor.
     17 * These heartbeats are initiated by user level programs.
     18 */
     19
     20/* the reverse heartbeat dot command */
     21#pragma pack(1)
     22static struct {
     23	struct dot_command_header	header;
     24	unsigned char			command[3];
     25} rhb_dot_cmd = {
     26	.header = {
     27		.type =		sp_read,
     28		.command_size = 3,
     29		.data_size =	0,
     30		.status =	0
     31	},
     32	.command = { 4, 3, 6 }
     33};
     34#pragma pack()
     35
     36void ibmasm_init_reverse_heartbeat(struct service_processor *sp, struct reverse_heartbeat *rhb)
     37{
     38	init_waitqueue_head(&rhb->wait);
     39	rhb->stopped = 0;
     40}
     41
     42/*
     43 * start_reverse_heartbeat
     44 * Loop forever, sending a reverse heartbeat dot command to the service
     45 * processor, then sleeping. The loop comes to an end if the service
     46 * processor fails to respond 3 times or we were interrupted.
     47 */
     48int ibmasm_start_reverse_heartbeat(struct service_processor *sp, struct reverse_heartbeat *rhb)
     49{
     50	struct command *cmd;
     51	int times_failed = 0;
     52	int result = 1;
     53
     54	cmd = ibmasm_new_command(sp, sizeof rhb_dot_cmd);
     55	if (!cmd)
     56		return -ENOMEM;
     57
     58	while (times_failed < 3) {
     59		memcpy(cmd->buffer, (void *)&rhb_dot_cmd, sizeof rhb_dot_cmd);
     60		cmd->status = IBMASM_CMD_PENDING;
     61		ibmasm_exec_command(sp, cmd);
     62		ibmasm_wait_for_response(cmd, IBMASM_CMD_TIMEOUT_NORMAL);
     63
     64		if (cmd->status != IBMASM_CMD_COMPLETE)
     65			times_failed++;
     66
     67		wait_event_interruptible_timeout(rhb->wait,
     68			rhb->stopped,
     69			REVERSE_HEARTBEAT_TIMEOUT * HZ);
     70
     71		if (signal_pending(current) || rhb->stopped) {
     72			result = -EINTR;
     73			break;
     74		}
     75	}
     76	command_put(cmd);
     77	rhb->stopped = 0;
     78
     79	return result;
     80}
     81
     82void ibmasm_stop_reverse_heartbeat(struct reverse_heartbeat *rhb)
     83{
     84	rhb->stopped = 1;
     85	wake_up_interruptible(&rhb->wait);
     86}