Received: by 2002:a05:6a10:16a7:0:0:0:0 with SMTP id gp39csp833826pxb; Tue, 3 Nov 2020 13:53:41 -0800 (PST) X-Google-Smtp-Source: ABdhPJz/Cj/b2M5gq4LEmJoQXoOATH/yLHaa/jr23vVhE1ziBl2kOEDs4JvzlLG8/5PZTUtpXoaV X-Received: by 2002:a17:906:70cf:: with SMTP id g15mr21457016ejk.323.1604440421685; Tue, 03 Nov 2020 13:53:41 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1604440421; cv=none; d=google.com; s=arc-20160816; b=fmrUU9Tyg3iteggF9zAKj6K7jlJWRS7BMuH4H9lKxSAGSbBGPynkQs5u8r+is1N+s9 3lBiOgCx7eDsb1NJGMBtvC7lux+TrpJyDQITVPw3+59rYTC0xmKcg0oRtIly1MMK7R1S yXm2KoV7sYjYvL2TOgpdWWAV6rLF6PwbhR7jpURJERjeAS81UN+m7FPAhD8mQQEdQqm8 xpoHaqqDGPbaEJqAY1SkucJqMG+Nljk7H8/8y8ucAC7NiAFq2PQPS2AljVd6n+ask9y0 LokKocExpMD8jAJrrLWzzJKqFHxprdxugJJWeEOGrmpUq79RzVLR8Lt0lbGTycMsffE9 CXWw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=KCFUBRi4r5GhBCBKJhapboimjPyNYBac/+1LGMv+sBI=; b=b4fKjFbSJCDk+2rHzRM1Z0YkVGt+dLwDvX21vBwqVdi//1naxTvc6hKpSSWck0wk6e blWdUkX/pDpPHxl7g5Mv3ffEm3ZERlTmCd98ll2vYZKMo+e0DD5B3q/GYK1II5kAiNWt AKjvqug3mMy+vx52SAAqI18qaOta+4F5tCpQ6hwd1WnfG/yKf6a58q/QA2xzgVpYClUy 7+Ohk5HqlZrmUO4UwyksNl6xarkrSVF0jWWsEf+p7fpexJWUOHozDQCeNGPwAljP80cu ++Hezaz7zNtnRi3vkx3ZKpnT9F2HO08FBfWBKnhdRIGSM93z/JroP0HyKYuRMVUl1M/G 1Jjw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=PErBGZiD; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id u7si3394526edy.373.2020.11.03.13.53.18; Tue, 03 Nov 2020 13:53:41 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=PErBGZiD; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731023AbgKCVvC (ORCPT + 99 others); Tue, 3 Nov 2020 16:51:02 -0500 Received: from mail.kernel.org ([198.145.29.99]:40510 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731557AbgKCUsj (ORCPT ); Tue, 3 Nov 2020 15:48:39 -0500 Received: from localhost (83-86-74-64.cable.dynamic.v4.ziggo.nl [83.86.74.64]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 810F82242F; Tue, 3 Nov 2020 20:48:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1604436519; bh=+X2budXCb6J4o/mCqhEBs0LDWUBHuO/8px/UpGU0p58=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=PErBGZiDGvUEzFcaBQzV+9gd8j9DylelX9xqJPka9msJSgKU0dvJz+LeMdE6Cps1K 01S2seGmz5LTwze0oyeKTXmuJRv44PJrWxEhbt1f9s5i4r8ued2rrZEk8+e9iYRGqn MQiTel0gWD23QJLSuBGEEJWJZ6FTA8bMfkIcs5hU= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Sven Schnelle , Alexander Egorenkov , Vasily Gorbik Subject: [PATCH 5.9 285/391] s390/stp: add locking to sysfs functions Date: Tue, 3 Nov 2020 21:35:36 +0100 Message-Id: <20201103203406.275946114@linuxfoundation.org> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201103203348.153465465@linuxfoundation.org> References: <20201103203348.153465465@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Sven Schnelle commit b3bd02495cb339124f13135d51940cf48d83e5cb upstream. The sysfs function might race with stp_work_fn. To prevent that, add the required locking. Another issue is that the sysfs functions are checking the stp_online flag, but this flag just holds the user setting whether STP is enabled. Add a flag to clock_sync_flag whether stp_info holds valid data and use that instead. Cc: stable@vger.kernel.org Signed-off-by: Sven Schnelle Reviewed-by: Alexander Egorenkov Signed-off-by: Vasily Gorbik Signed-off-by: Greg Kroah-Hartman --- arch/s390/kernel/time.c | 118 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 85 insertions(+), 33 deletions(-) --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c @@ -345,8 +345,9 @@ static DEFINE_PER_CPU(atomic_t, clock_sy static DEFINE_MUTEX(clock_sync_mutex); static unsigned long clock_sync_flags; -#define CLOCK_SYNC_HAS_STP 0 -#define CLOCK_SYNC_STP 1 +#define CLOCK_SYNC_HAS_STP 0 +#define CLOCK_SYNC_STP 1 +#define CLOCK_SYNC_STPINFO_VALID 2 /* * The get_clock function for the physical clock. It will get the current @@ -583,6 +584,22 @@ void stp_queue_work(void) queue_work(time_sync_wq, &stp_work); } +static int __store_stpinfo(void) +{ + int rc = chsc_sstpi(stp_page, &stp_info, sizeof(struct stp_sstpi)); + + if (rc) + clear_bit(CLOCK_SYNC_STPINFO_VALID, &clock_sync_flags); + else + set_bit(CLOCK_SYNC_STPINFO_VALID, &clock_sync_flags); + return rc; +} + +static int stpinfo_valid(void) +{ + return stp_online && test_bit(CLOCK_SYNC_STPINFO_VALID, &clock_sync_flags); +} + static int stp_sync_clock(void *data) { struct clock_sync_data *sync = data; @@ -604,8 +621,7 @@ static int stp_sync_clock(void *data) if (rc == 0) { sync->clock_delta = clock_delta; clock_sync_global(clock_delta); - rc = chsc_sstpi(stp_page, &stp_info, - sizeof(struct stp_sstpi)); + rc = __store_stpinfo(); if (rc == 0 && stp_info.tmd != 2) rc = -EAGAIN; } @@ -650,7 +666,7 @@ static void stp_work_fn(struct work_stru if (rc) goto out_unlock; - rc = chsc_sstpi(stp_page, &stp_info, sizeof(struct stp_sstpi)); + rc = __store_stpinfo(); if (rc || stp_info.c == 0) goto out_unlock; @@ -687,10 +703,14 @@ static ssize_t ctn_id_show(struct device struct device_attribute *attr, char *buf) { - if (!stp_online) - return -ENODATA; - return sprintf(buf, "%016llx\n", - *(unsigned long long *) stp_info.ctnid); + ssize_t ret = -ENODATA; + + mutex_lock(&stp_work_mutex); + if (stpinfo_valid()) + ret = sprintf(buf, "%016llx\n", + *(unsigned long long *) stp_info.ctnid); + mutex_unlock(&stp_work_mutex); + return ret; } static DEVICE_ATTR_RO(ctn_id); @@ -699,9 +719,13 @@ static ssize_t ctn_type_show(struct devi struct device_attribute *attr, char *buf) { - if (!stp_online) - return -ENODATA; - return sprintf(buf, "%i\n", stp_info.ctn); + ssize_t ret = -ENODATA; + + mutex_lock(&stp_work_mutex); + if (stpinfo_valid()) + ret = sprintf(buf, "%i\n", stp_info.ctn); + mutex_unlock(&stp_work_mutex); + return ret; } static DEVICE_ATTR_RO(ctn_type); @@ -710,9 +734,13 @@ static ssize_t dst_offset_show(struct de struct device_attribute *attr, char *buf) { - if (!stp_online || !(stp_info.vbits & 0x2000)) - return -ENODATA; - return sprintf(buf, "%i\n", (int)(s16) stp_info.dsto); + ssize_t ret = -ENODATA; + + mutex_lock(&stp_work_mutex); + if (stpinfo_valid() && (stp_info.vbits & 0x2000)) + ret = sprintf(buf, "%i\n", (int)(s16) stp_info.dsto); + mutex_unlock(&stp_work_mutex); + return ret; } static DEVICE_ATTR_RO(dst_offset); @@ -721,9 +749,13 @@ static ssize_t leap_seconds_show(struct struct device_attribute *attr, char *buf) { - if (!stp_online || !(stp_info.vbits & 0x8000)) - return -ENODATA; - return sprintf(buf, "%i\n", (int)(s16) stp_info.leaps); + ssize_t ret = -ENODATA; + + mutex_lock(&stp_work_mutex); + if (stpinfo_valid() && (stp_info.vbits & 0x8000)) + ret = sprintf(buf, "%i\n", (int)(s16) stp_info.leaps); + mutex_unlock(&stp_work_mutex); + return ret; } static DEVICE_ATTR_RO(leap_seconds); @@ -732,9 +764,13 @@ static ssize_t stratum_show(struct devic struct device_attribute *attr, char *buf) { - if (!stp_online) - return -ENODATA; - return sprintf(buf, "%i\n", (int)(s16) stp_info.stratum); + ssize_t ret = -ENODATA; + + mutex_lock(&stp_work_mutex); + if (stpinfo_valid()) + ret = sprintf(buf, "%i\n", (int)(s16) stp_info.stratum); + mutex_unlock(&stp_work_mutex); + return ret; } static DEVICE_ATTR_RO(stratum); @@ -743,9 +779,13 @@ static ssize_t time_offset_show(struct d struct device_attribute *attr, char *buf) { - if (!stp_online || !(stp_info.vbits & 0x0800)) - return -ENODATA; - return sprintf(buf, "%i\n", (int) stp_info.tto); + ssize_t ret = -ENODATA; + + mutex_lock(&stp_work_mutex); + if (stpinfo_valid() && (stp_info.vbits & 0x0800)) + ret = sprintf(buf, "%i\n", (int) stp_info.tto); + mutex_unlock(&stp_work_mutex); + return ret; } static DEVICE_ATTR_RO(time_offset); @@ -754,9 +794,13 @@ static ssize_t time_zone_offset_show(str struct device_attribute *attr, char *buf) { - if (!stp_online || !(stp_info.vbits & 0x4000)) - return -ENODATA; - return sprintf(buf, "%i\n", (int)(s16) stp_info.tzo); + ssize_t ret = -ENODATA; + + mutex_lock(&stp_work_mutex); + if (stpinfo_valid() && (stp_info.vbits & 0x4000)) + ret = sprintf(buf, "%i\n", (int)(s16) stp_info.tzo); + mutex_unlock(&stp_work_mutex); + return ret; } static DEVICE_ATTR_RO(time_zone_offset); @@ -765,9 +809,13 @@ static ssize_t timing_mode_show(struct d struct device_attribute *attr, char *buf) { - if (!stp_online) - return -ENODATA; - return sprintf(buf, "%i\n", stp_info.tmd); + ssize_t ret = -ENODATA; + + mutex_lock(&stp_work_mutex); + if (stpinfo_valid()) + ret = sprintf(buf, "%i\n", stp_info.tmd); + mutex_unlock(&stp_work_mutex); + return ret; } static DEVICE_ATTR_RO(timing_mode); @@ -776,9 +824,13 @@ static ssize_t timing_state_show(struct struct device_attribute *attr, char *buf) { - if (!stp_online) - return -ENODATA; - return sprintf(buf, "%i\n", stp_info.tst); + ssize_t ret = -ENODATA; + + mutex_lock(&stp_work_mutex); + if (stpinfo_valid()) + ret = sprintf(buf, "%i\n", stp_info.tst); + mutex_unlock(&stp_work_mutex); + return ret; } static DEVICE_ATTR_RO(timing_state);