Tiny query used to be sub-second speed, now takes 60+ seconds
the sub-select by itself still takes less than a second and returns
  about 20 rows ... Any suggestions?


In that case you may as well materialize it into a #temp table and join onto that instead.

SELECT BS.[database_name],
       DATEDIFF(HH, MAX(BS.backup_finish_date), GETDATE())                 AS last_backup,
       DATEDIFF(MI, MAX(BS.backup_start_date), MAX(BS.backup_finish_date)) AS last_duration
INTO   #BS1
FROM   msdb.dbo.backupset BS
WHERE  BS.type = 'L'
GROUP  BY BS.[database_name];

SELECT D.name AS [database_name],
       D.recovery_model,
       BS1.last_backup,
       BS1.last_duration
FROM   sys.databases D
       LEFT JOIN #BS1 BS1
         ON D.name = BS1.[database_name]
ORDER  BY D.[name];

DROP TABLE #BS1 ;