|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen master] x86: guard against port I/O overlapping the RTC/CMOS range
commit 899316e02e0d1c9bfe65cca1b20f8140ee9c4d17
Author: Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Fri Sep 11 14:13:46 2020 +0200
Commit: Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Fri Sep 11 14:13:46 2020 +0200
x86: guard against port I/O overlapping the RTC/CMOS range
Since we intercept RTC/CMOS port accesses, let's do so consistently in
all cases, i.e. also for e.g. a dword access to [006E,0071]. To avoid
the risk of unintended impact on Dom0 code actually doing so (despite
the belief that none ought to exist), also extend
guest_io_{read,write}() to decompose accesses where some ports are
allowed to be directly accessed and some aren't.
While splitting out the new _guest_io_write() also
- add ASSERT_UNREACHABLE(),
- drop stray casts,
- add blank lines.
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
Reviewed-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
---
xen/arch/x86/pv/emul-priv-op.c | 59 +++++++++++++++++++++++++++++++-----------
1 file changed, 44 insertions(+), 15 deletions(-)
diff --git a/xen/arch/x86/pv/emul-priv-op.c b/xen/arch/x86/pv/emul-priv-op.c
index a192160f84..c6fbf8f92d 100644
--- a/xen/arch/x86/pv/emul-priv-op.c
+++ b/xen/arch/x86/pv/emul-priv-op.c
@@ -210,7 +210,7 @@ static bool admin_io_okay(unsigned int port, unsigned int
bytes,
return false;
/* We also never permit direct access to the RTC/CMOS registers. */
- if ( ((port & ~1) == RTC_PORT(0)) )
+ if ( port <= RTC_PORT(1) && port + bytes > RTC_PORT(0) )
return false;
return ioports_access_permitted(d, port, port + bytes - 1);
@@ -297,6 +297,17 @@ static uint32_t guest_io_read(unsigned int port, unsigned
int bytes,
if ( pci_cfg_ok(currd, port & 3, size, NULL) )
sub_data = pci_conf_read(currd->arch.pci_cf8, port & 3, size);
}
+ else if ( ioports_access_permitted(currd, port, port) )
+ {
+ if ( bytes > 1 && !(port & 1) &&
+ ioports_access_permitted(currd, port, port + 1) )
+ {
+ sub_data = inw(port);
+ size = 2;
+ }
+ else
+ sub_data = inb(port);
+ }
if ( size == 4 )
return sub_data;
@@ -373,25 +384,36 @@ static int read_io(unsigned int port, unsigned int bytes,
return X86EMUL_OKAY;
}
+static void _guest_io_write(unsigned int port, unsigned int bytes,
+ uint32_t data)
+{
+ switch ( bytes )
+ {
+ case 1:
+ outb(data, port);
+ if ( amd_acpi_c1e_quirk )
+ amd_check_disable_c1e(port, data);
+ break;
+
+ case 2:
+ outw(data, port);
+ break;
+
+ case 4:
+ outl(data, port);
+ break;
+
+ default:
+ ASSERT_UNREACHABLE();
+ }
+}
+
static void guest_io_write(unsigned int port, unsigned int bytes,
uint32_t data, struct domain *currd)
{
if ( admin_io_okay(port, bytes, currd) )
{
- switch ( bytes )
- {
- case 1:
- outb((uint8_t)data, port);
- if ( amd_acpi_c1e_quirk )
- amd_check_disable_c1e(port, (uint8_t)data);
- break;
- case 2:
- outw((uint16_t)data, port);
- break;
- case 4:
- outl(data, port);
- break;
- }
+ _guest_io_write(port, bytes, data);
return;
}
@@ -420,6 +442,13 @@ static void guest_io_write(unsigned int port, unsigned int
bytes,
if ( pci_cfg_ok(currd, port & 3, size, &data) )
pci_conf_write(currd->arch.pci_cf8, port & 3, size, data);
}
+ else if ( ioports_access_permitted(currd, port, port) )
+ {
+ if ( bytes > 1 && !(port & 1) &&
+ ioports_access_permitted(currd, port, port + 1) )
+ size = 2;
+ _guest_io_write(port, size, data);
+ }
if ( size == 4 )
return;
--
generated by git-patchbot for /home/xen/git/xen.git#master
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |